From cc54b33720cc24906ebd4b3b909a1983913c5df5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 25 Sep 2025 09:52:37 +0200 Subject: [PATCH 001/853] chore(deps): update dependency typescript to ~5.9.0 (#36212) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: diondiondion --- .../mastodon/components/blurhash.tsx | 7 +++- .../mastodon/components/hashtag_bar.tsx | 2 +- .../components/embedded_status_content.tsx | 2 +- .../mastodon/features/onboarding/profile.tsx | 4 +- .../features/ui/components/embed_modal.tsx | 1 + app/javascript/mastodon/hooks/useLinks.ts | 2 +- eslint.config.mjs | 1 - package.json | 2 +- streaming/package.json | 2 +- yarn.lock | 40 +++++-------------- 10 files changed, 22 insertions(+), 41 deletions(-) diff --git a/app/javascript/mastodon/components/blurhash.tsx b/app/javascript/mastodon/components/blurhash.tsx index 8e2a8af23e5937..b7331755b7f0dd 100644 --- a/app/javascript/mastodon/components/blurhash.tsx +++ b/app/javascript/mastodon/components/blurhash.tsx @@ -30,9 +30,12 @@ const Blurhash: React.FC = ({ try { const pixels = decode(hash, width, height); const ctx = canvas.getContext('2d'); - const imageData = new ImageData(pixels, width, height); + const imageData = ctx?.createImageData(width, height); + imageData?.data.set(pixels); - ctx?.putImageData(imageData, 0, 0); + if (imageData) { + ctx?.putImageData(imageData, 0, 0); + } } catch (err) { console.error('Blurhash decoding failure', { err, hash }); } diff --git a/app/javascript/mastodon/components/hashtag_bar.tsx b/app/javascript/mastodon/components/hashtag_bar.tsx index 4f88385bef951f..f6b72d43404bd0 100644 --- a/app/javascript/mastodon/components/hashtag_bar.tsx +++ b/app/javascript/mastodon/components/hashtag_bar.tsx @@ -33,7 +33,7 @@ function isNodeLinkHashtag(element: Node): element is HTMLLinkElement { return ( element instanceof HTMLAnchorElement && // it may be a starting with a hashtag - (element.textContent?.[0] === '#' || + (element.textContent.startsWith('#') || // or a # element.previousSibling?.textContent?.[ element.previousSibling.textContent.length - 1 diff --git a/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx b/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx index 1a38be536ba6a8..855e160fac657d 100644 --- a/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx +++ b/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx @@ -64,7 +64,7 @@ export const EmbeddedStatusContent: React.FC<{ link.setAttribute('title', `@${mention.get('acct')}`); link.setAttribute('href', `/@${mention.get('acct')}`); } else if ( - link.textContent?.[0] === '#' || + link.textContent.startsWith('#') || link.previousSibling?.textContent?.endsWith('#') ) { link.addEventListener( diff --git a/app/javascript/mastodon/features/onboarding/profile.tsx b/app/javascript/mastodon/features/onboarding/profile.tsx index d9b394acfbb85d..7e725e97cc3861 100644 --- a/app/javascript/mastodon/features/onboarding/profile.tsx +++ b/app/javascript/mastodon/features/onboarding/profile.tsx @@ -54,9 +54,7 @@ export const Profile: React.FC<{ me ? state.accounts.get(me) : undefined, ); const [displayName, setDisplayName] = useState(account?.display_name ?? ''); - const [note, setNote] = useState( - account ? (unescapeHTML(account.note) ?? '') : '', - ); + const [note, setNote] = useState(account ? unescapeHTML(account.note) : ''); const [avatar, setAvatar] = useState(); const [header, setHeader] = useState(); const [discoverable, setDiscoverable] = useState( diff --git a/app/javascript/mastodon/features/ui/components/embed_modal.tsx b/app/javascript/mastodon/features/ui/components/embed_modal.tsx index b78d5b64c4fd72..0290b01d2f548d 100644 --- a/app/javascript/mastodon/features/ui/components/embed_modal.tsx +++ b/app/javascript/mastodon/features/ui/components/embed_modal.tsx @@ -36,6 +36,7 @@ const EmbedModal: React.FC<{ } iframeDocument.open(); + // eslint-disable-next-line @typescript-eslint/no-deprecated iframeDocument.write(data.html); iframeDocument.close(); diff --git a/app/javascript/mastodon/hooks/useLinks.ts b/app/javascript/mastodon/hooks/useLinks.ts index 160fe18503f36a..00e1dd9bb44253 100644 --- a/app/javascript/mastodon/hooks/useLinks.ts +++ b/app/javascript/mastodon/hooks/useLinks.ts @@ -12,7 +12,7 @@ const isMentionClick = (element: HTMLAnchorElement) => !element.classList.contains('hashtag'); const isHashtagClick = (element: HTMLAnchorElement) => - element.textContent?.[0] === '#' || + element.textContent.startsWith('#') || element.previousSibling?.textContent?.endsWith('#'); export const useLinks = (skipHashtags?: boolean) => { diff --git a/eslint.config.mjs b/eslint.config.mjs index 43aabc51100c4b..883ddf5fce7c20 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -5,7 +5,6 @@ import path from 'node:path'; import js from '@eslint/js'; import { globalIgnores } from 'eslint/config'; import formatjs from 'eslint-plugin-formatjs'; -// @ts-expect-error -- No typings import importPlugin from 'eslint-plugin-import'; import jsdoc from 'eslint-plugin-jsdoc'; import jsxA11Y from 'eslint-plugin-jsx-a11y'; diff --git a/package.json b/package.json index fcc74dc83f83fa..e38bc68e37e913 100644 --- a/package.json +++ b/package.json @@ -190,7 +190,7 @@ "stylelint": "^16.19.1", "stylelint-config-prettier-scss": "^1.0.0", "stylelint-config-standard-scss": "^15.0.1", - "typescript": "~5.7.3", + "typescript": "~5.9.0", "typescript-eslint": "^8.29.1", "vitest": "^3.2.4" }, diff --git a/streaming/package.json b/streaming/package.json index 40a737a61dad6a..05acc580312167 100644 --- a/streaming/package.json +++ b/streaming/package.json @@ -39,7 +39,7 @@ "@types/ws": "^8.5.9", "globals": "^16.0.0", "pino-pretty": "^13.0.0", - "typescript": "~5.7.3", + "typescript": "~5.9.0", "typescript-eslint": "^8.28.0" }, "optionalDependencies": { diff --git a/yarn.lock b/yarn.lock index 384a553387f340..9a5ac444be1fbc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2859,7 +2859,7 @@ __metadata: tesseract.js: "npm:^6.0.0" tiny-queue: "npm:^0.2.1" twitter-text: "npm:3.1.0" - typescript: "npm:~5.7.3" + typescript: "npm:~5.9.0" typescript-eslint: "npm:^8.29.1" use-debounce: "npm:^10.0.0" vite: "npm:^7.1.1" @@ -2907,7 +2907,7 @@ __metadata: pino-http: "npm:^10.0.0" pino-pretty: "npm:^13.0.0" prom-client: "npm:^15.0.0" - typescript: "npm:~5.7.3" + typescript: "npm:~5.9.0" typescript-eslint: "npm:^8.28.0" utf-8-validate: "npm:^6.0.3" uuid: "npm:^11.0.0" @@ -13459,43 +13459,23 @@ __metadata: languageName: node linkType: hard -"typescript@npm:^5.6.0": - version: 5.8.2 - resolution: "typescript@npm:5.8.2" +"typescript@npm:^5.6.0, typescript@npm:~5.9.0": + version: 5.9.2 + resolution: "typescript@npm:5.9.2" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10c0/5c4f6fbf1c6389b6928fe7b8fcd5dc73bb2d58cd4e3883f1d774ed5bd83b151cbac6b7ecf11723de56d4676daeba8713894b1e9af56174f2f9780ae7848ec3c6 + checksum: 10c0/cd635d50f02d6cf98ed42de2f76289701c1ec587a363369255f01ed15aaf22be0813226bff3c53e99d971f9b540e0b3cc7583dbe05faded49b1b0bed2f638a18 languageName: node linkType: hard -"typescript@npm:~5.7.3": - version: 5.7.3 - resolution: "typescript@npm:5.7.3" +"typescript@patch:typescript@npm%3A^5.6.0#optional!builtin, typescript@patch:typescript@npm%3A~5.9.0#optional!builtin": + version: 5.9.2 + resolution: "typescript@patch:typescript@npm%3A5.9.2#optional!builtin::version=5.9.2&hash=5786d5" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10c0/b7580d716cf1824736cc6e628ab4cd8b51877408ba2be0869d2866da35ef8366dd6ae9eb9d0851470a39be17cbd61df1126f9e211d8799d764ea7431d5435afa - languageName: node - linkType: hard - -"typescript@patch:typescript@npm%3A^5.6.0#optional!builtin": - version: 5.8.2 - resolution: "typescript@patch:typescript@npm%3A5.8.2#optional!builtin::version=5.8.2&hash=5786d5" - bin: - tsc: bin/tsc - tsserver: bin/tsserver - checksum: 10c0/5448a08e595cc558ab321e49d4cac64fb43d1fa106584f6ff9a8d8e592111b373a995a1d5c7f3046211c8a37201eb6d0f1566f15cdb7a62a5e3be01d087848e2 - languageName: node - linkType: hard - -"typescript@patch:typescript@npm%3A~5.7.3#optional!builtin": - version: 5.7.3 - resolution: "typescript@patch:typescript@npm%3A5.7.3#optional!builtin::version=5.7.3&hash=5786d5" - bin: - tsc: bin/tsc - tsserver: bin/tsserver - checksum: 10c0/6fd7e0ed3bf23a81246878c613423730c40e8bdbfec4c6e4d7bf1b847cbb39076e56ad5f50aa9d7ebd89877999abaee216002d3f2818885e41c907caaa192cc4 + checksum: 10c0/34d2a8e23eb8e0d1875072064d5e1d9c102e0bdce56a10a25c0b917b8aa9001a9cf5c225df12497e99da107dc379360bc138163c66b55b95f5b105b50578067e languageName: node linkType: hard From e0f7aedf419ab4cb136ec36036c8c0c68dbef2ee Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 25 Sep 2025 07:54:07 +0000 Subject: [PATCH 002/853] chore(deps): update dependency propshaft to v1.3.1 (#36241) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 64ef3057d8a664..27a70b2460fe48 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -629,7 +629,7 @@ GEM prism (1.4.0) prometheus_exporter (2.3.0) webrick - propshaft (1.2.1) + propshaft (1.3.1) actionpack (>= 7.0.0) activesupport (>= 7.0.0) rack @@ -643,7 +643,7 @@ GEM activesupport (>= 3.0.0) raabro (1.4.0) racc (1.8.1) - rack (3.1.16) + rack (3.2.1) rack-attack (6.7.0) rack (>= 1.0, < 4) rack-cors (3.0.0) From 33fd8c774b923ced52a2b79f8e7b83e6f609fb78 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 25 Sep 2025 07:54:41 +0000 Subject: [PATCH 003/853] chore(deps): update dependency webauthn to v3.4.2 (#36243) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 27a70b2460fe48..d4486681d291fd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -150,7 +150,7 @@ GEM playwright-ruby-client (>= 1.16.0) case_transform (0.2) activesupport - cbor (0.5.9.8) + cbor (0.5.10.1) cgi (0.4.2) charlock_holmes (0.7.9) chewy (7.6.0) @@ -814,8 +814,8 @@ GEM rubyzip (3.1.0) rufus-scheduler (3.9.2) fugit (~> 1.1, >= 1.11.1) - safety_net_attestation (0.4.0) - jwt (~> 2.0) + safety_net_attestation (0.5.0) + jwt (>= 2.0, < 4.0) sanitize (7.0.0) crass (~> 1.0.2) nokogiri (>= 1.16.8) @@ -918,13 +918,13 @@ GEM zeitwerk (~> 2.2) warden (1.2.9) rack (>= 2.0.9) - webauthn (3.4.1) + webauthn (3.4.2) android_key_attestation (~> 0.3.0) bindata (~> 2.4) cbor (~> 0.5.9) cose (~> 1.1) openssl (>= 2.2) - safety_net_attestation (~> 0.4.0) + safety_net_attestation (~> 0.5.0) tpm-key_attestation (~> 0.14.0) webfinger (2.1.3) activesupport From 0798d0c95a41deea018114e00a32d01832a544fc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 25 Sep 2025 09:54:58 +0200 Subject: [PATCH 004/853] chore(deps): update dependency pundit to v2.5.2 (#36251) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index d4486681d291fd..2d38065acc8af0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -639,7 +639,7 @@ GEM public_suffix (6.0.2) puma (7.0.3) nio4r (~> 2.0) - pundit (2.5.1) + pundit (2.5.2) activesupport (>= 3.0.0) raabro (1.4.0) racc (1.8.1) From fda3589498d47835bfa68e3b918300c06473f706 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 25 Sep 2025 09:55:09 +0200 Subject: [PATCH 005/853] fix(deps): update dependency sass to v1.93.2 (#36231) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 9a5ac444be1fbc..6fd58db3043d8e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12018,8 +12018,8 @@ __metadata: linkType: hard "sass@npm:^1.62.1": - version: 1.93.0 - resolution: "sass@npm:1.93.0" + version: 1.93.2 + resolution: "sass@npm:1.93.2" dependencies: "@parcel/watcher": "npm:^2.4.1" chokidar: "npm:^4.0.0" @@ -12030,7 +12030,7 @@ __metadata: optional: true bin: sass: sass.js - checksum: 10c0/51dcb4e65a69f97b4c200ee154ca45f81b748a45f8ef0ec3236b774bb143590a9304038e9ab09f809f734d4edb3add96a0a690b2e8451ff66b9f57c469b2685e + checksum: 10c0/5a19f12dbe8c142e40c1e0473d1e624898242b1c21010301e169b528be8c580df6356329c798522b525eb11eda4b04b9b77422badc55c47889600f8477201d2b languageName: node linkType: hard From 8fac87d77c06e0541392ea0dc574507a05738786 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 25 Sep 2025 07:55:46 +0000 Subject: [PATCH 006/853] chore(deps): update dependency rails to v8.0.3 (#36230) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 110 ++++++++++++++++++++++++++------------------------- 1 file changed, 56 insertions(+), 54 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 2d38065acc8af0..390debbf5de9b3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -10,29 +10,29 @@ GIT GEM remote: https://rubygems.org/ specs: - actioncable (8.0.2.1) - actionpack (= 8.0.2.1) - activesupport (= 8.0.2.1) + actioncable (8.0.3) + actionpack (= 8.0.3) + activesupport (= 8.0.3) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (8.0.2.1) - actionpack (= 8.0.2.1) - activejob (= 8.0.2.1) - activerecord (= 8.0.2.1) - activestorage (= 8.0.2.1) - activesupport (= 8.0.2.1) + actionmailbox (8.0.3) + actionpack (= 8.0.3) + activejob (= 8.0.3) + activerecord (= 8.0.3) + activestorage (= 8.0.3) + activesupport (= 8.0.3) mail (>= 2.8.0) - actionmailer (8.0.2.1) - actionpack (= 8.0.2.1) - actionview (= 8.0.2.1) - activejob (= 8.0.2.1) - activesupport (= 8.0.2.1) + actionmailer (8.0.3) + actionpack (= 8.0.3) + actionview (= 8.0.3) + activejob (= 8.0.3) + activesupport (= 8.0.3) mail (>= 2.8.0) rails-dom-testing (~> 2.2) - actionpack (8.0.2.1) - actionview (= 8.0.2.1) - activesupport (= 8.0.2.1) + actionpack (8.0.3) + actionview (= 8.0.3) + activesupport (= 8.0.3) nokogiri (>= 1.8.5) rack (>= 2.2.4) rack-session (>= 1.0.1) @@ -40,15 +40,15 @@ GEM rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) useragent (~> 0.16) - actiontext (8.0.2.1) - actionpack (= 8.0.2.1) - activerecord (= 8.0.2.1) - activestorage (= 8.0.2.1) - activesupport (= 8.0.2.1) + actiontext (8.0.3) + actionpack (= 8.0.3) + activerecord (= 8.0.3) + activestorage (= 8.0.3) + activesupport (= 8.0.3) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (8.0.2.1) - activesupport (= 8.0.2.1) + actionview (8.0.3) + activesupport (= 8.0.3) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) @@ -58,22 +58,22 @@ GEM activemodel (>= 4.1) case_transform (>= 0.2) jsonapi-renderer (>= 0.1.1.beta1, < 0.3) - activejob (8.0.2.1) - activesupport (= 8.0.2.1) + activejob (8.0.3) + activesupport (= 8.0.3) globalid (>= 0.3.6) - activemodel (8.0.2.1) - activesupport (= 8.0.2.1) - activerecord (8.0.2.1) - activemodel (= 8.0.2.1) - activesupport (= 8.0.2.1) + activemodel (8.0.3) + activesupport (= 8.0.3) + activerecord (8.0.3) + activemodel (= 8.0.3) + activesupport (= 8.0.3) timeout (>= 0.4.0) - activestorage (8.0.2.1) - actionpack (= 8.0.2.1) - activejob (= 8.0.2.1) - activerecord (= 8.0.2.1) - activesupport (= 8.0.2.1) + activestorage (8.0.3) + actionpack (= 8.0.3) + activejob (= 8.0.3) + activerecord (= 8.0.3) + activesupport (= 8.0.3) marcel (~> 1.0) - activesupport (8.0.2.1) + activesupport (8.0.3) base64 benchmark (>= 0.3) bigdecimal @@ -447,7 +447,7 @@ GEM mutex_m (0.3.0) net-http (0.6.0) uri - net-imap (0.5.9) + net-imap (0.5.10) date net-protocol net-ldap (0.20.0) @@ -669,20 +669,20 @@ GEM rack (>= 1.3) rackup (2.2.1) rack (>= 3) - rails (8.0.2.1) - actioncable (= 8.0.2.1) - actionmailbox (= 8.0.2.1) - actionmailer (= 8.0.2.1) - actionpack (= 8.0.2.1) - actiontext (= 8.0.2.1) - actionview (= 8.0.2.1) - activejob (= 8.0.2.1) - activemodel (= 8.0.2.1) - activerecord (= 8.0.2.1) - activestorage (= 8.0.2.1) - activesupport (= 8.0.2.1) + rails (8.0.3) + actioncable (= 8.0.3) + actionmailbox (= 8.0.3) + actionmailer (= 8.0.3) + actionpack (= 8.0.3) + actiontext (= 8.0.3) + actionview (= 8.0.3) + activejob (= 8.0.3) + activemodel (= 8.0.3) + activerecord (= 8.0.3) + activestorage (= 8.0.3) + activesupport (= 8.0.3) bundler (>= 1.15.0) - railties (= 8.0.2.1) + railties (= 8.0.3) rails-dom-testing (2.3.0) activesupport (>= 5.0.0) minitest @@ -693,13 +693,14 @@ GEM rails-i18n (8.0.2) i18n (>= 0.7, < 2) railties (>= 8.0.0, < 9) - railties (8.0.2.1) - actionpack (= 8.0.2.1) - activesupport (= 8.0.2.1) + railties (8.0.3) + actionpack (= 8.0.3) + activesupport (= 8.0.3) irb (~> 1.13) rackup (>= 1.0.0) rake (>= 12.2) thor (~> 1.0, >= 1.2.2) + tsort (>= 0.2) zeitwerk (~> 2.6) rainbow (3.1.1) rake (13.3.0) @@ -879,6 +880,7 @@ GEM bindata (~> 2.4) openssl (> 2.0) openssl-signature_algorithm (~> 1.0) + tsort (0.2.0) tty-color (0.6.0) tty-cursor (0.7.1) tty-prompt (0.23.1) From 85213dab471544114507345a1aeb182a34b138ab Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 25 Sep 2025 07:56:33 +0000 Subject: [PATCH 007/853] chore(deps): update yarn to v4.10.3 (#36178) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- streaming/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index e38bc68e37e913..2d0fa230cd65f5 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@mastodon/mastodon", "license": "AGPL-3.0-or-later", - "packageManager": "yarn@4.9.4", + "packageManager": "yarn@4.10.3", "engines": { "node": ">=20" }, diff --git a/streaming/package.json b/streaming/package.json index 05acc580312167..b77cfc02ad6866 100644 --- a/streaming/package.json +++ b/streaming/package.json @@ -1,7 +1,7 @@ { "name": "@mastodon/streaming", "license": "AGPL-3.0-or-later", - "packageManager": "yarn@4.9.4", + "packageManager": "yarn@4.10.3", "engines": { "node": ">=20" }, From 52d5e628a42023302f2d334a325307c0fe2aa87c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 25 Sep 2025 07:57:47 +0000 Subject: [PATCH 008/853] chore(deps): update dependency hiredis-client to v0.26.0 (#36233) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 390debbf5de9b3..ba724ac82b7056 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -300,8 +300,8 @@ GEM highline (3.1.2) reline hiredis (0.6.3) - hiredis-client (0.25.3) - redis-client (= 0.25.3) + hiredis-client (0.26.0) + redis-client (= 0.26.0) hkdf (0.3.0) htmlentities (4.3.4) http (5.3.1) @@ -720,7 +720,7 @@ GEM reline redcarpet (3.6.1) redis (4.8.1) - redis-client (0.25.3) + redis-client (0.26.0) connection_pool regexp_parser (2.11.2) reline (0.6.2) From 507e6dc47317af84606ab81ba101f7a13aa58960 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 25 Sep 2025 07:58:20 +0000 Subject: [PATCH 009/853] fix(deps): update dependency ioredis to v5.8.0 (#36234) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/yarn.lock b/yarn.lock index 6fd58db3043d8e..02f5f7dc5b89ba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2595,10 +2595,10 @@ __metadata: languageName: node linkType: hard -"@ioredis/commands@npm:^1.3.0": - version: 1.3.0 - resolution: "@ioredis/commands@npm:1.3.0" - checksum: 10c0/5ab990a8f69c20daf3d7d64307aa9f13ee727c92ab4c7664a6943bb500227667a0c368892e9c4913f06416377db47dba78d58627fe723da476d25f2c04a6d5aa +"@ioredis/commands@npm:1.4.0": + version: 1.4.0 + resolution: "@ioredis/commands@npm:1.4.0" + checksum: 10c0/99afe21fba794f84a2b84cceabcc370a7622e7b8b97a6589456c07c9fa62a15d54c5546f6f7214fb9a2458b1fa87579d5c531aaf48e06cc9be156d5923892c8d languageName: node linkType: hard @@ -8364,10 +8364,10 @@ __metadata: linkType: hard "ioredis@npm:^5.3.2": - version: 5.7.0 - resolution: "ioredis@npm:5.7.0" + version: 5.8.0 + resolution: "ioredis@npm:5.8.0" dependencies: - "@ioredis/commands": "npm:^1.3.0" + "@ioredis/commands": "npm:1.4.0" cluster-key-slot: "npm:^1.1.0" debug: "npm:^4.3.4" denque: "npm:^2.1.0" @@ -8376,7 +8376,7 @@ __metadata: redis-errors: "npm:^1.2.0" redis-parser: "npm:^3.0.0" standard-as-callback: "npm:^2.1.0" - checksum: 10c0/c63c521a953bfaf29f8c8871b122af38e439328336fa238f83bfbb066556f64daf69ed7a4ec01fc7b9ee1f0862059dd188b8c684150125d362d36642399b30ee + checksum: 10c0/66fad6283c6d9052b4aa0987d592c1bf6c9471304eb0edf0c9d18024b1b38028adf29c05f1cf114b90f5bdb516576f897a654946e8c29568f404ac33cd3b9d19 languageName: node linkType: hard From d2bdb03da0decfec96acc47a2ab97f744c45b2ba Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 25 Sep 2025 10:53:58 +0200 Subject: [PATCH 010/853] New Crowdin Translations (automated) (#36258) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/ar.json | 2 -- app/javascript/mastodon/locales/az.json | 2 -- app/javascript/mastodon/locales/be.json | 2 -- app/javascript/mastodon/locales/bg.json | 2 -- app/javascript/mastodon/locales/br.json | 2 -- app/javascript/mastodon/locales/ca.json | 2 -- app/javascript/mastodon/locales/cs.json | 2 -- app/javascript/mastodon/locales/cy.json | 2 -- app/javascript/mastodon/locales/da.json | 9 +++++++-- app/javascript/mastodon/locales/de.json | 9 +++++++-- app/javascript/mastodon/locales/el.json | 9 +++++++-- app/javascript/mastodon/locales/eo.json | 2 -- app/javascript/mastodon/locales/es-AR.json | 9 +++++++-- app/javascript/mastodon/locales/es-MX.json | 9 +++++++-- app/javascript/mastodon/locales/es.json | 9 +++++++-- app/javascript/mastodon/locales/et.json | 2 -- app/javascript/mastodon/locales/fa.json | 2 -- app/javascript/mastodon/locales/fi.json | 9 +++++++-- app/javascript/mastodon/locales/fo.json | 2 -- app/javascript/mastodon/locales/fr-CA.json | 2 -- app/javascript/mastodon/locales/fr.json | 2 -- app/javascript/mastodon/locales/fy.json | 2 -- app/javascript/mastodon/locales/ga.json | 2 -- app/javascript/mastodon/locales/gd.json | 2 -- app/javascript/mastodon/locales/gl.json | 11 ++++++++--- app/javascript/mastodon/locales/he.json | 9 +++++++-- app/javascript/mastodon/locales/hu.json | 2 -- app/javascript/mastodon/locales/ia.json | 13 +++++++++++-- app/javascript/mastodon/locales/is.json | 2 -- app/javascript/mastodon/locales/it.json | 11 +++++++++-- app/javascript/mastodon/locales/ja.json | 1 - app/javascript/mastodon/locales/kab.json | 1 - app/javascript/mastodon/locales/ko.json | 2 -- app/javascript/mastodon/locales/lt.json | 2 -- app/javascript/mastodon/locales/lv.json | 1 - app/javascript/mastodon/locales/nan.json | 2 -- app/javascript/mastodon/locales/nl.json | 2 -- app/javascript/mastodon/locales/nn.json | 2 -- app/javascript/mastodon/locales/pl.json | 2 -- app/javascript/mastodon/locales/pt-BR.json | 2 -- app/javascript/mastodon/locales/pt-PT.json | 11 +++++++++-- app/javascript/mastodon/locales/ru.json | 2 -- app/javascript/mastodon/locales/sv.json | 2 -- app/javascript/mastodon/locales/tr.json | 9 +++++++-- app/javascript/mastodon/locales/uk.json | 2 -- app/javascript/mastodon/locales/vi.json | 9 +++++++-- app/javascript/mastodon/locales/zh-CN.json | 11 ++++++++--- app/javascript/mastodon/locales/zh-TW.json | 9 +++++++-- config/locales/da.yml | 2 +- 49 files changed, 123 insertions(+), 96 deletions(-) diff --git a/app/javascript/mastodon/locales/ar.json b/app/javascript/mastodon/locales/ar.json index 3af126d5e71b0b..eb4933e1880625 100644 --- a/app/javascript/mastodon/locales/ar.json +++ b/app/javascript/mastodon/locales/ar.json @@ -861,8 +861,6 @@ "status.cancel_reblog_private": "إلغاء إعادة النشر", "status.cannot_quote": "غير مصرح لك باقتباس هذا المنشور", "status.cannot_reblog": "لا يمكن إعادة نشر هذا المنشور", - "status.context.load_new_replies": "الردود الجديدة المتاحة", - "status.context.loading": "التحقق من المزيد من الردود", "status.continued_thread": "تكملة للخيط", "status.copy": "انسخ رابط الرسالة", "status.delete": "احذف", diff --git a/app/javascript/mastodon/locales/az.json b/app/javascript/mastodon/locales/az.json index be7541011e3fb4..4c7a61746f3124 100644 --- a/app/javascript/mastodon/locales/az.json +++ b/app/javascript/mastodon/locales/az.json @@ -829,8 +829,6 @@ "status.bookmark": "Əlfəcin", "status.cancel_reblog_private": "Təkrar paylaşımı geri al", "status.cannot_reblog": "Bu göndəriş təkrar paylaşıla bilməz", - "status.context.load_new_replies": "Yeni cavablar mövcuddur", - "status.context.loading": "Daha çox cavab yoxlanılır", "status.continued_thread": "Davam edən mövzu", "status.copy": "Göndəriş keçidini kopyala", "status.delete": "Sil", diff --git a/app/javascript/mastodon/locales/be.json b/app/javascript/mastodon/locales/be.json index bf4f493831edb9..c61938faf5331a 100644 --- a/app/javascript/mastodon/locales/be.json +++ b/app/javascript/mastodon/locales/be.json @@ -864,8 +864,6 @@ "status.cancel_reblog_private": "Прыбраць", "status.cannot_quote": "Вы не маеце дазвол цытаваць гэты допіс", "status.cannot_reblog": "Гэты допіс нельга пашырыць", - "status.context.load_new_replies": "Даступныя новыя адказы", - "status.context.loading": "Правяраюцца новыя адказы", "status.continued_thread": "Працяг ланцужка", "status.copy": "Скапіраваць спасылку на допіс", "status.delete": "Выдаліць", diff --git a/app/javascript/mastodon/locales/bg.json b/app/javascript/mastodon/locales/bg.json index 618ce28c61b43f..b148994b552979 100644 --- a/app/javascript/mastodon/locales/bg.json +++ b/app/javascript/mastodon/locales/bg.json @@ -832,8 +832,6 @@ "status.bookmark": "Отмятане", "status.cancel_reblog_private": "Край на подсилването", "status.cannot_reblog": "Публикацията не може да се подсилва", - "status.context.load_new_replies": "Има нови отговори", - "status.context.loading": "Проверка за още отговори", "status.continued_thread": "Продължена нишка", "status.copy": "Копиране на връзката към публикация", "status.delete": "Изтриване", diff --git a/app/javascript/mastodon/locales/br.json b/app/javascript/mastodon/locales/br.json index 0f2f63c9ce75e6..5a4828daf53c25 100644 --- a/app/javascript/mastodon/locales/br.json +++ b/app/javascript/mastodon/locales/br.json @@ -653,8 +653,6 @@ "status.bookmark": "Ouzhpennañ d'ar sinedoù", "status.cancel_reblog_private": "Nac'hañ ar skignadenn", "status.cannot_reblog": "Ar c'hannad-se na c'hall ket bezañ skignet", - "status.context.load_new_replies": "Respontoù nevez zo", - "status.context.loading": "O kerc'hat muioc'h a respontoù", "status.copy": "Eilañ liamm ar c'hannad", "status.delete": "Dilemel", "status.delete.success": "Embannadur dilamet", diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json index 5f3d6913ab2b62..ee6e5050a8d49a 100644 --- a/app/javascript/mastodon/locales/ca.json +++ b/app/javascript/mastodon/locales/ca.json @@ -844,8 +844,6 @@ "status.bookmark": "Marca", "status.cancel_reblog_private": "Desfés l'impuls", "status.cannot_reblog": "No es pot impulsar aquest tut", - "status.context.load_new_replies": "Hi ha respostes noves", - "status.context.loading": "Comprovació de més respostes", "status.continued_thread": "Continuació del fil", "status.copy": "Copia l'enllaç al tut", "status.delete": "Elimina", diff --git a/app/javascript/mastodon/locales/cs.json b/app/javascript/mastodon/locales/cs.json index d1aaffe2f2a348..3b4138cbc8081f 100644 --- a/app/javascript/mastodon/locales/cs.json +++ b/app/javascript/mastodon/locales/cs.json @@ -865,8 +865,6 @@ "status.cannot_quote": "Nemáte oprávnění citovat tento příspěvek", "status.cannot_reblog": "Tento příspěvek nemůže být boostnutý", "status.contains_quote": "Obsahuje citaci", - "status.context.load_new_replies": "K dispozici jsou nové odpovědi", - "status.context.loading": "Hledání dalších odpovědí", "status.continued_thread": "Pokračuje ve vlákně", "status.copy": "Zkopírovat odkaz na příspěvek", "status.delete": "Smazat", diff --git a/app/javascript/mastodon/locales/cy.json b/app/javascript/mastodon/locales/cy.json index 6d8129e7036e0a..851ec1d5594f09 100644 --- a/app/javascript/mastodon/locales/cy.json +++ b/app/javascript/mastodon/locales/cy.json @@ -865,8 +865,6 @@ "status.cannot_quote": "Does dim caniatâd i chi ddyfynnu'r postiad hwn", "status.cannot_reblog": "Does dim modd hybu'r postiad hwn", "status.contains_quote": "Yn cynnwys dyfyniad", - "status.context.load_new_replies": "Mae atebion newydd ar gael", - "status.context.loading": "Yn chwilio am fwy o atebion", "status.continued_thread": "Edefyn parhaus", "status.copy": "Copïo dolen i'r post", "status.delete": "Dileu", diff --git a/app/javascript/mastodon/locales/da.json b/app/javascript/mastodon/locales/da.json index 9521401bca01fe..b22190881f10aa 100644 --- a/app/javascript/mastodon/locales/da.json +++ b/app/javascript/mastodon/locales/da.json @@ -865,8 +865,13 @@ "status.cannot_quote": "Du har ikke tilladelse til at citere dette indlæg", "status.cannot_reblog": "Dette indlæg kan ikke fremhæves", "status.contains_quote": "Indeholder citat", - "status.context.load_new_replies": "Nye svar tilgængelige", - "status.context.loading": "Tjekker for flere svar", + "status.context.loading": "Indlæser flere svar", + "status.context.loading_error": "Kunne ikke indlæse nye svar", + "status.context.loading_more": "Indlæser flere svar", + "status.context.loading_success": "Alle svar indlæst", + "status.context.more_replies_found": "Flere svar fundet", + "status.context.retry": "Prøv igen", + "status.context.show": "Vis", "status.continued_thread": "Fortsat tråd", "status.copy": "Kopiér link til indlæg", "status.delete": "Slet", diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json index 7ceb4509dc9497..910ed0c19add70 100644 --- a/app/javascript/mastodon/locales/de.json +++ b/app/javascript/mastodon/locales/de.json @@ -865,8 +865,13 @@ "status.cannot_quote": "Dir ist es nicht gestattet, diesen Beitrag zu zitieren", "status.cannot_reblog": "Dieser Beitrag kann nicht geteilt werden", "status.contains_quote": "Enthält Zitat", - "status.context.load_new_replies": "Neue Antworten verfügbar", - "status.context.loading": "Weitere Antworten werden abgerufen", + "status.context.loading": "Weitere Antworten werden geladen", + "status.context.loading_error": "Neue Antworten konnten nicht geladen werden", + "status.context.loading_more": "Weitere Antworten werden geladen", + "status.context.loading_success": "Alle Antworten geladen", + "status.context.more_replies_found": "Weitere Antworten verfügbar", + "status.context.retry": "Wiederholen", + "status.context.show": "Anzeigen", "status.continued_thread": "Fortgeführter Thread", "status.copy": "Link zum Beitrag kopieren", "status.delete": "Beitrag löschen", diff --git a/app/javascript/mastodon/locales/el.json b/app/javascript/mastodon/locales/el.json index feefaabeea6fa7..9b5479feeb0ed7 100644 --- a/app/javascript/mastodon/locales/el.json +++ b/app/javascript/mastodon/locales/el.json @@ -865,8 +865,13 @@ "status.cannot_quote": "Δε σας επιτρέπετε να παραθέσετε αυτή την ανάρτηση", "status.cannot_reblog": "Αυτή η ανάρτηση δεν μπορεί να ενισχυθεί", "status.contains_quote": "Περιέχει παράθεση", - "status.context.load_new_replies": "Νέες απαντήσεις διαθέσιμες", - "status.context.loading": "Γίνεται έλεγχος για περισσότερες απαντήσεις", + "status.context.loading": "Φόρτωση περισσότερων απαντήσεων", + "status.context.loading_error": "Αδυναμία φόρτωσης νέων απαντήσεων", + "status.context.loading_more": "Φόρτωση περισσότερων απαντήσεων", + "status.context.loading_success": "Όλες οι απαντήσεις φορτώθηκαν", + "status.context.more_replies_found": "Βρέθηκαν περισσότερες απαντήσεις", + "status.context.retry": "Επανάληψη", + "status.context.show": "Εμφάνιση", "status.continued_thread": "Συνεχιζόμενο νήματος", "status.copy": "Αντιγραφή συνδέσμου ανάρτησης", "status.delete": "Διαγραφή", diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json index 34967d20b09b5a..c1d650e3a10d74 100644 --- a/app/javascript/mastodon/locales/eo.json +++ b/app/javascript/mastodon/locales/eo.json @@ -849,8 +849,6 @@ "status.cancel_reblog_private": "Ne plu diskonigi", "status.cannot_quote": "Vi ne rajtas citi ĉi tiun afiŝon", "status.cannot_reblog": "Ĉi tiun afiŝon ne eblas diskonigi", - "status.context.load_new_replies": "Disponeblaj novaj respondoj", - "status.context.loading": "Serĉante pliajn respondojn", "status.continued_thread": "Daŭrigis fadenon", "status.copy": "Kopii la ligilon al la afiŝo", "status.delete": "Forigi", diff --git a/app/javascript/mastodon/locales/es-AR.json b/app/javascript/mastodon/locales/es-AR.json index 3f582452d51bda..3bd5172e13e869 100644 --- a/app/javascript/mastodon/locales/es-AR.json +++ b/app/javascript/mastodon/locales/es-AR.json @@ -865,8 +865,13 @@ "status.cannot_quote": "No te es permitido citar este mensaje", "status.cannot_reblog": "No se puede adherir a este mensaje", "status.contains_quote": "Contiene cita", - "status.context.load_new_replies": "Hay nuevas respuestas", - "status.context.loading": "Buscando más respuestas", + "status.context.loading": "Cargando más respuestas", + "status.context.loading_error": "No se pudieron cargar nuevas respuestas", + "status.context.loading_more": "Cargando más respuestas", + "status.context.loading_success": "Se cargaron todas las respuestas", + "status.context.more_replies_found": "Se encontraron más respuestas", + "status.context.retry": "Reintentar", + "status.context.show": "Mostrar", "status.continued_thread": "Continuación de hilo", "status.copy": "Copiar enlace al mensaje", "status.delete": "Eliminar", diff --git a/app/javascript/mastodon/locales/es-MX.json b/app/javascript/mastodon/locales/es-MX.json index 6b48c21d36127b..9c37456a3e0ba2 100644 --- a/app/javascript/mastodon/locales/es-MX.json +++ b/app/javascript/mastodon/locales/es-MX.json @@ -865,8 +865,13 @@ "status.cannot_quote": "No está permitido citar esta publicación", "status.cannot_reblog": "Esta publicación no puede ser impulsada", "status.contains_quote": "Contiene cita", - "status.context.load_new_replies": "Nuevas respuestas disponibles", - "status.context.loading": "Comprobando si hay más respuestas", + "status.context.loading": "Cargando más respuestas", + "status.context.loading_error": "No se pudieron cargar nuevas respuestas", + "status.context.loading_more": "Cargando más respuestas", + "status.context.loading_success": "Todas las respuestas cargadas", + "status.context.more_replies_found": "Se han encontrado más respuestas", + "status.context.retry": "Reintentar", + "status.context.show": "Mostrar", "status.continued_thread": "Hilo continuado", "status.copy": "Copiar enlace al estado", "status.delete": "Borrar", diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json index f84cb4151145fb..67eda71cf95ad6 100644 --- a/app/javascript/mastodon/locales/es.json +++ b/app/javascript/mastodon/locales/es.json @@ -865,8 +865,13 @@ "status.cannot_quote": "No tienes permiso para citar esta publicación", "status.cannot_reblog": "Esta publicación no se puede impulsar", "status.contains_quote": "Contiene cita", - "status.context.load_new_replies": "Hay nuevas respuestas", - "status.context.loading": "Buscando más respuestas", + "status.context.loading": "Cargando más respuestas", + "status.context.loading_error": "No se pudieron cargar nuevas respuestas", + "status.context.loading_more": "Cargando más respuestas", + "status.context.loading_success": "Se cargaron todas las respuestas", + "status.context.more_replies_found": "Se encontraron más respuestas", + "status.context.retry": "Reintentar", + "status.context.show": "Mostrar", "status.continued_thread": "Continuó el hilo", "status.copy": "Copiar enlace a la publicación", "status.delete": "Borrar", diff --git a/app/javascript/mastodon/locales/et.json b/app/javascript/mastodon/locales/et.json index 4aaeb514210258..b57383da234df0 100644 --- a/app/javascript/mastodon/locales/et.json +++ b/app/javascript/mastodon/locales/et.json @@ -865,8 +865,6 @@ "status.cannot_quote": "Sul pole õigust seda postitust tsiteerida", "status.cannot_reblog": "Seda postitust ei saa jagada", "status.contains_quote": "Sisaldab tsitaati", - "status.context.load_new_replies": "Leidub uusi vastuseid", - "status.context.loading": "Kontrollin täiendavate vastuste olemasolu", "status.continued_thread": "Jätkatud lõim", "status.copy": "Kopeeri postituse link", "status.delete": "Kustuta", diff --git a/app/javascript/mastodon/locales/fa.json b/app/javascript/mastodon/locales/fa.json index b2b0a6c2de372c..64e3ec83d1d947 100644 --- a/app/javascript/mastodon/locales/fa.json +++ b/app/javascript/mastodon/locales/fa.json @@ -842,8 +842,6 @@ "status.bookmark": "نشانک", "status.cancel_reblog_private": "ناتقویت", "status.cannot_reblog": "این فرسته قابل تقویت نیست", - "status.context.load_new_replies": "پاسخ‌های جدیدی موجودند", - "status.context.loading": "بررسی کردن برای پاسخ‌های بیش‌تر", "status.continued_thread": "رشتهٔ دنباله دار", "status.copy": "رونوشت از پیوند فرسته", "status.delete": "حذف", diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json index 8bf69ab31d873b..aad79c9fe96e46 100644 --- a/app/javascript/mastodon/locales/fi.json +++ b/app/javascript/mastodon/locales/fi.json @@ -865,8 +865,13 @@ "status.cannot_quote": "Sinulla ei ole oikeutta lainata tätä julkaisua", "status.cannot_reblog": "Tätä julkaisua ei voi tehostaa", "status.contains_quote": "Sisältää lainauksen", - "status.context.load_new_replies": "Uusia vastauksia saatavilla", - "status.context.loading": "Tarkistetaan lisävastauksia", + "status.context.loading": "Ladataan lisää vastauksia", + "status.context.loading_error": "Ei voitu ladata lisää vastauksia", + "status.context.loading_more": "Ladataan lisää vastauksia", + "status.context.loading_success": "Kaikki vastaukset ladattu", + "status.context.more_replies_found": "Löytyi lisää vastauksia", + "status.context.retry": "Yritä uudelleen", + "status.context.show": "Näytä", "status.continued_thread": "Jatkoi ketjua", "status.copy": "Kopioi linkki julkaisuun", "status.delete": "Poista", diff --git a/app/javascript/mastodon/locales/fo.json b/app/javascript/mastodon/locales/fo.json index a8db9baeca0078..348de34eb19758 100644 --- a/app/javascript/mastodon/locales/fo.json +++ b/app/javascript/mastodon/locales/fo.json @@ -865,8 +865,6 @@ "status.cannot_quote": "Tú hevur ikki loyvi at sitera hendan postin", "status.cannot_reblog": "Tað ber ikki til at stimbra hendan postin", "status.contains_quote": "Inniheldur sitat", - "status.context.load_new_replies": "Nýggj svar tøk", - "status.context.loading": "Kanni um tað eru fleiri svar", "status.continued_thread": "Framhaldandi tráður", "status.copy": "Kopiera leinki til postin", "status.delete": "Strika", diff --git a/app/javascript/mastodon/locales/fr-CA.json b/app/javascript/mastodon/locales/fr-CA.json index 2bc6195c55cec2..742d502fd58edb 100644 --- a/app/javascript/mastodon/locales/fr-CA.json +++ b/app/javascript/mastodon/locales/fr-CA.json @@ -864,8 +864,6 @@ "status.cancel_reblog_private": "Débooster", "status.cannot_quote": "Vous n'êtes pas autorisé à citer ce message", "status.cannot_reblog": "Cette publication ne peut pas être boostée", - "status.context.load_new_replies": "Nouvelles réponses disponibles", - "status.context.loading": "Vérification de plus de réponses", "status.continued_thread": "Suite du fil", "status.copy": "Copier un lien vers cette publication", "status.delete": "Supprimer", diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json index e579dbe09b904f..38a1215fd430af 100644 --- a/app/javascript/mastodon/locales/fr.json +++ b/app/javascript/mastodon/locales/fr.json @@ -864,8 +864,6 @@ "status.cancel_reblog_private": "Annuler le partage", "status.cannot_quote": "Vous n'êtes pas autorisé à citer ce message", "status.cannot_reblog": "Ce message ne peut pas être partagé", - "status.context.load_new_replies": "Nouvelles réponses disponibles", - "status.context.loading": "Vérification de plus de réponses", "status.continued_thread": "Suite du fil", "status.copy": "Copier le lien vers le message", "status.delete": "Supprimer", diff --git a/app/javascript/mastodon/locales/fy.json b/app/javascript/mastodon/locales/fy.json index 31b5196f3edc0b..d0da2af6bb16c2 100644 --- a/app/javascript/mastodon/locales/fy.json +++ b/app/javascript/mastodon/locales/fy.json @@ -834,8 +834,6 @@ "status.bookmark": "Blêdwizer tafoegje", "status.cancel_reblog_private": "Net langer booste", "status.cannot_reblog": "Dit berjocht kin net boost wurde", - "status.context.load_new_replies": "Nije reaksjes beskikber", - "status.context.loading": "Op nije reaksjes oan it kontrolearjen", "status.continued_thread": "Ferfolgje it petear", "status.copy": "Copy link to status", "status.delete": "Fuortsmite", diff --git a/app/javascript/mastodon/locales/ga.json b/app/javascript/mastodon/locales/ga.json index 4ede71c4870b90..2277128032c344 100644 --- a/app/javascript/mastodon/locales/ga.json +++ b/app/javascript/mastodon/locales/ga.json @@ -865,8 +865,6 @@ "status.cannot_quote": "Ní cheadaítear duit an post seo a lua", "status.cannot_reblog": "Ní féidir an phostáil seo a mholadh", "status.contains_quote": "Tá luachan ann", - "status.context.load_new_replies": "Freagraí nua ar fáil", - "status.context.loading": "Ag seiceáil le haghaidh tuilleadh freagraí", "status.continued_thread": "Snáithe ar lean", "status.copy": "Cóipeáil an nasc chuig an bpostáil", "status.delete": "Scrios", diff --git a/app/javascript/mastodon/locales/gd.json b/app/javascript/mastodon/locales/gd.json index 2b2efe733c8950..0b582c6fda9e18 100644 --- a/app/javascript/mastodon/locales/gd.json +++ b/app/javascript/mastodon/locales/gd.json @@ -864,8 +864,6 @@ "status.cancel_reblog_private": "Na brosnaich tuilleadh", "status.cannot_quote": "Chan fhaod thu am post seo a luaidh", "status.cannot_reblog": "Cha ghabh am post seo brosnachadh", - "status.context.load_new_replies": "Tha freagairt no dhà ùr ri fhaighinn", - "status.context.loading": "A’ toirt sùil airson barrachd fhreagairtean", "status.continued_thread": "Pàirt de shnàithlean", "status.copy": "Dèan lethbhreac dhen cheangal dhan phost", "status.delete": "Sguab às", diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json index 2d37337a0c10f8..c724e3d9cf1e36 100644 --- a/app/javascript/mastodon/locales/gl.json +++ b/app/javascript/mastodon/locales/gl.json @@ -851,7 +851,7 @@ "server_banner.is_one_of_many": "{domain} é un dos moitos servidores Mastodon independentes que podes usar para participar do Fediverso.", "server_banner.server_stats": "Estatísticas do servidor:", "sign_in_banner.create_account": "Crear conta", - "sign_in_banner.follow_anyone": "Sigue a quen queiras no Fediverso e le as publicacións en orde cronolóxica. Sen algoritmos, publicidade nin titulares engañosos.", + "sign_in_banner.follow_anyone": "Sigue a quen queiras no Fediverso e le as publicacións en orde cronolóxica. Sen algoritmos, publicidade nin titulares enganosos.", "sign_in_banner.mastodon_is": "Mastodon é o mellor xeito de estar ao día do que acontece.", "sign_in_banner.sign_in": "Iniciar sesión", "sign_in_banner.sso_redirect": "Acceder ou Crear conta", @@ -865,8 +865,13 @@ "status.cannot_quote": "Non tes permiso para citar esta publicación", "status.cannot_reblog": "Esta publicación non pode ser promovida", "status.contains_quote": "Contén unha cita", - "status.context.load_new_replies": "Non hai respostas dispoñibles", - "status.context.loading": "Mirando se hai máis respostas", + "status.context.loading": "Cargando máis respostas", + "status.context.loading_error": "Non se puideron mostrar novas respostas", + "status.context.loading_more": "Cargando máis respostas", + "status.context.loading_success": "Móstranse todas as respostas", + "status.context.more_replies_found": "Existen máis respostas", + "status.context.retry": "Volver tentar", + "status.context.show": "Mostrar", "status.continued_thread": "Continua co fío", "status.copy": "Copiar ligazón á publicación", "status.delete": "Eliminar", diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json index bcba5e0b7ce103..6adcc4b406c7e9 100644 --- a/app/javascript/mastodon/locales/he.json +++ b/app/javascript/mastodon/locales/he.json @@ -865,8 +865,13 @@ "status.cannot_quote": "אין לך הרשאה לצטט את ההודעה הזו", "status.cannot_reblog": "לא ניתן להדהד חצרוץ זה", "status.contains_quote": "הודעה מכילה ציטוט", - "status.context.load_new_replies": "הגיעו תגובות חדשות", - "status.context.loading": "מחפש תגובות חדשות", + "status.context.loading": "נטענות תשובות נוספות", + "status.context.loading_error": "טעינת תשובות נוספות נכשלה", + "status.context.loading_more": "נטענות תשובות נוספות", + "status.context.loading_success": "כל התשובות נטענו", + "status.context.more_replies_found": "תשובות נוספות נמצאו", + "status.context.retry": "נסה שוב", + "status.context.show": "הצג", "status.continued_thread": "שרשור מתמשך", "status.copy": "העתק/י קישור להודעה זו", "status.delete": "מחיקה", diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json index 83fb3e60fe4c6e..80693f586e3a7a 100644 --- a/app/javascript/mastodon/locales/hu.json +++ b/app/javascript/mastodon/locales/hu.json @@ -865,8 +865,6 @@ "status.cannot_quote": "Nem idézheted ezt a bejegyzést", "status.cannot_reblog": "Ezt a bejegyzést nem lehet megtolni", "status.contains_quote": "Idézést tartalmaz", - "status.context.load_new_replies": "Új válaszok érhetőek el", - "status.context.loading": "További válaszok keresése", "status.continued_thread": "Folytatott szál", "status.copy": "Link másolása bejegyzésbe", "status.delete": "Törlés", diff --git a/app/javascript/mastodon/locales/ia.json b/app/javascript/mastodon/locales/ia.json index 8291e8ad5f9040..9b3c8f8ed48555 100644 --- a/app/javascript/mastodon/locales/ia.json +++ b/app/javascript/mastodon/locales/ia.json @@ -864,8 +864,14 @@ "status.cancel_reblog_private": "Disfacer impulso", "status.cannot_quote": "Tu non es autorisate a citar iste message", "status.cannot_reblog": "Iste message non pote esser impulsate", - "status.context.load_new_replies": "Nove responsas disponibile", - "status.context.loading": "Cercante plus responsas", + "status.contains_quote": "Contine un citation", + "status.context.loading": "Cargante plus responsas", + "status.context.loading_error": "Non poteva cargar nove responsas", + "status.context.loading_more": "Cargante plus responsas", + "status.context.loading_success": "Tote le responsas cargate", + "status.context.more_replies_found": "Plus responsas trovate", + "status.context.retry": "Tentar de novo", + "status.context.show": "Monstrar", "status.continued_thread": "Continuation del discussion", "status.copy": "Copiar ligamine a message", "status.delete": "Deler", @@ -895,12 +901,15 @@ "status.quote": "Citar", "status.quote.cancel": "Cancellar le citation", "status.quote_error.filtered": "Celate a causa de un de tu filtros", + "status.quote_error.limited_account_hint.action": "Monstrar in omne caso", + "status.quote_error.limited_account_hint.title": "Iste conto ha essite celate per le moderatores de {domain}.", "status.quote_error.not_available": "Message indisponibile", "status.quote_error.pending_approval": "Message pendente", "status.quote_error.pending_approval_popout.body": "Sur Mastodon, tu pote controlar si on pote citar te. Iste message attende ora le approbation del autor original.", "status.quote_error.revoked": "Message removite per le autor", "status.quote_followers_only": "Solmente sequitores pote citar iste message", "status.quote_manual_review": "Le autor lo examinara manualmente", + "status.quote_noun": "Citation", "status.quote_policy_change": "Cambiar qui pote citar", "status.quote_post_author": "Ha citate un message de @{name}", "status.quote_private": "Le messages private non pote esser citate", diff --git a/app/javascript/mastodon/locales/is.json b/app/javascript/mastodon/locales/is.json index f380a4b4a50c80..92bae015319096 100644 --- a/app/javascript/mastodon/locales/is.json +++ b/app/javascript/mastodon/locales/is.json @@ -864,8 +864,6 @@ "status.cancel_reblog_private": "Taka úr endurbirtingu", "status.cannot_quote": "Þú hefur ekki heimild til að vitna í þessa færslu", "status.cannot_reblog": "Þessa færslu er ekki hægt að endurbirta", - "status.context.load_new_replies": "Ný svör hafa borist", - "status.context.loading": "Athuga með fleiri svör", "status.continued_thread": "Hélt samtali áfram", "status.copy": "Afrita tengil í færslu", "status.delete": "Eyða", diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json index 448b51944bd349..3dde3f5775c4e6 100644 --- a/app/javascript/mastodon/locales/it.json +++ b/app/javascript/mastodon/locales/it.json @@ -864,8 +864,14 @@ "status.cancel_reblog_private": "Annulla reblog", "status.cannot_quote": "Non ti è consentito citare questo post", "status.cannot_reblog": "Questo post non può essere condiviso", - "status.context.load_new_replies": "Nuove risposte disponibili", - "status.context.loading": "Controllo per altre risposte", + "status.contains_quote": "Contiene una citazione", + "status.context.loading": "Caricamento di altre risposte", + "status.context.loading_error": "Impossibile caricare nuove risposte", + "status.context.loading_more": "Caricamento di altre risposte", + "status.context.loading_success": "Tutte le risposte caricate", + "status.context.more_replies_found": "Sono state trovate altre risposte", + "status.context.retry": "Riprova", + "status.context.show": "Mostra", "status.continued_thread": "Discussione continua", "status.copy": "Copia link al post", "status.delete": "Elimina", @@ -903,6 +909,7 @@ "status.quote_error.revoked": "Post rimosso dall'autore", "status.quote_followers_only": "Solo i seguaci possono citare questo post", "status.quote_manual_review": "L'autore esaminerà manualmente", + "status.quote_noun": "Citazione", "status.quote_policy_change": "Cambia chi può citare", "status.quote_post_author": "Citato un post di @{name}", "status.quote_private": "I post privati non possono essere citati", diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json index ba42000ec7c350..22377dc7867462 100644 --- a/app/javascript/mastodon/locales/ja.json +++ b/app/javascript/mastodon/locales/ja.json @@ -844,7 +844,6 @@ "status.cancel_reblog_private": "ブースト解除", "status.cannot_quote": "この投稿は引用できません", "status.cannot_reblog": "この投稿はブーストできません", - "status.context.load_new_replies": "新しい返信があります", "status.continued_thread": "続きのスレッド", "status.copy": "投稿へのリンクをコピー", "status.delete": "削除", diff --git a/app/javascript/mastodon/locales/kab.json b/app/javascript/mastodon/locales/kab.json index c48480995753b7..f14f3b5c701ec7 100644 --- a/app/javascript/mastodon/locales/kab.json +++ b/app/javascript/mastodon/locales/kab.json @@ -639,7 +639,6 @@ "status.bookmark": "Creḍ", "status.cancel_reblog_private": "Sefsex beṭṭu", "status.cannot_reblog": "Tasuffeɣt-a ur tezmir ara ad tettwabḍu tikelt-nniḍen", - "status.context.load_new_replies": "Llant tririyin timaynutin", "status.continued_thread": "Asqerdec yettkemmil", "status.copy": "Nɣel assaɣ ɣer tasuffeɣt", "status.delete": "Kkes", diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json index 40c9ae00044bc5..89137643f3f9ef 100644 --- a/app/javascript/mastodon/locales/ko.json +++ b/app/javascript/mastodon/locales/ko.json @@ -861,8 +861,6 @@ "status.bookmark": "북마크", "status.cancel_reblog_private": "부스트 취소", "status.cannot_reblog": "이 게시물은 부스트 할 수 없습니다", - "status.context.load_new_replies": "새 답글 보기", - "status.context.loading": "추가 답글 확인중", "status.continued_thread": "이어지는 글타래", "status.copy": "게시물 링크 복사", "status.delete": "삭제", diff --git a/app/javascript/mastodon/locales/lt.json b/app/javascript/mastodon/locales/lt.json index 6276bb80383152..5f4d357f0d2217 100644 --- a/app/javascript/mastodon/locales/lt.json +++ b/app/javascript/mastodon/locales/lt.json @@ -784,8 +784,6 @@ "status.bookmark": "Pridėti į žymės", "status.cancel_reblog_private": "Nebepasidalinti", "status.cannot_reblog": "Šis įrašas negali būti pakeltas.", - "status.context.load_new_replies": "Yra naujų atsakymų", - "status.context.loading": "Tikrinama dėl daugiau atsakymų", "status.continued_thread": "Tęsiama gijoje", "status.copy": "Kopijuoti nuorodą į įrašą", "status.delete": "Ištrinti", diff --git a/app/javascript/mastodon/locales/lv.json b/app/javascript/mastodon/locales/lv.json index d80b8daf200e9f..ff532bb295c643 100644 --- a/app/javascript/mastodon/locales/lv.json +++ b/app/javascript/mastodon/locales/lv.json @@ -725,7 +725,6 @@ "status.bookmark": "Grāmatzīme", "status.cancel_reblog_private": "Nepastiprināt", "status.cannot_reblog": "Šo ierakstu nevar pastiprināt", - "status.context.loading": "Pārbauda, vai ir vairāk atbilžu", "status.continued_thread": "Turpināts pavediens", "status.copy": "Ievietot ieraksta saiti starpliktuvē", "status.delete": "Dzēst", diff --git a/app/javascript/mastodon/locales/nan.json b/app/javascript/mastodon/locales/nan.json index 9bce13a8dadef2..b070566564b771 100644 --- a/app/javascript/mastodon/locales/nan.json +++ b/app/javascript/mastodon/locales/nan.json @@ -864,8 +864,6 @@ "status.cancel_reblog_private": "取消轉送", "status.cannot_quote": "Lí bô允准引用tsit篇PO文。", "status.cannot_reblog": "Tsit篇PO文bē當轉送", - "status.context.load_new_replies": "有新ê回應", - "status.context.loading": "Leh檢查其他ê回應", "status.continued_thread": "接續ê討論線", "status.copy": "Khóo-pih PO文ê連結", "status.delete": "Thâi掉", diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json index f61f7469d52684..894a93b5fbe702 100644 --- a/app/javascript/mastodon/locales/nl.json +++ b/app/javascript/mastodon/locales/nl.json @@ -865,8 +865,6 @@ "status.cannot_quote": "Je bent niet gemachtigd om dit bericht te citeren", "status.cannot_reblog": "Dit bericht kan niet geboost worden", "status.contains_quote": "Bevat citaat", - "status.context.load_new_replies": "Nieuwe reacties beschikbaar", - "status.context.loading": "Op nieuwe reacties aan het controleren", "status.continued_thread": "Vervolg van gesprek", "status.copy": "Link naar bericht kopiëren", "status.delete": "Verwijderen", diff --git a/app/javascript/mastodon/locales/nn.json b/app/javascript/mastodon/locales/nn.json index caab03e7cd4f71..fe2c5fc925e907 100644 --- a/app/javascript/mastodon/locales/nn.json +++ b/app/javascript/mastodon/locales/nn.json @@ -864,8 +864,6 @@ "status.cancel_reblog_private": "Opphev framheving", "status.cannot_quote": "Du har ikkje løyve til å sitera dette innlegget", "status.cannot_reblog": "Du kan ikkje framheva dette innlegget", - "status.context.load_new_replies": "Nye svar finst", - "status.context.loading": "Ser etter fleire svar", "status.continued_thread": "Framhald til tråden", "status.copy": "Kopier lenke til status", "status.delete": "Slett", diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json index ab1062ed8b0dd2..2fb0a6f1bd2c69 100644 --- a/app/javascript/mastodon/locales/pl.json +++ b/app/javascript/mastodon/locales/pl.json @@ -849,8 +849,6 @@ "status.bookmark": "Dodaj zakładkę", "status.cancel_reblog_private": "Cofnij podbicie", "status.cannot_reblog": "Ten wpis nie może zostać podbity", - "status.context.load_new_replies": "Dostępne są nowe odpowiedzi", - "status.context.loading": "Sprawdzanie kolejnych odpowiedzi", "status.continued_thread": "Ciąg dalszy wątku", "status.copy": "Skopiuj odnośnik do wpisu", "status.delete": "Usuń", diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json index cc46fb4304d29b..e550b7463aece9 100644 --- a/app/javascript/mastodon/locales/pt-BR.json +++ b/app/javascript/mastodon/locales/pt-BR.json @@ -855,8 +855,6 @@ "status.bookmark": "Salvar", "status.cancel_reblog_private": "Desfazer boost", "status.cannot_reblog": "Este toot não pode receber boost", - "status.context.load_new_replies": "Novas respostas disponíveis", - "status.context.loading": "Verificando mais respostas", "status.continued_thread": "Continuação da conversa", "status.copy": "Copiar link", "status.delete": "Excluir", diff --git a/app/javascript/mastodon/locales/pt-PT.json b/app/javascript/mastodon/locales/pt-PT.json index af7c70b9fba6bc..8167b9b49ec250 100644 --- a/app/javascript/mastodon/locales/pt-PT.json +++ b/app/javascript/mastodon/locales/pt-PT.json @@ -864,8 +864,14 @@ "status.cancel_reblog_private": "Retirar impulso", "status.cannot_quote": "Não lhe é permitido citar esta publicação", "status.cannot_reblog": "Esta publicação não pode ser impulsionada", - "status.context.load_new_replies": "Novas respostas disponíveis", - "status.context.loading": "A verificar por mais respostas", + "status.contains_quote": "Contém citação", + "status.context.loading": "A carregar mais respostas", + "status.context.loading_error": "Não foi possível carregar novas respostas", + "status.context.loading_more": "A carregar mais respostas", + "status.context.loading_success": "Todas as respostas carregadas", + "status.context.more_replies_found": "Foram encontradas mais respostas", + "status.context.retry": "Repetir", + "status.context.show": "Mostrar", "status.continued_thread": "Continuação da conversa", "status.copy": "Copiar hiperligação da publicação", "status.delete": "Eliminar", @@ -903,6 +909,7 @@ "status.quote_error.revoked": "Publicação removida pelo autor", "status.quote_followers_only": "Apenas seguidores podem citar esta publicação", "status.quote_manual_review": "O autor vai proceder a uma revisão manual", + "status.quote_noun": "Citação", "status.quote_policy_change": "Alterar quem pode citar", "status.quote_post_author": "Citou uma publicação de @{name}", "status.quote_private": "Publicações privadas não podem ser citadas", diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json index a22268bb62bce2..1416198a42ba29 100644 --- a/app/javascript/mastodon/locales/ru.json +++ b/app/javascript/mastodon/locales/ru.json @@ -863,8 +863,6 @@ "status.bookmark": "Добавить в закладки", "status.cancel_reblog_private": "Отменить продвижение", "status.cannot_reblog": "Этот пост не может быть продвинут", - "status.context.load_new_replies": "Доступны новые ответы", - "status.context.loading": "Проверяем, есть ли ещё ответы", "status.continued_thread": "Продолжение предыдущего поста", "status.copy": "Скопировать ссылку на пост", "status.delete": "Удалить", diff --git a/app/javascript/mastodon/locales/sv.json b/app/javascript/mastodon/locales/sv.json index 3bbe6434ed8e39..e56c9da32636c3 100644 --- a/app/javascript/mastodon/locales/sv.json +++ b/app/javascript/mastodon/locales/sv.json @@ -843,8 +843,6 @@ "status.bookmark": "Bokmärk", "status.cancel_reblog_private": "Sluta boosta", "status.cannot_reblog": "Detta inlägg kan inte boostas", - "status.context.load_new_replies": "Nya svar finns", - "status.context.loading": "Letar efter fler svar", "status.continued_thread": "Fortsatt tråd", "status.copy": "Kopiera inläggslänk", "status.delete": "Radera", diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json index 9d61ed20531467..cc94d324d78485 100644 --- a/app/javascript/mastodon/locales/tr.json +++ b/app/javascript/mastodon/locales/tr.json @@ -865,8 +865,13 @@ "status.cannot_quote": "Bu gönderiyi alıntılamaya izniniz yok", "status.cannot_reblog": "Bu gönderi yeniden paylaşılamaz", "status.contains_quote": "Alıntı içeriyor", - "status.context.load_new_replies": "Yeni yanıtlar mevcut", - "status.context.loading": "Daha fazla yanıt için kontrol ediliyor", + "status.context.loading": "Daha fazla yanıt yükleniyor", + "status.context.loading_error": "Yeni yanıtlar yüklenemiyor", + "status.context.loading_more": "Daha fazla yanıt yükleniyor", + "status.context.loading_success": "Tüm yanıtlar yüklendi", + "status.context.more_replies_found": "Daha fazla yanıt bulundu", + "status.context.retry": "Yeniden dene", + "status.context.show": "Göster", "status.continued_thread": "Devam eden akış", "status.copy": "Gönderi bağlantısını kopyala", "status.delete": "Sil", diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json index 913ef41d74495b..02370341df6c70 100644 --- a/app/javascript/mastodon/locales/uk.json +++ b/app/javascript/mastodon/locales/uk.json @@ -814,8 +814,6 @@ "status.bookmark": "Додати до закладок", "status.cancel_reblog_private": "Скасувати поширення", "status.cannot_reblog": "Цей допис не може бути поширений", - "status.context.load_new_replies": "Доступні нові відповіді", - "status.context.loading": "Перевірка додаткових відповідей", "status.continued_thread": "Продовження у потоці", "status.copy": "Копіювати посилання на допис", "status.delete": "Видалити", diff --git a/app/javascript/mastodon/locales/vi.json b/app/javascript/mastodon/locales/vi.json index 99a5dc9051bf3d..c4e21bbe7ea045 100644 --- a/app/javascript/mastodon/locales/vi.json +++ b/app/javascript/mastodon/locales/vi.json @@ -865,8 +865,13 @@ "status.cannot_quote": "Bạn không được phép trích dẫn tút này", "status.cannot_reblog": "Không thể đăng lại tút này", "status.contains_quote": "Chứa trích dẫn", - "status.context.load_new_replies": "Có những trả lời mới", - "status.context.loading": "Kiểm tra nhiều trả lời hơn", + "status.context.loading": "Tải thêm các trả lời", + "status.context.loading_error": "Không thể tải những trả lời mới", + "status.context.loading_more": "Tải thêm các trả lời", + "status.context.loading_success": "Đã tải toàn bộ trả lời", + "status.context.more_replies_found": "Có trả lời mới", + "status.context.retry": "Thử lại", + "status.context.show": "Hiện", "status.continued_thread": "Tiếp tục chủ đề", "status.copy": "Sao chép URL", "status.delete": "Xóa", diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json index c69e72eced44ee..1c52a6334fb7d4 100644 --- a/app/javascript/mastodon/locales/zh-CN.json +++ b/app/javascript/mastodon/locales/zh-CN.json @@ -862,11 +862,16 @@ "status.block": "屏蔽 @{name}", "status.bookmark": "添加到书签", "status.cancel_reblog_private": "取消转嘟", - "status.cannot_quote": "你无法引用此嘟文", + "status.cannot_quote": "你无权引用这条嘟文", "status.cannot_reblog": "不能转嘟这条嘟文", "status.contains_quote": "包含引用", - "status.context.load_new_replies": "有新回复", - "status.context.loading": "正在检查更多回复", + "status.context.loading": "正在加载更多回复", + "status.context.loading_error": "无法加载新回复", + "status.context.loading_more": "正在加载更多回复", + "status.context.loading_success": "已加载所有回复", + "status.context.more_replies_found": "已找到更多回复", + "status.context.retry": "重试", + "status.context.show": "显示", "status.continued_thread": "上接嘟文串", "status.copy": "复制嘟文链接", "status.delete": "删除", diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json index e4f9dcea29bb52..02edd5f45256d4 100644 --- a/app/javascript/mastodon/locales/zh-TW.json +++ b/app/javascript/mastodon/locales/zh-TW.json @@ -865,8 +865,13 @@ "status.cannot_quote": "您不被允許引用此嘟文", "status.cannot_reblog": "這則嘟文無法被轉嘟", "status.contains_quote": "包含引用嘟文", - "status.context.load_new_replies": "有新回嘟", - "status.context.loading": "正在檢查更多回嘟", + "status.context.loading": "讀取更多回嘟", + "status.context.loading_error": "無法讀取新回嘟", + "status.context.loading_more": "讀取更多回嘟", + "status.context.loading_success": "已讀取所有回嘟", + "status.context.more_replies_found": "已有更多回嘟", + "status.context.retry": "再試一次", + "status.context.show": "顯示", "status.continued_thread": "接續討論串", "status.copy": "複製嘟文連結", "status.delete": "刪除", diff --git a/config/locales/da.yml b/config/locales/da.yml index 9f15c2a43f0e44..8ad3ccb1389bac 100644 --- a/config/locales/da.yml +++ b/config/locales/da.yml @@ -1634,7 +1634,7 @@ da: not_found: kunne ikke findes on_cooldown: Du er på nedkøling followers_count: Følgere på flytningstidspunktet - incoming_migrations: Flytter fra en anden konto + incoming_migrations: Flytning fra en anden konto incoming_migrations_html: For at flytte fra en anden konto til denne skal der først oprettes et kontoalias. moved_msg: Din konto omdirigeres nu til %{acct} og dine følgere overflyttes. not_redirecting: Din konto omdirigerer pt. ikke til nogen anden konto. From 719b2de3c35e947f45626c86bf730b6cbc6a1477 Mon Sep 17 00:00:00 2001 From: Renaud Chaput Date: Thu, 25 Sep 2025 10:54:02 +0200 Subject: [PATCH 011/853] Update `uuid` package to latest version (#36259) --- streaming/package.json | 3 +-- yarn.lock | 20 ++++++-------------- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/streaming/package.json b/streaming/package.json index b77cfc02ad6866..7df035d6e7e910 100644 --- a/streaming/package.json +++ b/streaming/package.json @@ -27,7 +27,7 @@ "pino": "^9.0.0", "pino-http": "^10.0.0", "prom-client": "^15.0.0", - "uuid": "^11.0.0", + "uuid": "^13.0.0", "ws": "^8.12.1" }, "devDependencies": { @@ -35,7 +35,6 @@ "@types/cors": "^2.8.16", "@types/express": "^4.17.17", "@types/pg": "^8.6.6", - "@types/uuid": "^10.0.0", "@types/ws": "^8.5.9", "globals": "^16.0.0", "pino-pretty": "^13.0.0", diff --git a/yarn.lock b/yarn.lock index 02f5f7dc5b89ba..1ca3bec11eddfe 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2892,7 +2892,6 @@ __metadata: "@types/cors": "npm:^2.8.16" "@types/express": "npm:^4.17.17" "@types/pg": "npm:^8.6.6" - "@types/uuid": "npm:^10.0.0" "@types/ws": "npm:^8.5.9" bufferutil: "npm:^4.0.7" cors: "npm:^2.8.5" @@ -2910,7 +2909,7 @@ __metadata: typescript: "npm:~5.9.0" typescript-eslint: "npm:^8.28.0" utf-8-validate: "npm:^6.0.3" - uuid: "npm:^11.0.0" + uuid: "npm:^13.0.0" ws: "npm:^8.12.1" dependenciesMeta: bufferutil: @@ -4488,13 +4487,6 @@ __metadata: languageName: node linkType: hard -"@types/uuid@npm:^10.0.0": - version: 10.0.0 - resolution: "@types/uuid@npm:10.0.0" - checksum: 10c0/9a1404bf287164481cb9b97f6bb638f78f955be57c40c6513b7655160beb29df6f84c915aaf4089a1559c216557dc4d2f79b48d978742d3ae10b937420ddac60 - languageName: node - linkType: hard - "@types/warning@npm:^3.0.0": version: 3.0.2 resolution: "@types/warning@npm:3.0.2" @@ -13791,12 +13783,12 @@ __metadata: languageName: node linkType: hard -"uuid@npm:^11.0.0": - version: 11.1.0 - resolution: "uuid@npm:11.1.0" +"uuid@npm:^13.0.0": + version: 13.0.0 + resolution: "uuid@npm:13.0.0" bin: - uuid: dist/esm/bin/uuid - checksum: 10c0/34aa51b9874ae398c2b799c88a127701408cd581ee89ec3baa53509dd8728cbb25826f2a038f9465f8b7be446f0fbf11558862965b18d21c993684297628d4d3 + uuid: dist-node/bin/uuid + checksum: 10c0/950e4c18d57fef6c69675344f5700a08af21e26b9eff2bf2180427564297368c538ea11ac9fb2e6528b17fc3966a9fd2c5049361b0b63c7d654f3c550c9b3d67 languageName: node linkType: hard From 66686994c1c9a079d3a854f0c2ef5baae4cf16c0 Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 25 Sep 2025 11:25:00 +0200 Subject: [PATCH 012/853] Fix not being able to author quotes with CW but no text (#36153) Co-authored-by: diondiondion --- app/javascript/mastodon/actions/compose.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/javascript/mastodon/actions/compose.js b/app/javascript/mastodon/actions/compose.js index 96c0c43c74cbd0..ccb69f0a3d3d00 100644 --- a/app/javascript/mastodon/actions/compose.js +++ b/app/javascript/mastodon/actions/compose.js @@ -194,8 +194,10 @@ export function submitCompose(successCallback) { const status = getState().getIn(['compose', 'text'], ''); const media = getState().getIn(['compose', 'media_attachments']); const statusId = getState().getIn(['compose', 'id'], null); + const hasQuote = !!getState().getIn(['compose', 'quoted_status_id']); + const spoiler_text = getState().getIn(['compose', 'spoiler']) ? getState().getIn(['compose', 'spoiler_text'], '') : ''; - if ((!status || !status.length) && media.size === 0) { + if (!(status?.length || media.size !== 0 || (hasQuote && spoiler_text?.length))) { return; } @@ -227,11 +229,11 @@ export function submitCompose(successCallback) { method: statusId === null ? 'post' : 'put', data: { status, + spoiler_text, in_reply_to_id: getState().getIn(['compose', 'in_reply_to'], null), media_ids: media.map(item => item.get('id')), media_attributes, sensitive: getState().getIn(['compose', 'sensitive']), - spoiler_text: getState().getIn(['compose', 'spoiler']) ? getState().getIn(['compose', 'spoiler_text'], '') : '', visibility: visibility, poll: getState().getIn(['compose', 'poll'], null), language: getState().getIn(['compose', 'language']), From 6d2493ca7c39a5d60edd7109de0c24256f8fff8c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 25 Sep 2025 12:03:53 +0200 Subject: [PATCH 013/853] chore(deps): update dependency puma to v7.0.4 (#36240) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index ba724ac82b7056..b4d58cbb69f2a9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -637,7 +637,7 @@ GEM date stringio public_suffix (6.0.2) - puma (7.0.3) + puma (7.0.4) nio4r (~> 2.0) pundit (2.5.2) activesupport (>= 3.0.0) From d801cf8e59edaea24cf70f1f62aa4e1ff8d1dcbd Mon Sep 17 00:00:00 2001 From: diondiondion Date: Thu, 25 Sep 2025 14:26:50 +0200 Subject: [PATCH 014/853] Replace `react-router-scroll-4` with inlined implementation (#36253) --- app/javascript/mastodon/components/router.tsx | 5 +- .../mastodon/components/scrollable_list.jsx | 2 +- .../mastodon/containers/mastodon.jsx | 9 +- .../mastodon/containers/scroll_container.js | 18 --- .../default_should_update_scroll.tsx | 25 ++++ .../containers/scroll_container/index.tsx | 62 ++++++++ .../scroll_container/scroll_context.tsx | 141 ++++++++++++++++++ .../scroll_container/state_storage.ts | 46 ++++++ .../mastodon/features/directory/index.tsx | 3 +- .../mastodon/features/status/index.jsx | 6 +- package.json | 2 +- yarn.lock | 55 ++----- 12 files changed, 302 insertions(+), 72 deletions(-) delete mode 100644 app/javascript/mastodon/containers/scroll_container.js create mode 100644 app/javascript/mastodon/containers/scroll_container/default_should_update_scroll.tsx create mode 100644 app/javascript/mastodon/containers/scroll_container/index.tsx create mode 100644 app/javascript/mastodon/containers/scroll_container/scroll_context.tsx create mode 100644 app/javascript/mastodon/containers/scroll_container/state_storage.ts diff --git a/app/javascript/mastodon/components/router.tsx b/app/javascript/mastodon/components/router.tsx index 815b4b59abd725..1dc1d45083dfd9 100644 --- a/app/javascript/mastodon/components/router.tsx +++ b/app/javascript/mastodon/components/router.tsx @@ -1,6 +1,7 @@ import type { PropsWithChildren } from 'react'; import type React from 'react'; +import type { useLocation } from 'react-router'; import { Router as OriginalRouter, useHistory } from 'react-router'; import type { @@ -18,7 +19,9 @@ interface MastodonLocationState { mastodonModalKey?: string; } -type LocationState = MastodonLocationState | null | undefined; +export type LocationState = MastodonLocationState | null | undefined; + +export type MastodonLocation = ReturnType>; type HistoryPath = Path | LocationDescriptor; diff --git a/app/javascript/mastodon/components/scrollable_list.jsx b/app/javascript/mastodon/components/scrollable_list.jsx index 22ec18afa9c926..47b6235c9e9287 100644 --- a/app/javascript/mastodon/components/scrollable_list.jsx +++ b/app/javascript/mastodon/components/scrollable_list.jsx @@ -10,7 +10,7 @@ import { connect } from 'react-redux'; import { supportsPassiveEvents } from 'detect-passive-events'; import { throttle } from 'lodash'; -import ScrollContainer from 'mastodon/containers/scroll_container'; +import { ScrollContainer } from 'mastodon/containers/scroll_container'; import IntersectionObserverArticleContainer from '../containers/intersection_observer_article_container'; import { attachFullscreenListener, detachFullscreenListener, isFullscreen } from '../features/ui/util/fullscreen'; diff --git a/app/javascript/mastodon/containers/mastodon.jsx b/app/javascript/mastodon/containers/mastodon.jsx index 8dcda3b0a94a35..086a7681c403d9 100644 --- a/app/javascript/mastodon/containers/mastodon.jsx +++ b/app/javascript/mastodon/containers/mastodon.jsx @@ -5,7 +5,6 @@ import { Route } from 'react-router-dom'; import { Provider as ReduxProvider } from 'react-redux'; -import { ScrollContext } from 'react-router-scroll-4'; import { fetchCustomEmojis } from 'mastodon/actions/custom_emojis'; import { hydrateStore } from 'mastodon/actions/store'; @@ -20,6 +19,8 @@ import { store } from 'mastodon/store'; import { isProduction } from 'mastodon/utils/environment'; import { BodyScrollLock } from 'mastodon/features/ui/components/body_scroll_lock'; +import { ScrollContext } from './scroll_container/scroll_context'; + const title = isProduction() ? siteTitle : `${siteTitle} (Dev)`; const hydrateAction = hydrateStore(initialState); @@ -45,10 +46,6 @@ export default class Mastodon extends PureComponent { } } - shouldUpdateScroll (prevRouterProps, { location }) { - return !(location.state?.mastodonModalKey && location.state?.mastodonModalKey !== prevRouterProps?.location?.state?.mastodonModalKey); - } - render () { return ( @@ -56,7 +53,7 @@ export default class Mastodon extends PureComponent { - + diff --git a/app/javascript/mastodon/containers/scroll_container.js b/app/javascript/mastodon/containers/scroll_container.js deleted file mode 100644 index d21ff63687dbfd..00000000000000 --- a/app/javascript/mastodon/containers/scroll_container.js +++ /dev/null @@ -1,18 +0,0 @@ -import { ScrollContainer as OriginalScrollContainer } from 'react-router-scroll-4'; - -// ScrollContainer is used to automatically scroll to the top when pushing a -// new history state and remembering the scroll position when going back. -// There are a few things we need to do differently, though. -const defaultShouldUpdateScroll = (prevRouterProps, { location }) => { - // If the change is caused by opening a modal, do not scroll to top - return !(location.state?.mastodonModalKey && location.state?.mastodonModalKey !== prevRouterProps?.location?.state?.mastodonModalKey); -}; - -export default -class ScrollContainer extends OriginalScrollContainer { - - static defaultProps = { - shouldUpdateScroll: defaultShouldUpdateScroll, - }; - -} diff --git a/app/javascript/mastodon/containers/scroll_container/default_should_update_scroll.tsx b/app/javascript/mastodon/containers/scroll_container/default_should_update_scroll.tsx new file mode 100644 index 00000000000000..b8726a1a75170b --- /dev/null +++ b/app/javascript/mastodon/containers/scroll_container/default_should_update_scroll.tsx @@ -0,0 +1,25 @@ +import type { MastodonLocation } from 'mastodon/components/router'; + +export type ShouldUpdateScrollFn = ( + prevLocationContext: MastodonLocation | null, + locationContext: MastodonLocation, +) => boolean; + +/** + * ScrollBehavior will automatically scroll to the top on navigations + * or restore saved scroll positions, but on some location changes we + * need to prevent this. + */ + +export const defaultShouldUpdateScroll: ShouldUpdateScrollFn = ( + prevLocation, + location, +) => { + // If the change is caused by opening a modal, do not scroll to top + const shouldUpdateScroll = !( + location.state?.mastodonModalKey && + location.state.mastodonModalKey !== prevLocation?.state?.mastodonModalKey + ); + + return shouldUpdateScroll; +}; diff --git a/app/javascript/mastodon/containers/scroll_container/index.tsx b/app/javascript/mastodon/containers/scroll_container/index.tsx new file mode 100644 index 00000000000000..e7d27267157aac --- /dev/null +++ b/app/javascript/mastodon/containers/scroll_container/index.tsx @@ -0,0 +1,62 @@ +import React, { useContext, useEffect, useRef } from 'react'; + +import { defaultShouldUpdateScroll } from './default_should_update_scroll'; +import type { ShouldUpdateScrollFn } from './default_should_update_scroll'; +import { ScrollBehaviorContext } from './scroll_context'; + +interface ScrollContainerProps { + /** + * This key must be static for the element & not change + * while the component is mounted. + */ + scrollKey: string; + shouldUpdateScroll?: ShouldUpdateScrollFn; + children: React.ReactElement; +} + +/** + * `ScrollContainer` is used to manage the scroll position of elements on the page + * that can be scrolled independently of the page body. + * This component is a port of the unmaintained https://github.com/ytase/react-router-scroll/ + */ + +export const ScrollContainer: React.FC = ({ + children, + scrollKey, + shouldUpdateScroll = defaultShouldUpdateScroll, +}) => { + const scrollBehaviorContext = useContext(ScrollBehaviorContext); + + const containerRef = useRef(); + + /** + * Register/unregister scrollable element with ScrollBehavior + */ + useEffect(() => { + if (!scrollBehaviorContext || !containerRef.current) { + return; + } + + scrollBehaviorContext.registerElement( + scrollKey, + containerRef.current, + (prevLocation, location) => { + // Hack to allow accessing scrollBehavior._stateStorage + return shouldUpdateScroll.call( + scrollBehaviorContext.scrollBehavior, + prevLocation, + location, + ); + }, + ); + + return () => { + scrollBehaviorContext.unregisterElement(scrollKey); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + return React.Children.only( + React.cloneElement(children, { ref: containerRef }), + ); +}; diff --git a/app/javascript/mastodon/containers/scroll_container/scroll_context.tsx b/app/javascript/mastodon/containers/scroll_container/scroll_context.tsx new file mode 100644 index 00000000000000..a7eb7808003797 --- /dev/null +++ b/app/javascript/mastodon/containers/scroll_container/scroll_context.tsx @@ -0,0 +1,141 @@ +import React, { useEffect, useMemo, useRef, useState } from 'react'; + +import { useLocation, useHistory } from 'react-router-dom'; + +import type { LocationBase } from 'scroll-behavior'; +import ScrollBehavior from 'scroll-behavior'; + +import type { + LocationState, + MastodonLocation, +} from 'mastodon/components/router'; +import { usePrevious } from 'mastodon/hooks/usePrevious'; + +import { defaultShouldUpdateScroll } from './default_should_update_scroll'; +import type { ShouldUpdateScrollFn } from './default_should_update_scroll'; +import { SessionStorage } from './state_storage'; + +type ScrollBehaviorInstance = InstanceType< + typeof ScrollBehavior +>; + +export interface ScrollBehaviorContextType { + registerElement: ( + key: string, + element: HTMLElement, + shouldUpdateScroll: ( + prevLocationContext: MastodonLocation | null, + locationContext: MastodonLocation, + ) => boolean, + ) => void; + unregisterElement: (key: string) => void; + scrollBehavior?: ScrollBehaviorInstance; +} + +export const ScrollBehaviorContext = + React.createContext(null); + +interface ScrollContextProps { + shouldUpdateScroll?: ShouldUpdateScrollFn; + children: React.ReactElement; +} + +/** + * A top-level wrapper that provides the app with an instance of the + * ScrollBehavior object. scroll-behavior is a library for managing the + * scroll position of a single-page app in the same way the browser would + * normally do for a multi-page app. This means it'll scroll back to top + * when navigating to a new page, and will restore the scroll position + * when navigating e.g. using `history.back`. + * The library keeps a record of scroll positions in session storage. + * + * This component is a port of the unmaintained https://github.com/ytase/react-router-scroll/ + */ + +export const ScrollContext: React.FC = ({ + children, + shouldUpdateScroll = defaultShouldUpdateScroll, +}) => { + const location = useLocation(); + const history = useHistory(); + + /** + * Keep the current location in a mutable ref so that ScrollBehavior's + * `getCurrentLocation` can access it without having to recreate the + * whole ScrollBehavior object + */ + const currentLocationRef = useRef(location); + useEffect(() => { + currentLocationRef.current = location; + }, [location]); + + /** + * Initialise ScrollBehavior object once – using state rather + * than a ref to simplify the types and ensure it's defined immediately. + */ + const [scrollBehavior] = useState( + (): ScrollBehaviorInstance => + new ScrollBehavior({ + addNavigationListener: history.listen.bind(history), + stateStorage: new SessionStorage(), + getCurrentLocation: () => + currentLocationRef.current as unknown as LocationBase, + shouldUpdateScroll: ( + prevLocationContext: MastodonLocation | null, + locationContext: MastodonLocation, + ) => + // Hack to allow accessing scrollBehavior._stateStorage + shouldUpdateScroll.call( + scrollBehavior, + prevLocationContext, + locationContext, + ), + }), + ); + + /** + * Handle scroll update when location changes + */ + const prevLocation = usePrevious(location) ?? null; + useEffect(() => { + scrollBehavior.updateScroll(prevLocation, location); + }, [location, prevLocation, scrollBehavior]); + + /** + * Stop Scrollbehavior on unmount + */ + useEffect(() => { + return () => { + scrollBehavior.stop(); + }; + }, [scrollBehavior]); + + /** + * Provide the app with a way to register separately scrollable + * elements to also be tracked by ScrollBehavior. (By default + * ScrollBehavior only handles scrolling on the main document body.) + */ + const contextValue = useMemo( + () => ({ + registerElement: (key, element, shouldUpdateScroll) => { + scrollBehavior.registerElement( + key, + element, + shouldUpdateScroll, + location, + ); + }, + unregisterElement: (key) => { + scrollBehavior.unregisterElement(key); + }, + scrollBehavior, + }), + [location, scrollBehavior], + ); + + return ( + + {React.Children.only(children)} + + ); +}; diff --git a/app/javascript/mastodon/containers/scroll_container/state_storage.ts b/app/javascript/mastodon/containers/scroll_container/state_storage.ts new file mode 100644 index 00000000000000..fe8a208aae4390 --- /dev/null +++ b/app/javascript/mastodon/containers/scroll_container/state_storage.ts @@ -0,0 +1,46 @@ +import type { LocationBase, ScrollPosition } from 'scroll-behavior'; + +const STATE_KEY_PREFIX = '@@scroll|'; + +interface LocationBaseWithKey extends LocationBase { + key?: string; +} + +/** + * This module is part of our port of https://github.com/ytase/react-router-scroll/ + * and handles storing scroll positions in SessionStorage. + * Stored positions (`[x, y]`) are keyed by the location key and an optional + * `scrollKey` that's used for to track separately scrollable elements other + * than the document body. + */ + +export class SessionStorage { + read( + location: LocationBaseWithKey, + key: string | null, + ): ScrollPosition | null { + const stateKey = this.getStateKey(location, key); + + try { + const value = sessionStorage.getItem(stateKey); + return value ? (JSON.parse(value) as ScrollPosition) : null; + } catch { + return null; + } + } + + save(location: LocationBaseWithKey, key: string | null, value: unknown) { + const stateKey = this.getStateKey(location, key); + const storedValue = JSON.stringify(value); + + try { + sessionStorage.setItem(stateKey, storedValue); + } catch {} + } + + getStateKey(location: LocationBaseWithKey, key: string | null) { + const locationKey = location.key; + const stateKeyBase = `${STATE_KEY_PREFIX}${locationKey}`; + return key == null ? stateKeyBase : `${stateKeyBase}|${key}`; + } +} diff --git a/app/javascript/mastodon/features/directory/index.tsx b/app/javascript/mastodon/features/directory/index.tsx index a29febcd1ab25b..0fe140b4eb49d4 100644 --- a/app/javascript/mastodon/features/directory/index.tsx +++ b/app/javascript/mastodon/features/directory/index.tsx @@ -21,7 +21,7 @@ import { ColumnHeader } from 'mastodon/components/column_header'; import { LoadMore } from 'mastodon/components/load_more'; import { LoadingIndicator } from 'mastodon/components/loading_indicator'; import { RadioButton } from 'mastodon/components/radio_button'; -import ScrollContainer from 'mastodon/containers/scroll_container'; +import { ScrollContainer } from 'mastodon/containers/scroll_container'; import { useSearchParam } from 'mastodon/hooks/useSearchParam'; import { useAppDispatch, useAppSelector } from 'mastodon/store'; @@ -206,7 +206,6 @@ export const Directory: React.FC<{ /> {multiColumn && !pinned ? ( - // @ts-expect-error ScrollContainer is not properly typed yet {scrollableArea} diff --git a/app/javascript/mastodon/features/status/index.jsx b/app/javascript/mastodon/features/status/index.jsx index 404faf609e4ef1..2ceff2577fd7b6 100644 --- a/app/javascript/mastodon/features/status/index.jsx +++ b/app/javascript/mastodon/features/status/index.jsx @@ -16,7 +16,7 @@ import VisibilityOffIcon from '@/material-icons/400-24px/visibility_off.svg?reac import { Hotkeys } from 'mastodon/components/hotkeys'; import { Icon } from 'mastodon/components/icon'; import { LoadingIndicator } from 'mastodon/components/loading_indicator'; -import ScrollContainer from 'mastodon/containers/scroll_container'; +import { ScrollContainer } from 'mastodon/containers/scroll_container'; import BundleColumnError from 'mastodon/features/ui/components/bundle_column_error'; import { identityContextPropShape, withIdentity } from 'mastodon/identity_context'; import { WithRouterPropTypes } from 'mastodon/utils/react_router'; @@ -526,9 +526,9 @@ class Status extends ImmutablePureComponent { this.setState({ fullscreen: isFullscreen() }); }; - shouldUpdateScroll = (prevRouterProps, { location }) => { + shouldUpdateScroll = (prevLocation, location) => { // Do not change scroll when opening a modal - if (location.state?.mastodonModalKey !== prevRouterProps?.location?.state?.mastodonModalKey) { + if (location.state?.mastodonModalKey !== prevLocation?.state?.mastodonModalKey) { return false; } diff --git a/package.json b/package.json index 2d0fa230cd65f5..0fd14de656543a 100644 --- a/package.json +++ b/package.json @@ -99,7 +99,6 @@ "react-redux-loading-bar": "^5.0.8", "react-router": "^5.3.4", "react-router-dom": "^5.3.4", - "react-router-scroll-4": "^1.0.0-beta.1", "react-select": "^5.7.3", "react-sparklines": "^1.7.0", "react-swipeable-views": "^0.14.0", @@ -111,6 +110,7 @@ "rollup-plugin-gzip": "^4.1.1", "rollup-plugin-visualizer": "^6.0.3", "sass": "^1.62.1", + "scroll-behavior": "^0.11.0", "stacktrace-js": "^2.0.2", "stringz": "^2.1.0", "substring-trie": "^1.0.2", diff --git a/yarn.lock b/yarn.lock index 1ca3bec11eddfe..beca808c934c9f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2836,7 +2836,6 @@ __metadata: react-redux-loading-bar: "npm:^5.0.8" react-router: "npm:^5.3.4" react-router-dom: "npm:^5.3.4" - react-router-scroll-4: "npm:^1.0.0-beta.1" react-select: "npm:^5.7.3" react-sparklines: "npm:^1.7.0" react-swipeable-views: "npm:^0.14.0" @@ -2849,6 +2848,7 @@ __metadata: rollup-plugin-gzip: "npm:^4.1.1" rollup-plugin-visualizer: "npm:^6.0.3" sass: "npm:^1.62.1" + scroll-behavior: "npm:^0.11.0" stacktrace-js: "npm:^2.0.2" storybook: "npm:^9.1.1" stringz: "npm:^2.1.0" @@ -6478,16 +6478,7 @@ __metadata: languageName: node linkType: hard -"dom-helpers@npm:^3.4.0": - version: 3.4.0 - resolution: "dom-helpers@npm:3.4.0" - dependencies: - "@babel/runtime": "npm:^7.1.2" - checksum: 10c0/1d2d3e4eadac2c4f4c8c7470a737ab32b7ec28237c4d094ea967ec3184168fd12452196fcc424a5d7860b6176117301aeaecba39467bf1a6e8492a8e5c9639d1 - languageName: node - linkType: hard - -"dom-helpers@npm:^5.0.1, dom-helpers@npm:^5.2.0": +"dom-helpers@npm:^5.0.1, dom-helpers@npm:^5.1.4, dom-helpers@npm:^5.2.0": version: 5.2.1 resolution: "dom-helpers@npm:5.2.1" dependencies: @@ -10036,6 +10027,13 @@ __metadata: languageName: node linkType: hard +"page-lifecycle@npm:^0.1.2": + version: 0.1.2 + resolution: "page-lifecycle@npm:0.1.2" + checksum: 10c0/509dbbc2ad2000dffcf591f66ab13d80fb1dba9337d85c76269173f7a5c3959b5a876e3bfb1e4494f6b932c1dc02a0b5824ebd452ab1a7204d4abdf498cb27c5 + languageName: node + linkType: hard + "parent-module@npm:^1.0.0": version: 1.0.1 resolution: "parent-module@npm:1.0.1" @@ -11277,21 +11275,6 @@ __metadata: languageName: node linkType: hard -"react-router-scroll-4@npm:^1.0.0-beta.1": - version: 1.0.0-beta.2 - resolution: "react-router-scroll-4@npm:1.0.0-beta.2" - dependencies: - scroll-behavior: "npm:^0.9.1" - warning: "npm:^3.0.0" - peerDependencies: - prop-types: ^15.6.0 - react: ^15.0.0 || ^16.0.0 - react-dom: ^15.0.0 || ^16.0.0 - react-router-dom: ^4.0 - checksum: 10c0/ad195b7359fd3146530cf299ec437f0a619c577b2cacfb2c76a156d3cd9d5d3e97af56e17c300c37ca8c485041e93124fe63f0c86db6aea468caf838281e62cb - languageName: node - linkType: hard - "react-router@npm:5.3.4, react-router@npm:^5.3.4": version: 5.3.4 resolution: "react-router@npm:5.3.4" @@ -12051,13 +12034,14 @@ __metadata: languageName: node linkType: hard -"scroll-behavior@npm:^0.9.1": - version: 0.9.12 - resolution: "scroll-behavior@npm:0.9.12" +"scroll-behavior@npm:^0.11.0": + version: 0.11.0 + resolution: "scroll-behavior@npm:0.11.0" dependencies: - dom-helpers: "npm:^3.4.0" + dom-helpers: "npm:^5.1.4" invariant: "npm:^2.2.4" - checksum: 10c0/4f438c48b93a1dcc2ab51a18670fac6f5ce41885291d8aa13251b4a187be9d0c6dd518ee974eb52ac9bbe227b9811c2615ecca73192a1a190b78dfdadb9c2cf2 + page-lifecycle: "npm:^0.1.2" + checksum: 10c0/c54010c9fdd9fc360fd7887ecf64f16972f9557ac679723709612cd54fc4778c7433ab46a9637933179ef31471f78e2591fb35351dc0e15537fecf1c8c89d32c languageName: node linkType: hard @@ -14013,15 +13997,6 @@ __metadata: languageName: node linkType: hard -"warning@npm:^3.0.0": - version: 3.0.0 - resolution: "warning@npm:3.0.0" - dependencies: - loose-envify: "npm:^1.0.0" - checksum: 10c0/6a2a56ab3139d3927193d926a027e74e1449fa47cc692feea95f8a81a4bb5b7f10c312def94cce03f3b58cb26ba3247858e75d17d596451d2c483a62e8204705 - languageName: node - linkType: hard - "warning@npm:^4.0.1, warning@npm:^4.0.3": version: 4.0.3 resolution: "warning@npm:4.0.3" From 11bd51564898854c652451c9a28d8f73afc6a293 Mon Sep 17 00:00:00 2001 From: diondiondion Date: Thu, 25 Sep 2025 18:14:49 +0200 Subject: [PATCH 015/853] Allow accessing ref of ScrollContainer's child (#36265) --- .../mastodon/components/scrollable_list.jsx | 2 +- .../containers/scroll_container/index.tsx | 16 +++++++++++++++- .../mastodon/features/status/index.jsx | 2 +- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/app/javascript/mastodon/components/scrollable_list.jsx b/app/javascript/mastodon/components/scrollable_list.jsx index 47b6235c9e9287..38c3cd991bc736 100644 --- a/app/javascript/mastodon/components/scrollable_list.jsx +++ b/app/javascript/mastodon/components/scrollable_list.jsx @@ -399,7 +399,7 @@ class ScrollableList extends PureComponent { if (trackScroll) { return ( - + {scrollableArea} ); diff --git a/app/javascript/mastodon/containers/scroll_container/index.tsx b/app/javascript/mastodon/containers/scroll_container/index.tsx index e7d27267157aac..0d0ab364dc0b9c 100644 --- a/app/javascript/mastodon/containers/scroll_container/index.tsx +++ b/app/javascript/mastodon/containers/scroll_container/index.tsx @@ -1,4 +1,9 @@ -import React, { useContext, useEffect, useRef } from 'react'; +import React, { + useContext, + useEffect, + useImperativeHandle, + useRef, +} from 'react'; import { defaultShouldUpdateScroll } from './default_should_update_scroll'; import type { ShouldUpdateScrollFn } from './default_should_update_scroll'; @@ -11,6 +16,7 @@ interface ScrollContainerProps { */ scrollKey: string; shouldUpdateScroll?: ShouldUpdateScrollFn; + childRef?: React.ForwardedRef; children: React.ReactElement; } @@ -23,12 +29,20 @@ interface ScrollContainerProps { export const ScrollContainer: React.FC = ({ children, scrollKey, + childRef, shouldUpdateScroll = defaultShouldUpdateScroll, }) => { const scrollBehaviorContext = useContext(ScrollBehaviorContext); const containerRef = useRef(); + /** + * If a childRef is passed, sync it with the containerRef. This + * is necessary because in this component's return statement, + * we're overwriting the immediate child component's ref prop. + */ + useImperativeHandle(childRef, () => containerRef.current, []); + /** * Register/unregister scrollable element with ScrollBehavior */ diff --git a/app/javascript/mastodon/features/status/index.jsx b/app/javascript/mastodon/features/status/index.jsx index 2ceff2577fd7b6..7c38af3277dffc 100644 --- a/app/javascript/mastodon/features/status/index.jsx +++ b/app/javascript/mastodon/features/status/index.jsx @@ -602,7 +602,7 @@ class Status extends ImmutablePureComponent { )} /> - +
{ancestors} From 3eed83b6ffce30270f0cae0f57d1fc2b5307d065 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 25 Sep 2025 09:52:37 +0200 Subject: [PATCH 016/853] [Glitch] chore(deps): update dependency typescript to ~5.9.0 Port cc54b33720cc24906ebd4b3b909a1983913c5df5 to glitch-soc Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: diondiondion Signed-off-by: Claire --- app/javascript/flavours/glitch/components/blurhash.tsx | 7 +++++-- app/javascript/flavours/glitch/components/hashtag_bar.tsx | 2 +- .../components/embedded_status_content.tsx | 2 +- .../flavours/glitch/features/onboarding/profile.tsx | 4 +--- .../flavours/glitch/features/ui/components/embed_modal.tsx | 1 + app/javascript/flavours/glitch/hooks/useLinks.ts | 2 +- 6 files changed, 10 insertions(+), 8 deletions(-) diff --git a/app/javascript/flavours/glitch/components/blurhash.tsx b/app/javascript/flavours/glitch/components/blurhash.tsx index 8e2a8af23e5937..b7331755b7f0dd 100644 --- a/app/javascript/flavours/glitch/components/blurhash.tsx +++ b/app/javascript/flavours/glitch/components/blurhash.tsx @@ -30,9 +30,12 @@ const Blurhash: React.FC = ({ try { const pixels = decode(hash, width, height); const ctx = canvas.getContext('2d'); - const imageData = new ImageData(pixels, width, height); + const imageData = ctx?.createImageData(width, height); + imageData?.data.set(pixels); - ctx?.putImageData(imageData, 0, 0); + if (imageData) { + ctx?.putImageData(imageData, 0, 0); + } } catch (err) { console.error('Blurhash decoding failure', { err, hash }); } diff --git a/app/javascript/flavours/glitch/components/hashtag_bar.tsx b/app/javascript/flavours/glitch/components/hashtag_bar.tsx index 4f88385bef951f..f6b72d43404bd0 100644 --- a/app/javascript/flavours/glitch/components/hashtag_bar.tsx +++ b/app/javascript/flavours/glitch/components/hashtag_bar.tsx @@ -33,7 +33,7 @@ function isNodeLinkHashtag(element: Node): element is HTMLLinkElement { return ( element instanceof HTMLAnchorElement && // it may be a starting with a hashtag - (element.textContent?.[0] === '#' || + (element.textContent.startsWith('#') || // or a # element.previousSibling?.textContent?.[ element.previousSibling.textContent.length - 1 diff --git a/app/javascript/flavours/glitch/features/notifications_v2/components/embedded_status_content.tsx b/app/javascript/flavours/glitch/features/notifications_v2/components/embedded_status_content.tsx index 1a38be536ba6a8..855e160fac657d 100644 --- a/app/javascript/flavours/glitch/features/notifications_v2/components/embedded_status_content.tsx +++ b/app/javascript/flavours/glitch/features/notifications_v2/components/embedded_status_content.tsx @@ -64,7 +64,7 @@ export const EmbeddedStatusContent: React.FC<{ link.setAttribute('title', `@${mention.get('acct')}`); link.setAttribute('href', `/@${mention.get('acct')}`); } else if ( - link.textContent?.[0] === '#' || + link.textContent.startsWith('#') || link.previousSibling?.textContent?.endsWith('#') ) { link.addEventListener( diff --git a/app/javascript/flavours/glitch/features/onboarding/profile.tsx b/app/javascript/flavours/glitch/features/onboarding/profile.tsx index d5d35368f02793..8dab94be562c16 100644 --- a/app/javascript/flavours/glitch/features/onboarding/profile.tsx +++ b/app/javascript/flavours/glitch/features/onboarding/profile.tsx @@ -54,9 +54,7 @@ export const Profile: React.FC<{ me ? state.accounts.get(me) : undefined, ); const [displayName, setDisplayName] = useState(account?.display_name ?? ''); - const [note, setNote] = useState( - account ? (unescapeHTML(account.note) ?? '') : '', - ); + const [note, setNote] = useState(account ? unescapeHTML(account.note) : ''); const [avatar, setAvatar] = useState(); const [header, setHeader] = useState(); const [discoverable, setDiscoverable] = useState( diff --git a/app/javascript/flavours/glitch/features/ui/components/embed_modal.tsx b/app/javascript/flavours/glitch/features/ui/components/embed_modal.tsx index 5607987347570f..7a1aabcb3836bb 100644 --- a/app/javascript/flavours/glitch/features/ui/components/embed_modal.tsx +++ b/app/javascript/flavours/glitch/features/ui/components/embed_modal.tsx @@ -36,6 +36,7 @@ const EmbedModal: React.FC<{ } iframeDocument.open(); + // eslint-disable-next-line @typescript-eslint/no-deprecated iframeDocument.write(data.html); iframeDocument.close(); diff --git a/app/javascript/flavours/glitch/hooks/useLinks.ts b/app/javascript/flavours/glitch/hooks/useLinks.ts index 12142d9f138a51..ab9ac4ef474a33 100644 --- a/app/javascript/flavours/glitch/hooks/useLinks.ts +++ b/app/javascript/flavours/glitch/hooks/useLinks.ts @@ -12,7 +12,7 @@ const isMentionClick = (element: HTMLAnchorElement) => !element.classList.contains('hashtag'); const isHashtagClick = (element: HTMLAnchorElement) => - element.textContent?.[0] === '#' || + element.textContent.startsWith('#') || element.previousSibling?.textContent?.endsWith('#'); export const useLinks = (skipHashtags?: boolean) => { From 40f9873504b79b82dbc61a889b47263a2decc154 Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 25 Sep 2025 11:25:00 +0200 Subject: [PATCH 017/853] [Glitch] Fix not being able to author quotes with CW but no text Port 66686994c1c9a079d3a854f0c2ef5baae4cf16c0 to glitch-soc Co-authored-by: diondiondion Signed-off-by: Claire --- app/javascript/flavours/glitch/actions/compose.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/app/javascript/flavours/glitch/actions/compose.js b/app/javascript/flavours/glitch/actions/compose.js index 387982325c3e75..270ee49bb8ae25 100644 --- a/app/javascript/flavours/glitch/actions/compose.js +++ b/app/javascript/flavours/glitch/actions/compose.js @@ -206,10 +206,11 @@ export function submitCompose(overridePrivacy = null, successCallback = undefine let status = getState().getIn(['compose', 'text'], ''); const media = getState().getIn(['compose', 'media_attachments']); const statusId = getState().getIn(['compose', 'id'], null); + const hasQuote = !!getState().getIn(['compose', 'quoted_status_id']); const spoilers = getState().getIn(['compose', 'spoiler']) || getState().getIn(['local_settings', 'always_show_spoilers_field']); - let spoilerText = spoilers ? getState().getIn(['compose', 'spoiler_text'], '') : ''; + const spoiler_text = spoilers ? getState().getIn(['compose', 'spoiler_text'], '') : ''; - if ((!status || !status.length) && media.size === 0) { + if (!(status?.length || media.size !== 0 || (hasQuote && spoiler_text?.length))) { return; } @@ -245,12 +246,12 @@ export function submitCompose(overridePrivacy = null, successCallback = undefine method: statusId === null ? 'post' : 'put', data: { status, + spoiler_text, content_type: getState().getIn(['compose', 'content_type']), in_reply_to_id: getState().getIn(['compose', 'in_reply_to'], null), media_ids: media.map(item => item.get('id')), media_attributes, - sensitive: getState().getIn(['compose', 'sensitive']) || (spoilerText.length > 0 && media.size !== 0), - spoiler_text: spoilerText, + sensitive: getState().getIn(['compose', 'sensitive']) || (spoiler_text.length > 0 && media.size !== 0), visibility: visibility, poll: getState().getIn(['compose', 'poll'], null), language: getState().getIn(['compose', 'language']), From f61d8cb02a22180d0502581c370e6d0e80c5b4bf Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 26 Sep 2025 04:21:03 -0400 Subject: [PATCH 018/853] Hold usable value lists in admin settings form (#36268) --- app/models/form/admin_settings.rb | 8 +++++--- app/views/admin/settings/about/show.html.haml | 4 ++-- app/views/admin/settings/registrations/show.html.haml | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/app/models/form/admin_settings.rb b/app/models/form/admin_settings.rb index 5f23e683b99c14..a19a6308fac740 100644 --- a/app/models/form/admin_settings.rb +++ b/app/models/form/admin_settings.rb @@ -82,15 +82,17 @@ class Form::AdminSettings }.freeze DESCRIPTION_LIMIT = 200 + DOMAIN_BLOCK_AUDIENCES = %w(disabled users all).freeze + REGISTRATION_MODES = %w(open approved none).freeze attr_accessor(*KEYS) - validates :registrations_mode, inclusion: { in: %w(open approved none) }, if: -> { defined?(@registrations_mode) } + validates :registrations_mode, inclusion: { in: REGISTRATION_MODES }, if: -> { defined?(@registrations_mode) } validates :site_contact_email, :site_contact_username, presence: true, if: -> { defined?(@site_contact_username) || defined?(@site_contact_email) } validates :site_contact_username, existing_username: true, if: -> { defined?(@site_contact_username) } validates :bootstrap_timeline_accounts, existing_username: { multiple: true }, if: -> { defined?(@bootstrap_timeline_accounts) } - validates :show_domain_blocks, inclusion: { in: %w(disabled users all) }, if: -> { defined?(@show_domain_blocks) } - validates :show_domain_blocks_rationale, inclusion: { in: %w(disabled users all) }, if: -> { defined?(@show_domain_blocks_rationale) } + validates :show_domain_blocks, inclusion: { in: DOMAIN_BLOCK_AUDIENCES }, if: -> { defined?(@show_domain_blocks) } + validates :show_domain_blocks_rationale, inclusion: { in: DOMAIN_BLOCK_AUDIENCES }, if: -> { defined?(@show_domain_blocks_rationale) } validates :media_cache_retention_period, :content_cache_retention_period, :backups_retention_period, numericality: { only_integer: true }, allow_blank: true, if: -> { defined?(@media_cache_retention_period) || defined?(@content_cache_retention_period) || defined?(@backups_retention_period) } validates :min_age, numericality: { only_integer: true }, allow_blank: true, if: -> { defined?(@min_age) } validates :site_short_description, length: { maximum: DESCRIPTION_LIMIT }, if: -> { defined?(@site_short_description) } diff --git a/app/views/admin/settings/about/show.html.haml b/app/views/admin/settings/about/show.html.haml index 1eb47a0b54e865..adc8f1ff04ac36 100644 --- a/app/views/admin/settings/about/show.html.haml +++ b/app/views/admin/settings/about/show.html.haml @@ -24,7 +24,7 @@ .fields-row__column.fields-row__column-6.fields-group = f.input :show_domain_blocks, collection_wrapper_tag: 'ul', - collection: %i(disabled users all), + collection: f.object.class::DOMAIN_BLOCK_AUDIENCES, include_blank: false, item_wrapper_tag: 'li', label_method: ->(value) { t("admin.settings.domain_blocks.#{value}") }, @@ -32,7 +32,7 @@ .fields-row__column.fields-row__column-6.fields-group = f.input :show_domain_blocks_rationale, collection_wrapper_tag: 'ul', - collection: %i(disabled users all), + collection: f.object.class::DOMAIN_BLOCK_AUDIENCES, include_blank: false, item_wrapper_tag: 'li', label_method: ->(value) { t("admin.settings.domain_blocks.#{value}") }, diff --git a/app/views/admin/settings/registrations/show.html.haml b/app/views/admin/settings/registrations/show.html.haml index cb5a3eb6baf727..7303eca662ab99 100644 --- a/app/views/admin/settings/registrations/show.html.haml +++ b/app/views/admin/settings/registrations/show.html.haml @@ -18,7 +18,7 @@ .fields-row .fields-row__column.fields-row__column-6.fields-group = f.input :registrations_mode, - collection: %w(open approved none), + collection: f.object.class::REGISTRATION_MODES, include_blank: false, label_method: ->(mode) { I18n.t("admin.settings.registrations_mode.modes.#{mode}") }, warning_hint: I18n.t('admin.settings.registrations_mode.warning_hint'), From c2d426a565c72d616284a61a0f6f2eca68336fae Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 26 Sep 2025 10:21:06 +0200 Subject: [PATCH 019/853] chore(deps): update dependency rubocop to v1.81.0 (#36269) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index b4d58cbb69f2a9..db436c01bea4e2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -345,7 +345,7 @@ GEM azure-blob (~> 0.5.2) hashie (~> 5.0) jmespath (1.6.2) - json (2.13.2) + json (2.15.0) json-canonicalization (1.0.0) json-jwt (1.16.7) activesupport (>= 4.2) @@ -626,7 +626,7 @@ GEM net-smtp premailer (~> 1.7, >= 1.7.9) prettyprint (0.2.0) - prism (1.4.0) + prism (1.5.1) prometheus_exporter (2.3.0) webrick propshaft (1.3.1) @@ -722,7 +722,7 @@ GEM redis (4.8.1) redis-client (0.26.0) connection_pool - regexp_parser (2.11.2) + regexp_parser (2.11.3) reline (0.6.2) io-console (~> 0.5) request_store (1.7.0) @@ -766,7 +766,7 @@ GEM rspec-mocks (~> 3.0) sidekiq (>= 5, < 9) rspec-support (3.13.4) - rubocop (1.80.2) + rubocop (1.81.0) json (~> 2.3) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.1.0) @@ -774,10 +774,10 @@ GEM parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 2.9.3, < 3.0) - rubocop-ast (>= 1.46.0, < 2.0) + rubocop-ast (>= 1.47.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 4.0) - rubocop-ast (1.46.0) + rubocop-ast (1.47.1) parser (>= 3.3.7.2) prism (~> 1.4) rubocop-capybara (2.22.1) @@ -901,9 +901,9 @@ GEM unf (0.1.4) unf_ext unf_ext (0.0.9.1) - unicode-display_width (3.1.5) - unicode-emoji (~> 4.0, >= 4.0.4) - unicode-emoji (4.0.4) + unicode-display_width (3.2.0) + unicode-emoji (~> 4.1) + unicode-emoji (4.1.0) uri (1.0.3) useragent (0.16.11) validate_url (1.0.15) From 7431c505668d8face7415cc0d09be76e770ec821 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 26 Sep 2025 10:42:28 +0200 Subject: [PATCH 020/853] New Crowdin Translations (automated) (#36270) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/be.json | 9 +++++++++ app/javascript/mastodon/locales/cs.json | 7 +++++++ app/javascript/mastodon/locales/de.json | 10 +++++----- app/javascript/mastodon/locales/et.json | 7 +++++++ app/javascript/mastodon/locales/fo.json | 7 +++++++ app/javascript/mastodon/locales/ga.json | 7 +++++++ app/javascript/mastodon/locales/nl.json | 7 +++++++ 7 files changed, 49 insertions(+), 5 deletions(-) diff --git a/app/javascript/mastodon/locales/be.json b/app/javascript/mastodon/locales/be.json index c61938faf5331a..6086fbf77f04ea 100644 --- a/app/javascript/mastodon/locales/be.json +++ b/app/javascript/mastodon/locales/be.json @@ -864,6 +864,14 @@ "status.cancel_reblog_private": "Прыбраць", "status.cannot_quote": "Вы не маеце дазвол цытаваць гэты допіс", "status.cannot_reblog": "Гэты допіс нельга пашырыць", + "status.contains_quote": "Утрымлівае цытату", + "status.context.loading": "Загружаюцца іншыя адказы", + "status.context.loading_error": "Немагчыма загрузіць новыя адказы", + "status.context.loading_more": "Загружаюцца іншыя адказы", + "status.context.loading_success": "Усе адказы загружаныя", + "status.context.more_replies_found": "Знойдзеныя іншыя адказы", + "status.context.retry": "Паспрабаваць зноў", + "status.context.show": "Паказаць", "status.continued_thread": "Працяг ланцужка", "status.copy": "Скапіраваць спасылку на допіс", "status.delete": "Выдаліць", @@ -901,6 +909,7 @@ "status.quote_error.revoked": "Аўтар выдаліў допіс", "status.quote_followers_only": "Толькі падпісчыкі могуць цытаваць гэты допіс", "status.quote_manual_review": "Аўтар зробіць агляд уручную", + "status.quote_noun": "Цытаваць", "status.quote_policy_change": "Змяніць, хто можа цытаваць", "status.quote_post_author": "Цытаваў допіс @{name}", "status.quote_private": "Прыватныя допісы нельга цытаваць", diff --git a/app/javascript/mastodon/locales/cs.json b/app/javascript/mastodon/locales/cs.json index 3b4138cbc8081f..d972d4705b3645 100644 --- a/app/javascript/mastodon/locales/cs.json +++ b/app/javascript/mastodon/locales/cs.json @@ -865,6 +865,13 @@ "status.cannot_quote": "Nemáte oprávnění citovat tento příspěvek", "status.cannot_reblog": "Tento příspěvek nemůže být boostnutý", "status.contains_quote": "Obsahuje citaci", + "status.context.loading": "Načítání dalších odpovědí", + "status.context.loading_error": "Nelze načíst nové odpovědi", + "status.context.loading_more": "Načítání dalších odpovědí", + "status.context.loading_success": "Všechny odpovědi načteny", + "status.context.more_replies_found": "Nalezeny další odpovědi", + "status.context.retry": "Zkusit znovu", + "status.context.show": "Zobrazit", "status.continued_thread": "Pokračuje ve vlákně", "status.copy": "Zkopírovat odkaz na příspěvek", "status.delete": "Smazat", diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json index 910ed0c19add70..e756b6bab61a96 100644 --- a/app/javascript/mastodon/locales/de.json +++ b/app/javascript/mastodon/locales/de.json @@ -865,12 +865,12 @@ "status.cannot_quote": "Dir ist es nicht gestattet, diesen Beitrag zu zitieren", "status.cannot_reblog": "Dieser Beitrag kann nicht geteilt werden", "status.contains_quote": "Enthält Zitat", - "status.context.loading": "Weitere Antworten werden geladen", - "status.context.loading_error": "Neue Antworten konnten nicht geladen werden", - "status.context.loading_more": "Weitere Antworten werden geladen", - "status.context.loading_success": "Alle Antworten geladen", + "status.context.loading": "Weitere Antworten laden", + "status.context.loading_error": "Weitere Antworten konnten nicht geladen werden", + "status.context.loading_more": "Weitere Antworten laden", + "status.context.loading_success": "Alle weiteren Antworten geladen", "status.context.more_replies_found": "Weitere Antworten verfügbar", - "status.context.retry": "Wiederholen", + "status.context.retry": "Erneut versuchen", "status.context.show": "Anzeigen", "status.continued_thread": "Fortgeführter Thread", "status.copy": "Link zum Beitrag kopieren", diff --git a/app/javascript/mastodon/locales/et.json b/app/javascript/mastodon/locales/et.json index b57383da234df0..b6e02a0ba6225c 100644 --- a/app/javascript/mastodon/locales/et.json +++ b/app/javascript/mastodon/locales/et.json @@ -865,6 +865,13 @@ "status.cannot_quote": "Sul pole õigust seda postitust tsiteerida", "status.cannot_reblog": "Seda postitust ei saa jagada", "status.contains_quote": "Sisaldab tsitaati", + "status.context.loading": "Laadin veel vastuseid", + "status.context.loading_error": "Uute vastuste laadimine ei õnnestunud", + "status.context.loading_more": "Laadin veel vastuseid", + "status.context.loading_success": "Kõik vastused on laaditud", + "status.context.more_replies_found": "Leidub veel vastuseid", + "status.context.retry": "Proovi uuesti", + "status.context.show": "Näita", "status.continued_thread": "Jätkatud lõim", "status.copy": "Kopeeri postituse link", "status.delete": "Kustuta", diff --git a/app/javascript/mastodon/locales/fo.json b/app/javascript/mastodon/locales/fo.json index 348de34eb19758..938db30d7a87ae 100644 --- a/app/javascript/mastodon/locales/fo.json +++ b/app/javascript/mastodon/locales/fo.json @@ -865,6 +865,13 @@ "status.cannot_quote": "Tú hevur ikki loyvi at sitera hendan postin", "status.cannot_reblog": "Tað ber ikki til at stimbra hendan postin", "status.contains_quote": "Inniheldur sitat", + "status.context.loading": "Tekur fleiri svar niður", + "status.context.loading_error": "Fekk ikki tikið nýggj svar niður", + "status.context.loading_more": "Tekur fleiri svar niður", + "status.context.loading_success": "Øll svar tikin niður", + "status.context.more_replies_found": "Fleiri svar funnin", + "status.context.retry": "Royn aftur", + "status.context.show": "Vís", "status.continued_thread": "Framhaldandi tráður", "status.copy": "Kopiera leinki til postin", "status.delete": "Strika", diff --git a/app/javascript/mastodon/locales/ga.json b/app/javascript/mastodon/locales/ga.json index 2277128032c344..88d03ea43c1ac5 100644 --- a/app/javascript/mastodon/locales/ga.json +++ b/app/javascript/mastodon/locales/ga.json @@ -865,6 +865,13 @@ "status.cannot_quote": "Ní cheadaítear duit an post seo a lua", "status.cannot_reblog": "Ní féidir an phostáil seo a mholadh", "status.contains_quote": "Tá luachan ann", + "status.context.loading": "Ag lódáil tuilleadh freagraí", + "status.context.loading_error": "Níorbh fhéidir freagraí nua a lódáil", + "status.context.loading_more": "Ag lódáil tuilleadh freagraí", + "status.context.loading_success": "Luchtaithe na freagraí uile", + "status.context.more_replies_found": "Tuilleadh freagraí aimsithe", + "status.context.retry": "Déan iarracht arís", + "status.context.show": "Taispeáin", "status.continued_thread": "Snáithe ar lean", "status.copy": "Cóipeáil an nasc chuig an bpostáil", "status.delete": "Scrios", diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json index 894a93b5fbe702..4250040040efbd 100644 --- a/app/javascript/mastodon/locales/nl.json +++ b/app/javascript/mastodon/locales/nl.json @@ -865,6 +865,13 @@ "status.cannot_quote": "Je bent niet gemachtigd om dit bericht te citeren", "status.cannot_reblog": "Dit bericht kan niet geboost worden", "status.contains_quote": "Bevat citaat", + "status.context.loading": "Meer reacties laden", + "status.context.loading_error": "Kon geen nieuwe reacties laden", + "status.context.loading_more": "Meer reacties laden", + "status.context.loading_success": "Alle reacties zijn geladen", + "status.context.more_replies_found": "Meer reacties gevonden", + "status.context.retry": "Opnieuw proberen", + "status.context.show": "Tonen", "status.continued_thread": "Vervolg van gesprek", "status.copy": "Link naar bericht kopiëren", "status.delete": "Verwijderen", From 238d74fe81b960de974c8a7459ec81f832842261 Mon Sep 17 00:00:00 2001 From: Brad Dunbar Date: Fri, 26 Sep 2025 04:53:08 -0400 Subject: [PATCH 021/853] Refactor `getFocusedItemIndex` to avoid conditionals that `closest` already handles (#36267) --- .../mastodon/features/ui/util/focusUtils.ts | 20 +++++-------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/app/javascript/mastodon/features/ui/util/focusUtils.ts b/app/javascript/mastodon/features/ui/util/focusUtils.ts index a19852e0d26f8c..9bcd3f894397be 100644 --- a/app/javascript/mastodon/features/ui/util/focusUtils.ts +++ b/app/javascript/mastodon/features/ui/util/focusUtils.ts @@ -60,23 +60,13 @@ export function focusColumn({ * Get the index of the currently focused item in one of our item lists */ export function getFocusedItemIndex() { - const focusedElement = document.activeElement; - const itemList = focusedElement?.closest('.item-list'); - - if (!focusedElement || !itemList) { - return -1; - } - - let focusedItem: HTMLElement | null = null; - if (focusedElement.parentElement === itemList) { - focusedItem = focusedElement as HTMLElement; - } else { - focusedItem = focusedElement.closest('.item-list > *'); - } - + const focusedItem = document.activeElement?.closest('.item-list > *'); if (!focusedItem) return -1; - const items = Array.from(itemList.children); + const { parentElement } = focusedItem; + if (!parentElement) return -1; + + const items = Array.from(parentElement.children); return items.indexOf(focusedItem); } From 1571514e49ec02a57c050612b3bca856f54933fb Mon Sep 17 00:00:00 2001 From: diondiondion Date: Fri, 26 Sep 2025 11:23:30 +0200 Subject: [PATCH 022/853] Fix page being vertically scrollable in Advanced UI (#36271) --- app/javascript/styles/mastodon/components.scss | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index b390a8a8e54d45..614b268ec7a8a7 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -2972,8 +2972,12 @@ a.account__display-name { justify-content: flex-start; position: relative; - &.unscrollable { - overflow-x: hidden; + .layout-multiple-columns & { + overflow-x: auto; + + &.unscrollable { + overflow-x: hidden; + } } &__panels { From e07b9dfdc12adb9c8b79d89f80049335053c3324 Mon Sep 17 00:00:00 2001 From: Echo Date: Fri, 26 Sep 2025 11:50:59 +0200 Subject: [PATCH 023/853] Adds new HTMLBlock component (#36262) --- app/javascript/config/html-tags.json | 61 +++++++++ .../html_block/html_block.stories.tsx | 40 ++++++ .../mastodon/components/html_block/index.tsx | 50 +++++++ .../mastodon/features/emoji/hooks.ts | 29 +--- .../mastodon/features/emoji/normalize.ts | 23 +++- .../__tests__/__snapshots__/html-test.ts.snap | 3 + .../mastodon/utils/__tests__/html-test.ts | 11 +- app/javascript/mastodon/utils/html.ts | 124 +++++++++++------- 8 files changed, 261 insertions(+), 80 deletions(-) create mode 100644 app/javascript/config/html-tags.json create mode 100644 app/javascript/mastodon/components/html_block/html_block.stories.tsx create mode 100644 app/javascript/mastodon/components/html_block/index.tsx diff --git a/app/javascript/config/html-tags.json b/app/javascript/config/html-tags.json new file mode 100644 index 00000000000000..c788113487c6c2 --- /dev/null +++ b/app/javascript/config/html-tags.json @@ -0,0 +1,61 @@ +{ + "global": { + "class": "className", + "id": true, + "title": true, + "dir": true, + "lang": true + }, + "tags": { + "p": {}, + "br": { + "children": false + }, + "span": { + "attributes": { + "translate": true + } + }, + "a": { + "attributes": { + "href": true, + "rel": true, + "translate": true, + "target": true + } + }, + "del": {}, + "s": {}, + "pre": {}, + "blockquote": {}, + "code": {}, + "b": {}, + "strong": {}, + "u": {}, + "i": {}, + "img": { + "children": false, + "attributes": { + "src": true, + "alt": true, + "title": true + } + }, + "em": {}, + "ul": {}, + "ol": { + "attributes": { + "start": true, + "reversed": true + } + }, + "li": { + "attributes": { + "value": true + } + }, + "ruby": {}, + "rt": {}, + "rp": {} + } +} diff --git a/app/javascript/mastodon/components/html_block/html_block.stories.tsx b/app/javascript/mastodon/components/html_block/html_block.stories.tsx new file mode 100644 index 00000000000000..9c104ba45cb68e --- /dev/null +++ b/app/javascript/mastodon/components/html_block/html_block.stories.tsx @@ -0,0 +1,40 @@ +import type { Meta, StoryObj } from '@storybook/react-vite'; +import { expect } from 'storybook/test'; + +import { HTMLBlock } from './index'; + +const meta = { + title: 'Components/HTMLBlock', + component: HTMLBlock, + args: { + contents: + '

Hello, world!

\n

A link

\n

This should be filtered out:

', + }, + render(args) { + return ( + // Just for visual clarity in Storybook. +
+ +
+ ); + }, +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + async play({ canvas }) { + const link = canvas.queryByRole('link'); + await expect(link).toBeInTheDocument(); + const button = canvas.queryByRole('button'); + await expect(button).not.toBeInTheDocument(); + }, +}; diff --git a/app/javascript/mastodon/components/html_block/index.tsx b/app/javascript/mastodon/components/html_block/index.tsx new file mode 100644 index 00000000000000..51baea614d74b1 --- /dev/null +++ b/app/javascript/mastodon/components/html_block/index.tsx @@ -0,0 +1,50 @@ +import type { FC, ReactNode } from 'react'; +import { useMemo } from 'react'; + +import { cleanExtraEmojis } from '@/mastodon/features/emoji/normalize'; +import type { CustomEmojiMapArg } from '@/mastodon/features/emoji/types'; +import { createLimitedCache } from '@/mastodon/utils/cache'; + +import { htmlStringToComponents } from '../../utils/html'; + +// Use a module-level cache to avoid re-rendering the same HTML multiple times. +const cache = createLimitedCache({ maxSize: 1000 }); + +interface HTMLBlockProps { + contents: string; + extraEmojis?: CustomEmojiMapArg; +} + +export const HTMLBlock: FC = ({ + contents: raw, + extraEmojis, +}) => { + const customEmojis = useMemo( + () => cleanExtraEmojis(extraEmojis), + [extraEmojis], + ); + const contents = useMemo(() => { + const key = JSON.stringify({ raw, customEmojis }); + if (cache.has(key)) { + return cache.get(key); + } + + const rendered = htmlStringToComponents(raw, { + onText, + extraArgs: { customEmojis }, + }); + + cache.set(key, rendered); + return rendered; + }, [raw, customEmojis]); + + return contents; +}; + +function onText( + text: string, + // eslint-disable-next-line @typescript-eslint/no-unused-vars -- Doesn't do anything, just showing how typing would work. + { customEmojis }: { customEmojis: CustomEmojiMapArg | null }, +) { + return text; +} diff --git a/app/javascript/mastodon/features/emoji/hooks.ts b/app/javascript/mastodon/features/emoji/hooks.ts index 7e91486780a763..b3b27d274a63a5 100644 --- a/app/javascript/mastodon/features/emoji/hooks.ts +++ b/app/javascript/mastodon/features/emoji/hooks.ts @@ -1,19 +1,13 @@ import { useCallback, useLayoutEffect, useMemo, useState } from 'react'; -import { isList } from 'immutable'; - -import type { ApiCustomEmojiJSON } from '@/mastodon/api_types/custom_emoji'; import { useAppSelector } from '@/mastodon/store'; import { isModernEmojiEnabled } from '@/mastodon/utils/environment'; import { toSupportedLocale } from './locale'; import { determineEmojiMode } from './mode'; +import { cleanExtraEmojis } from './normalize'; import { emojifyElement, emojifyText } from './render'; -import type { - CustomEmojiMapArg, - EmojiAppState, - ExtraCustomEmojiMap, -} from './types'; +import type { CustomEmojiMapArg, EmojiAppState } from './types'; import { stringHasAnyEmoji } from './utils'; interface UseEmojifyOptions { @@ -30,20 +24,7 @@ export function useEmojify({ const [emojifiedText, setEmojifiedText] = useState(null); const appState = useEmojiAppState(); - const extra: ExtraCustomEmojiMap = useMemo(() => { - if (!extraEmojis) { - return {}; - } - if (isList(extraEmojis)) { - return ( - extraEmojis.toJS() as ApiCustomEmojiJSON[] - ).reduce( - (acc, emoji) => ({ ...acc, [emoji.shortcode]: emoji }), - {}, - ); - } - return extraEmojis; - }, [extraEmojis]); + const extra = useMemo(() => cleanExtraEmojis(extraEmojis), [extraEmojis]); const emojify = useCallback( async (input: string) => { @@ -51,11 +32,11 @@ export function useEmojify({ if (deep) { const wrapper = document.createElement('div'); wrapper.innerHTML = input; - if (await emojifyElement(wrapper, appState, extra)) { + if (await emojifyElement(wrapper, appState, extra ?? {})) { result = wrapper.innerHTML; } } else { - result = await emojifyText(text, appState, extra); + result = await emojifyText(text, appState, extra ?? {}); } if (result) { setEmojifiedText(result); diff --git a/app/javascript/mastodon/features/emoji/normalize.ts b/app/javascript/mastodon/features/emoji/normalize.ts index 6a64c3b8bfabc2..959732f9856d19 100644 --- a/app/javascript/mastodon/features/emoji/normalize.ts +++ b/app/javascript/mastodon/features/emoji/normalize.ts @@ -1,3 +1,5 @@ +import { isList } from 'immutable'; + import { VARIATION_SELECTOR_CODE, KEYCAP_CODE, @@ -7,7 +9,11 @@ import { EMOJIS_WITH_DARK_BORDER, EMOJIS_WITH_LIGHT_BORDER, } from './constants'; -import type { TwemojiBorderInfo } from './types'; +import type { + CustomEmojiMapArg, + ExtraCustomEmojiMap, + TwemojiBorderInfo, +} from './types'; // Misc codes that have special handling const SKIER_CODE = 0x26f7; @@ -150,6 +156,21 @@ export function twemojiToUnicodeInfo( return hexNumbersToString(mappedCodes); } +export function cleanExtraEmojis(extraEmojis?: CustomEmojiMapArg) { + if (!extraEmojis) { + return null; + } + if (!isList(extraEmojis)) { + return extraEmojis; + } + return extraEmojis + .toJSON() + .reduce( + (acc, emoji) => ({ ...acc, [emoji.shortcode]: emoji }), + {}, + ); +} + function hexStringToNumbers(hexString: string): number[] { return hexString .split('-') diff --git a/app/javascript/mastodon/utils/__tests__/__snapshots__/html-test.ts.snap b/app/javascript/mastodon/utils/__tests__/__snapshots__/html-test.ts.snap index a579efa406b1ce..ea4561bc610c33 100644 --- a/app/javascript/mastodon/utils/__tests__/__snapshots__/html-test.ts.snap +++ b/app/javascript/mastodon/utils/__tests__/__snapshots__/html-test.ts.snap @@ -26,9 +26,11 @@ exports[`html > htmlStringToComponents > handles nested elements 1`] = ` exports[`html > htmlStringToComponents > ignores empty text nodes 1`] = ` [

+ lorem ipsum +

, ] `; @@ -37,6 +39,7 @@ exports[`html > htmlStringToComponents > respects allowedTags option 1`] = ` [

lorem + dolor diff --git a/app/javascript/mastodon/utils/__tests__/html-test.ts b/app/javascript/mastodon/utils/__tests__/html-test.ts index 6c08cc7cbfc07b..6aacc396dc8873 100644 --- a/app/javascript/mastodon/utils/__tests__/html-test.ts +++ b/app/javascript/mastodon/utils/__tests__/html-test.ts @@ -48,7 +48,7 @@ describe('html', () => { const input = '

lorem ipsum

'; const onText = vi.fn((text: string) => text); html.htmlStringToComponents(input, { onText }); - expect(onText).toHaveBeenCalledExactlyOnceWith('lorem ipsum'); + expect(onText).toHaveBeenCalledExactlyOnceWith('lorem ipsum', {}); }); it('calls onElement callback', () => { @@ -61,6 +61,7 @@ describe('html', () => { expect(onElement).toHaveBeenCalledExactlyOnceWith( expect.objectContaining({ tagName: 'P' }), expect.arrayContaining(['lorem ipsum']), + {}, ); }); @@ -71,6 +72,7 @@ describe('html', () => { expect(onElement).toHaveBeenCalledExactlyOnceWith( expect.objectContaining({ tagName: 'P' }), expect.arrayContaining(['lorem ipsum']), + {}, ); expect(output).toMatchSnapshot(); }); @@ -88,15 +90,16 @@ describe('html', () => { 'href', 'https://example.com', 'a', + {}, ); - expect(onAttribute).toHaveBeenCalledWith('target', '_blank', 'a'); - expect(onAttribute).toHaveBeenCalledWith('rel', 'nofollow', 'a'); + expect(onAttribute).toHaveBeenCalledWith('target', '_blank', 'a', {}); + expect(onAttribute).toHaveBeenCalledWith('rel', 'nofollow', 'a', {}); }); it('respects allowedTags option', () => { const input = '

lorem ipsum dolor

'; const output = html.htmlStringToComponents(input, { - allowedTags: new Set(['p', 'em']), + allowedTags: { p: {}, em: {} }, }); expect(output).toMatchSnapshot(); }); diff --git a/app/javascript/mastodon/utils/html.ts b/app/javascript/mastodon/utils/html.ts index 16863223007abf..971aefa6d16b4b 100644 --- a/app/javascript/mastodon/utils/html.ts +++ b/app/javascript/mastodon/utils/html.ts @@ -1,5 +1,7 @@ import React from 'react'; +import htmlConfig from '../../config/html-tags.json'; + // NB: This function can still return unsafe HTML export const unescapeHTML = (html: string) => { const wrapper = document.createElement('div'); @@ -10,64 +12,49 @@ export const unescapeHTML = (html: string) => { return wrapper.textContent; }; +interface AllowedTag { + /* True means allow, false disallows global attributes, string renames the attribute name for React. */ + attributes?: Record; + /* If false, the tag cannot have children. Undefined or true means allowed. */ + children?: boolean; +} + +type AllowedTagsType = { + [Tag in keyof React.ReactHTML]?: AllowedTag; +}; + +const globalAttributes: Record = htmlConfig.global; +const defaultAllowedTags: AllowedTagsType = htmlConfig.tags; + interface QueueItem { node: Node; parent: React.ReactNode[]; depth: number; } -interface Options { +export interface HTMLToStringOptions> { maxDepth?: number; - onText?: (text: string) => React.ReactNode; + onText?: (text: string, extra: Arg) => React.ReactNode; onElement?: ( element: HTMLElement, children: React.ReactNode[], + extra: Arg, ) => React.ReactNode; onAttribute?: ( name: string, value: string, tagName: string, + extra: Arg, ) => [string, unknown] | null; - allowedTags?: Set; + allowedTags?: AllowedTagsType; + extraArgs?: Arg; } -const DEFAULT_ALLOWED_TAGS: ReadonlySet = new Set([ - 'a', - 'abbr', - 'b', - 'blockquote', - 'br', - 'cite', - 'code', - 'del', - 'dfn', - 'dl', - 'dt', - 'em', - 'h1', - 'h2', - 'h3', - 'h4', - 'h5', - 'h6', - 'hr', - 'i', - 'li', - 'ol', - 'p', - 'pre', - 'small', - 'span', - 'strong', - 'sub', - 'sup', - 'time', - 'u', - 'ul', -]); - -export function htmlStringToComponents( + +let uniqueIdCounter = 0; + +export function htmlStringToComponents>( htmlString: string, - options: Options = {}, + options: HTMLToStringOptions = {}, ) { const wrapper = document.createElement('template'); wrapper.innerHTML = htmlString; @@ -79,10 +66,11 @@ export function htmlStringToComponents( const { maxDepth = 10, - allowedTags = DEFAULT_ALLOWED_TAGS, + allowedTags = defaultAllowedTags, onAttribute, onElement, onText, + extraArgs = {} as Arg, } = options; while (queue.length > 0) { @@ -109,9 +97,9 @@ export function htmlStringToComponents( // Text can be added directly if it has any non-whitespace content. case Node.TEXT_NODE: { const text = node.textContent; - if (text && text.trim() !== '') { + if (text) { if (onText) { - parent.push(onText(text)); + parent.push(onText(text, extraArgs)); } else { parent.push(text); } @@ -127,7 +115,9 @@ export function htmlStringToComponents( } // If the tag is not allowed, skip it and its children. - if (!allowedTags.has(node.tagName.toLowerCase())) { + const tagName = node.tagName.toLowerCase(); + const tagInfo = allowedTags[tagName as keyof typeof allowedTags]; + if (!tagInfo) { continue; } @@ -137,7 +127,8 @@ export function htmlStringToComponents( // If onElement is provided, use it to create the element. if (onElement) { - const component = onElement(node, children); + const component = onElement(node, children, extraArgs); + // Check for undefined to allow returning null. if (component !== undefined) { element = component; @@ -147,25 +138,56 @@ export function htmlStringToComponents( // If the element wasn't created, use the default conversion. if (element === undefined) { const props: Record = {}; + props.key = `html-${uniqueIdCounter++}`; // Get the current key and then increment it. for (const attr of node.attributes) { + let name = attr.name.toLowerCase(); + + // Custom attribute handler. if (onAttribute) { const result = onAttribute( - attr.name, + name, attr.value, node.tagName.toLowerCase(), + extraArgs, ); if (result) { - const [name, value] = result; - props[name] = value; + const [cbName, value] = result; + props[cbName] = value; } } else { - props[attr.name] = attr.value; + // Check global attributes first, then tag-specific ones. + const globalAttr = globalAttributes[name]; + const tagAttr = tagInfo.attributes?.[name]; + + // Exit if neither global nor tag-specific attribute is allowed. + if (!globalAttr && !tagAttr) { + continue; + } + + // Rename if needed. + if (typeof tagAttr === 'string') { + name = tagAttr; + } else if (typeof globalAttr === 'string') { + name = globalAttr; + } + + let value: string | boolean | number = attr.value; + + // Handle boolean attributes. + if (value === 'true') { + value = true; + } else if (value === 'false') { + value = false; + } + + props[name] = value; } } + element = React.createElement( - node.tagName.toLowerCase(), + tagName, props, - children, + tagInfo.children !== false ? children : undefined, ); } From cb5bbbfb051e175afb538bf9b83a7ca2d2b2b867 Mon Sep 17 00:00:00 2001 From: diondiondion Date: Fri, 26 Sep 2025 12:00:50 +0200 Subject: [PATCH 024/853] Update "Follow" button labels (#36264) --- .../mastodon/components/follow_button.tsx | 70 +++++++++- .../directory/components/account_card.tsx | 123 +----------------- .../components/inline_follow_suggestions.tsx | 2 - .../features/ui/hooks/useBreakpoint.tsx | 3 +- app/javascript/mastodon/locales/en.json | 7 +- 5 files changed, 78 insertions(+), 127 deletions(-) diff --git a/app/javascript/mastodon/components/follow_button.tsx b/app/javascript/mastodon/components/follow_button.tsx index 98ef3ba3f1c851..15a9046848f5ab 100644 --- a/app/javascript/mastodon/components/follow_button.tsx +++ b/app/javascript/mastodon/components/follow_button.tsx @@ -5,24 +5,61 @@ import { useIntl, defineMessages } from 'react-intl'; import classNames from 'classnames'; import { useIdentity } from '@/mastodon/identity_context'; -import { fetchRelationships, followAccount } from 'mastodon/actions/accounts'; +import { + fetchRelationships, + followAccount, + unblockAccount, + unmuteAccount, +} from 'mastodon/actions/accounts'; import { openModal } from 'mastodon/actions/modal'; import { Button } from 'mastodon/components/button'; import { LoadingIndicator } from 'mastodon/components/loading_indicator'; import { me } from 'mastodon/initial_state'; import { useAppDispatch, useAppSelector } from 'mastodon/store'; -const messages = defineMessages({ +import { useBreakpoint } from '../features/ui/hooks/useBreakpoint'; + +const longMessages = defineMessages({ unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' }, + unblock: { id: 'account.unblock_short', defaultMessage: 'Unblock' }, + unmute: { id: 'account.unmute_short', defaultMessage: 'Unmute' }, follow: { id: 'account.follow', defaultMessage: 'Follow' }, followBack: { id: 'account.follow_back', defaultMessage: 'Follow back' }, + followRequest: { + id: 'account.follow_request', + defaultMessage: 'Request to follow', + }, + followRequestCancel: { + id: 'account.follow_request_cancel', + defaultMessage: 'Cancel request', + }, editProfile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' }, }); +const shortMessages = { + ...longMessages, // Align type signature of shortMessages and longMessages + ...defineMessages({ + followBack: { + id: 'account.follow_back_short', + defaultMessage: 'Follow back', + }, + followRequest: { + id: 'account.follow_request_short', + defaultMessage: 'Request', + }, + followRequestCancel: { + id: 'account.follow_request_cancel_short', + defaultMessage: 'Cancel', + }, + editProfile: { id: 'account.edit_profile_short', defaultMessage: 'Edit' }, + }), +}; + export const FollowButton: React.FC<{ accountId?: string; compact?: boolean; -}> = ({ accountId, compact }) => { + labelLength?: 'auto' | 'short' | 'long'; +}> = ({ accountId, compact, labelLength = 'auto' }) => { const intl = useIntl(); const dispatch = useAppDispatch(); const { signedIn } = useIdentity(); @@ -57,29 +94,48 @@ export const FollowButton: React.FC<{ if (accountId === me) { return; + } else if (relationship.muting) { + dispatch(unmuteAccount(accountId)); } else if (account && (relationship.following || relationship.requested)) { dispatch( openModal({ modalType: 'CONFIRM_UNFOLLOW', modalProps: { account } }), ); + } else if (relationship.blocking) { + dispatch(unblockAccount(accountId)); } else { dispatch(followAccount(accountId)); } }, [dispatch, accountId, relationship, account, signedIn]); + const isNarrow = useBreakpoint('narrow'); + const useShortLabel = + labelLength === 'short' || (labelLength === 'auto' && isNarrow); + const messages = useShortLabel ? shortMessages : longMessages; + + const followMessage = account?.locked + ? messages.followRequest + : messages.follow; + let label; if (!signedIn) { - label = intl.formatMessage(messages.follow); + label = intl.formatMessage(followMessage); } else if (accountId === me) { label = intl.formatMessage(messages.editProfile); } else if (!relationship) { label = ; - } else if (relationship.following || relationship.requested) { + } else if (relationship.muting) { + label = intl.formatMessage(messages.unmute); + } else if (relationship.following) { label = intl.formatMessage(messages.unfollow); - } else if (relationship.followed_by) { + } else if (relationship.blocking) { + label = intl.formatMessage(messages.unblock); + } else if (relationship.requested) { + label = intl.formatMessage(messages.followRequestCancel); + } else if (relationship.followed_by && !account?.locked) { label = intl.formatMessage(messages.followBack); } else { - label = intl.formatMessage(messages.follow); + label = intl.formatMessage(followMessage); } if (accountId === me) { diff --git a/app/javascript/mastodon/features/directory/components/account_card.tsx b/app/javascript/mastodon/features/directory/components/account_card.tsx index 9d317efd437479..6dc70532ab0b03 100644 --- a/app/javascript/mastodon/features/directory/components/account_card.tsx +++ b/app/javascript/mastodon/features/directory/components/account_card.tsx @@ -1,134 +1,23 @@ -import { useCallback } from 'react'; +import { FormattedMessage } from 'react-intl'; -import { FormattedMessage, defineMessages, useIntl } from 'react-intl'; - -import classNames from 'classnames'; import { Link } from 'react-router-dom'; -import { - followAccount, - unblockAccount, - unmuteAccount, -} from 'mastodon/actions/accounts'; -import { openModal } from 'mastodon/actions/modal'; import { Avatar } from 'mastodon/components/avatar'; -import { Button } from 'mastodon/components/button'; import { DisplayName } from 'mastodon/components/display_name'; +import { FollowButton } from 'mastodon/components/follow_button'; import { ShortNumber } from 'mastodon/components/short_number'; -import { autoPlayGif, me } from 'mastodon/initial_state'; +import { autoPlayGif } from 'mastodon/initial_state'; import type { Account } from 'mastodon/models/account'; import { makeGetAccount } from 'mastodon/selectors'; -import { useAppDispatch, useAppSelector } from 'mastodon/store'; - -const messages = defineMessages({ - unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' }, - follow: { id: 'account.follow', defaultMessage: 'Follow' }, - cancel_follow_request: { - id: 'account.cancel_follow_request', - defaultMessage: 'Withdraw follow request', - }, - requested: { - id: 'account.requested', - defaultMessage: 'Awaiting approval. Click to cancel follow request', - }, - unblock: { id: 'account.unblock_short', defaultMessage: 'Unblock' }, - unmute: { id: 'account.unmute_short', defaultMessage: 'Unmute' }, - edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' }, -}); +import { useAppSelector } from 'mastodon/store'; const getAccount = makeGetAccount(); export const AccountCard: React.FC<{ accountId: string }> = ({ accountId }) => { - const intl = useIntl(); const account = useAppSelector((s) => getAccount(s, accountId)); - const dispatch = useAppDispatch(); - - const handleFollow = useCallback(() => { - if (!account) return; - - if ( - account.getIn(['relationship', 'following']) || - account.getIn(['relationship', 'requested']) - ) { - dispatch( - openModal({ modalType: 'CONFIRM_UNFOLLOW', modalProps: { account } }), - ); - } else { - dispatch(followAccount(account.get('id'))); - } - }, [account, dispatch]); - - const handleBlock = useCallback(() => { - if (account?.relationship?.blocking) { - dispatch(unblockAccount(account.get('id'))); - } - }, [account, dispatch]); - - const handleMute = useCallback(() => { - if (account?.relationship?.muting) { - dispatch(unmuteAccount(account.get('id'))); - } - }, [account, dispatch]); - - const handleEditProfile = useCallback(() => { - window.open('/settings/profile', '_blank'); - }, []); if (!account) return null; - let actionBtn; - - if (me !== account.get('id')) { - if (!account.get('relationship')) { - // Wait until the relationship is loaded - actionBtn = ''; - } else if (account.getIn(['relationship', 'requested'])) { - actionBtn = ( -
-
{actionBtn}
+
+ +
); diff --git a/app/javascript/mastodon/features/home_timeline/components/inline_follow_suggestions.tsx b/app/javascript/mastodon/features/home_timeline/components/inline_follow_suggestions.tsx index 3df6d67ecf6d34..05799ccb824c59 100644 --- a/app/javascript/mastodon/features/home_timeline/components/inline_follow_suggestions.tsx +++ b/app/javascript/mastodon/features/home_timeline/components/inline_follow_suggestions.tsx @@ -25,8 +25,6 @@ import { domain } from 'mastodon/initial_state'; import { useAppDispatch, useAppSelector } from 'mastodon/store'; const messages = defineMessages({ - follow: { id: 'account.follow', defaultMessage: 'Follow' }, - unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' }, previous: { id: 'lightbox.previous', defaultMessage: 'Previous' }, next: { id: 'lightbox.next', defaultMessage: 'Next' }, dismiss: { diff --git a/app/javascript/mastodon/features/ui/hooks/useBreakpoint.tsx b/app/javascript/mastodon/features/ui/hooks/useBreakpoint.tsx index af96ab3766345c..cb7b3551f222f0 100644 --- a/app/javascript/mastodon/features/ui/hooks/useBreakpoint.tsx +++ b/app/javascript/mastodon/features/ui/hooks/useBreakpoint.tsx @@ -1,11 +1,12 @@ import { useState, useEffect } from 'react'; const breakpoints = { + narrow: 479, // Device width under which horizontal space is constrained openable: 759, // Device width at which the sidebar becomes an openable hamburger menu full: 1174, // Device width at which all 3 columns can be displayed }; -type Breakpoint = 'openable' | 'full'; +type Breakpoint = keyof typeof breakpoints; export const useBreakpoint = (breakpoint: Breakpoint) => { const [isMatching, setIsMatching] = useState(false); diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index f949c3033963a5..9dc405ab14ada6 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -28,6 +28,7 @@ "account.disable_notifications": "Stop notifying me when @{name} posts", "account.domain_blocking": "Blocking domain", "account.edit_profile": "Edit profile", + "account.edit_profile_short": "Edit", "account.enable_notifications": "Notify me when @{name} posts", "account.endorse": "Feature on profile", "account.familiar_followers_many": "Followed by {name1}, {name2}, and {othersCount, plural, one {one other you know} other {# others you know}}", @@ -40,6 +41,11 @@ "account.featured_tags.last_status_never": "No posts", "account.follow": "Follow", "account.follow_back": "Follow back", + "account.follow_back_short": "Follow back", + "account.follow_request": "Request to follow", + "account.follow_request_cancel": "Cancel request", + "account.follow_request_cancel_short": "Cancel", + "account.follow_request_short": "Request", "account.followers": "Followers", "account.followers.empty": "No one follows this user yet.", "account.followers_counter": "{count, plural, one {{counter} follower} other {{counter} followers}}", @@ -70,7 +76,6 @@ "account.posts_with_replies": "Posts and replies", "account.remove_from_followers": "Remove {name} from followers", "account.report": "Report @{name}", - "account.requested": "Awaiting approval. Click to cancel follow request", "account.requested_follow": "{name} has requested to follow you", "account.requests_to_follow_you": "Requests to follow you", "account.share": "Share @{name}'s profile", From a44a3f6d4047568921469ff9fbd212f553b1e7f4 Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 26 Sep 2025 12:00:53 +0200 Subject: [PATCH 025/853] Expand test coverage of `ActivityPub::TagManager` class (#36260) --- spec/lib/activitypub/tag_manager_spec.rb | 255 ++++++++++++++++++++++- 1 file changed, 245 insertions(+), 10 deletions(-) diff --git a/spec/lib/activitypub/tag_manager_spec.rb b/spec/lib/activitypub/tag_manager_spec.rb index 7a4cf3c1b86c3d..e536883a557645 100644 --- a/spec/lib/activitypub/tag_manager_spec.rb +++ b/spec/lib/activitypub/tag_manager_spec.rb @@ -7,7 +7,7 @@ subject { described_class.instance } - let(:domain) { "#{Rails.configuration.x.use_https ? 'https' : 'http'}://#{Rails.configuration.x.web_domain}" } + let(:host_prefix) { "#{Rails.configuration.x.use_https ? 'https' : 'http'}://#{Rails.configuration.x.web_domain}" } describe '#public_collection?' do it 'returns true for the special public collection and common shorthands' do @@ -22,18 +22,123 @@ end describe '#url_for' do - it 'returns a string starting with web domain' do - account = Fabricate(:account) - expect(subject.url_for(account)).to be_a(String) - .and start_with(domain) + context 'with a local account' do + let(:account) { Fabricate(:account) } + + it 'returns a string starting with web domain and with the expected path' do + expect(subject.url_for(account)) + .to eq("#{host_prefix}/@#{account.username}") + end + end + + context 'with a remote account' do + let(:account) { Fabricate(:account, domain: 'example.com', url: 'https://example.com/profiles/dskjfsdf') } + + it 'returns the expected URL' do + expect(subject.url_for(account)).to eq account.url + end + end + + context 'with a local status' do + let(:status) { Fabricate(:status) } + + it 'returns a string starting with web domain and with the expected path' do + expect(subject.url_for(status)) + .to eq("#{host_prefix}/@#{status.account.username}/#{status.id}") + end + end + + context 'with a remote status' do + let(:account) { Fabricate(:account, domain: 'example.com', url: 'https://example.com/profiles/dskjfsdf') } + let(:status) { Fabricate(:status, account: account, url: 'https://example.com/posts/1234') } + + it 'returns the expected URL' do + expect(subject.url_for(status)).to eq status.url + end end end describe '#uri_for' do - it 'returns a string starting with web domain' do - account = Fabricate(:account) - expect(subject.uri_for(account)).to be_a(String) - .and start_with(domain) + context 'with the instance actor' do + it 'returns a string starting with web domain and with the expected path' do + expect(subject.uri_for(Account.representative)) + .to eq("#{host_prefix}/actor") + end + end + + context 'with a local account' do + let(:account) { Fabricate(:account) } + + it 'returns a string starting with web domain and with the expected path' do + expect(subject.uri_for(account)) + .to eq("#{host_prefix}/users/#{account.username}") + end + end + + context 'with a remote account' do + let(:account) { Fabricate(:account, domain: 'example.com', uri: 'https://example.com/profiles/dskjfsdf') } + + it 'returns the expected URL' do + expect(subject.uri_for(account)).to eq account.uri + end + end + + context 'with a local status' do + let(:status) { Fabricate(:status) } + + it 'returns a string starting with web domain and with the expected path' do + expect(subject.uri_for(status)) + .to eq("#{host_prefix}/users/#{status.account.username}/statuses/#{status.id}") + end + end + + context 'with a remote status' do + let(:account) { Fabricate(:account, domain: 'example.com', uri: 'https://example.com/profiles/dskjfsdf') } + let(:status) { Fabricate(:status, account: account, uri: 'https://example.com/posts/1234') } + + it 'returns the expected URL' do + expect(subject.uri_for(status)).to eq status.uri + end + end + + context 'with a local conversation' do + let(:status) { Fabricate(:status) } + + it 'returns a string starting with web domain and with the expected path' do + expect(subject.uri_for(status.conversation)) + .to eq("#{host_prefix}/contexts/#{status.account.id}-#{status.id}") + end + end + + context 'with a remote conversation' do + let(:account) { Fabricate(:account, domain: 'example.com', uri: 'https://example.com/profiles/dskjfsdf') } + let(:status) { Fabricate(:status, account: account, uri: 'https://example.com/posts/1234') } + + before do + status.conversation.update!(uri: 'https://example.com/conversations/1234') + end + + it 'returns the expected URL' do + expect(subject.uri_for(status.conversation)).to eq status.conversation.uri + end + end + end + + describe '#key_uri_for' do + context 'with the instance actor' do + it 'returns a string starting with web domain and with the expected path' do + expect(subject.key_uri_for(Account.representative)) + .to eq("#{host_prefix}/actor#main-key") + end + end + + context 'with a local account' do + let(:account) { Fabricate(:account) } + + it 'returns a string starting with web domain and with the expected path' do + expect(subject.key_uri_for(account)) + .to eq("#{host_prefix}/users/#{account.username}#main-key") + end end end @@ -49,7 +154,137 @@ it 'returns a string starting with web domain' do status = Fabricate(:status) expect(subject.uri_for(status)).to be_a(String) - .and start_with(domain) + .and start_with(host_prefix) + end + end + end + + describe '#approval_uri_for' do + context 'with a valid local approval' do + let(:quote) { Fabricate(:quote, state: :accepted) } + + it 'returns a string with the web domain and expected path' do + expect(subject.approval_uri_for(quote)) + .to eq("#{host_prefix}/users/#{quote.quoted_account.username}/quote_authorizations/#{quote.id}") + end + end + + context 'with an unapproved local quote' do + let(:quote) { Fabricate(:quote, state: :rejected) } + + it 'returns nil' do + expect(subject.approval_uri_for(quote)) + .to be_nil + end + end + + context 'with a valid remote approval' do + let(:quoted_account) { Fabricate(:account, domain: 'example.com') } + let(:quoted_status) { Fabricate(:status, account: quoted_account) } + let(:quote) { Fabricate(:quote, state: :accepted, quoted_status: quoted_status, approval_uri: 'https://example.com/approvals/1') } + + it 'returns the expected URI' do + expect(subject.approval_uri_for(quote)).to eq quote.approval_uri + end + end + + context 'with an unapproved local quote but check_approval override' do + let(:quote) { Fabricate(:quote, state: :rejected) } + + it 'returns a string with the web domain and expected path' do + expect(subject.approval_uri_for(quote, check_approval: false)) + .to eq("#{host_prefix}/users/#{quote.quoted_account.username}/quote_authorizations/#{quote.id}") + end + end + end + + describe '#replies_uri_for' do + context 'with a local status' do + let(:status) { Fabricate(:status) } + + it 'returns a string starting with web domain and with the expected path' do + expect(subject.replies_uri_for(status)) + .to eq("#{host_prefix}/users/#{status.account.username}/statuses/#{status.id}/replies") + end + end + end + + describe '#likes_uri_for' do + context 'with a local status' do + let(:status) { Fabricate(:status) } + + it 'returns a string starting with web domain and with the expected path' do + expect(subject.likes_uri_for(status)) + .to eq("#{host_prefix}/users/#{status.account.username}/statuses/#{status.id}/likes") + end + end + end + + describe '#shares_uri_for' do + context 'with a local status' do + let(:status) { Fabricate(:status) } + + it 'returns a string starting with web domain and with the expected path' do + expect(subject.shares_uri_for(status)) + .to eq("#{host_prefix}/users/#{status.account.username}/statuses/#{status.id}/shares") + end + end + end + + describe '#following_uri_for' do + context 'with a local account' do + let(:account) { Fabricate(:account) } + + it 'returns a string starting with web domain and with the expected path' do + expect(subject.following_uri_for(account)) + .to eq("#{host_prefix}/users/#{account.username}/following") + end + end + end + + describe '#followers_uri_for' do + context 'with a local account' do + let(:account) { Fabricate(:account) } + + it 'returns a string starting with web domain and with the expected path' do + expect(subject.followers_uri_for(account)) + .to eq("#{host_prefix}/users/#{account.username}/followers") + end + end + end + + describe '#inbox_uri_for' do + context 'with the instance actor' do + it 'returns a string starting with web domain and with the expected path' do + expect(subject.inbox_uri_for(Account.representative)) + .to eq("#{host_prefix}/actor/inbox") + end + end + + context 'with a local account' do + let(:account) { Fabricate(:account) } + + it 'returns a string starting with web domain and with the expected path' do + expect(subject.inbox_uri_for(account)) + .to eq("#{host_prefix}/users/#{account.username}/inbox") + end + end + end + + describe '#outbox_uri_for' do + context 'with the instance actor' do + it 'returns a string starting with web domain and with the expected path' do + expect(subject.outbox_uri_for(Account.representative)) + .to eq("#{host_prefix}/actor/outbox") + end + end + + context 'with a local account' do + let(:account) { Fabricate(:account) } + + it 'returns a string starting with web domain and with the expected path' do + expect(subject.outbox_uri_for(account)) + .to eq("#{host_prefix}/users/#{account.username}/outbox") end end end From 3cd021d4d985d63594129169e80252b4d3c532cd Mon Sep 17 00:00:00 2001 From: diondiondion Date: Thu, 25 Sep 2025 14:26:50 +0200 Subject: [PATCH 026/853] [Glitch] Replace `react-router-scroll-4` with inlined implementation Port d801cf8e59edaea24cf70f1f62aa4e1ff8d1dcbd to glitch-soc Signed-off-by: Claire --- .../flavours/glitch/components/router.tsx | 5 +- .../glitch/components/scrollable_list.jsx | 2 +- .../flavours/glitch/containers/mastodon.jsx | 9 +- .../glitch/containers/scroll_container.js | 18 --- .../default_should_update_scroll.tsx | 25 ++++ .../containers/scroll_container/index.tsx | 62 ++++++++ .../scroll_container/scroll_context.tsx | 141 ++++++++++++++++++ .../scroll_container/state_storage.ts | 46 ++++++ .../glitch/features/directory/index.tsx | 3 +- .../flavours/glitch/features/status/index.jsx | 6 +- 10 files changed, 286 insertions(+), 31 deletions(-) delete mode 100644 app/javascript/flavours/glitch/containers/scroll_container.js create mode 100644 app/javascript/flavours/glitch/containers/scroll_container/default_should_update_scroll.tsx create mode 100644 app/javascript/flavours/glitch/containers/scroll_container/index.tsx create mode 100644 app/javascript/flavours/glitch/containers/scroll_container/scroll_context.tsx create mode 100644 app/javascript/flavours/glitch/containers/scroll_container/state_storage.ts diff --git a/app/javascript/flavours/glitch/components/router.tsx b/app/javascript/flavours/glitch/components/router.tsx index 0175e1b44ffce9..f027d6cd3586ba 100644 --- a/app/javascript/flavours/glitch/components/router.tsx +++ b/app/javascript/flavours/glitch/components/router.tsx @@ -1,6 +1,7 @@ import type { PropsWithChildren } from 'react'; import type React from 'react'; +import type { useLocation } from 'react-router'; import { Router as OriginalRouter, useHistory } from 'react-router'; import type { @@ -18,7 +19,9 @@ interface MastodonLocationState { mastodonModalKey?: string; } -type LocationState = MastodonLocationState | null | undefined; +export type LocationState = MastodonLocationState | null | undefined; + +export type MastodonLocation = ReturnType>; type HistoryPath = Path | LocationDescriptor; diff --git a/app/javascript/flavours/glitch/components/scrollable_list.jsx b/app/javascript/flavours/glitch/components/scrollable_list.jsx index 836cc5ee20a6cf..d1a0ab991cc320 100644 --- a/app/javascript/flavours/glitch/components/scrollable_list.jsx +++ b/app/javascript/flavours/glitch/components/scrollable_list.jsx @@ -10,7 +10,7 @@ import { connect } from 'react-redux'; import { supportsPassiveEvents } from 'detect-passive-events'; import { throttle } from 'lodash'; -import ScrollContainer from 'flavours/glitch/containers/scroll_container'; +import { ScrollContainer } from 'flavours/glitch/containers/scroll_container'; import IntersectionObserverArticleContainer from '../containers/intersection_observer_article_container'; import { attachFullscreenListener, detachFullscreenListener, isFullscreen } from '../features/ui/util/fullscreen'; diff --git a/app/javascript/flavours/glitch/containers/mastodon.jsx b/app/javascript/flavours/glitch/containers/mastodon.jsx index d300be1f396c16..f715ebf9d18c22 100644 --- a/app/javascript/flavours/glitch/containers/mastodon.jsx +++ b/app/javascript/flavours/glitch/containers/mastodon.jsx @@ -5,7 +5,6 @@ import { Route } from 'react-router-dom'; import { Provider as ReduxProvider } from 'react-redux'; -import { ScrollContext } from 'react-router-scroll-4'; import { fetchCustomEmojis } from 'flavours/glitch/actions/custom_emojis'; import { checkDeprecatedLocalSettings } from 'flavours/glitch/actions/local_settings'; @@ -21,6 +20,8 @@ import { store } from 'flavours/glitch/store'; import { isProduction } from 'flavours/glitch/utils/environment'; import { BodyScrollLock } from 'flavours/glitch/features/ui/components/body_scroll_lock'; +import { ScrollContext } from './scroll_container/scroll_context'; + const title = isProduction() ? siteTitle : `${siteTitle} (Dev)`; const hydrateAction = hydrateStore(initialState); @@ -50,10 +51,6 @@ export default class Mastodon extends PureComponent { } } - shouldUpdateScroll (prevRouterProps, { location }) { - return !(location.state?.mastodonModalKey && location.state?.mastodonModalKey !== prevRouterProps?.location?.state?.mastodonModalKey); - } - render () { return ( @@ -61,7 +58,7 @@ export default class Mastodon extends PureComponent { - + diff --git a/app/javascript/flavours/glitch/containers/scroll_container.js b/app/javascript/flavours/glitch/containers/scroll_container.js deleted file mode 100644 index d21ff63687dbfd..00000000000000 --- a/app/javascript/flavours/glitch/containers/scroll_container.js +++ /dev/null @@ -1,18 +0,0 @@ -import { ScrollContainer as OriginalScrollContainer } from 'react-router-scroll-4'; - -// ScrollContainer is used to automatically scroll to the top when pushing a -// new history state and remembering the scroll position when going back. -// There are a few things we need to do differently, though. -const defaultShouldUpdateScroll = (prevRouterProps, { location }) => { - // If the change is caused by opening a modal, do not scroll to top - return !(location.state?.mastodonModalKey && location.state?.mastodonModalKey !== prevRouterProps?.location?.state?.mastodonModalKey); -}; - -export default -class ScrollContainer extends OriginalScrollContainer { - - static defaultProps = { - shouldUpdateScroll: defaultShouldUpdateScroll, - }; - -} diff --git a/app/javascript/flavours/glitch/containers/scroll_container/default_should_update_scroll.tsx b/app/javascript/flavours/glitch/containers/scroll_container/default_should_update_scroll.tsx new file mode 100644 index 00000000000000..5e5035d973bd57 --- /dev/null +++ b/app/javascript/flavours/glitch/containers/scroll_container/default_should_update_scroll.tsx @@ -0,0 +1,25 @@ +import type { MastodonLocation } from 'flavours/glitch/components/router'; + +export type ShouldUpdateScrollFn = ( + prevLocationContext: MastodonLocation | null, + locationContext: MastodonLocation, +) => boolean; + +/** + * ScrollBehavior will automatically scroll to the top on navigations + * or restore saved scroll positions, but on some location changes we + * need to prevent this. + */ + +export const defaultShouldUpdateScroll: ShouldUpdateScrollFn = ( + prevLocation, + location, +) => { + // If the change is caused by opening a modal, do not scroll to top + const shouldUpdateScroll = !( + location.state?.mastodonModalKey && + location.state.mastodonModalKey !== prevLocation?.state?.mastodonModalKey + ); + + return shouldUpdateScroll; +}; diff --git a/app/javascript/flavours/glitch/containers/scroll_container/index.tsx b/app/javascript/flavours/glitch/containers/scroll_container/index.tsx new file mode 100644 index 00000000000000..e7d27267157aac --- /dev/null +++ b/app/javascript/flavours/glitch/containers/scroll_container/index.tsx @@ -0,0 +1,62 @@ +import React, { useContext, useEffect, useRef } from 'react'; + +import { defaultShouldUpdateScroll } from './default_should_update_scroll'; +import type { ShouldUpdateScrollFn } from './default_should_update_scroll'; +import { ScrollBehaviorContext } from './scroll_context'; + +interface ScrollContainerProps { + /** + * This key must be static for the element & not change + * while the component is mounted. + */ + scrollKey: string; + shouldUpdateScroll?: ShouldUpdateScrollFn; + children: React.ReactElement; +} + +/** + * `ScrollContainer` is used to manage the scroll position of elements on the page + * that can be scrolled independently of the page body. + * This component is a port of the unmaintained https://github.com/ytase/react-router-scroll/ + */ + +export const ScrollContainer: React.FC = ({ + children, + scrollKey, + shouldUpdateScroll = defaultShouldUpdateScroll, +}) => { + const scrollBehaviorContext = useContext(ScrollBehaviorContext); + + const containerRef = useRef(); + + /** + * Register/unregister scrollable element with ScrollBehavior + */ + useEffect(() => { + if (!scrollBehaviorContext || !containerRef.current) { + return; + } + + scrollBehaviorContext.registerElement( + scrollKey, + containerRef.current, + (prevLocation, location) => { + // Hack to allow accessing scrollBehavior._stateStorage + return shouldUpdateScroll.call( + scrollBehaviorContext.scrollBehavior, + prevLocation, + location, + ); + }, + ); + + return () => { + scrollBehaviorContext.unregisterElement(scrollKey); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + return React.Children.only( + React.cloneElement(children, { ref: containerRef }), + ); +}; diff --git a/app/javascript/flavours/glitch/containers/scroll_container/scroll_context.tsx b/app/javascript/flavours/glitch/containers/scroll_container/scroll_context.tsx new file mode 100644 index 00000000000000..1f73ffa6f5b5e5 --- /dev/null +++ b/app/javascript/flavours/glitch/containers/scroll_container/scroll_context.tsx @@ -0,0 +1,141 @@ +import React, { useEffect, useMemo, useRef, useState } from 'react'; + +import { useLocation, useHistory } from 'react-router-dom'; + +import type { LocationBase } from 'scroll-behavior'; +import ScrollBehavior from 'scroll-behavior'; + +import type { + LocationState, + MastodonLocation, +} from 'flavours/glitch/components/router'; +import { usePrevious } from 'flavours/glitch/hooks/usePrevious'; + +import { defaultShouldUpdateScroll } from './default_should_update_scroll'; +import type { ShouldUpdateScrollFn } from './default_should_update_scroll'; +import { SessionStorage } from './state_storage'; + +type ScrollBehaviorInstance = InstanceType< + typeof ScrollBehavior +>; + +export interface ScrollBehaviorContextType { + registerElement: ( + key: string, + element: HTMLElement, + shouldUpdateScroll: ( + prevLocationContext: MastodonLocation | null, + locationContext: MastodonLocation, + ) => boolean, + ) => void; + unregisterElement: (key: string) => void; + scrollBehavior?: ScrollBehaviorInstance; +} + +export const ScrollBehaviorContext = + React.createContext(null); + +interface ScrollContextProps { + shouldUpdateScroll?: ShouldUpdateScrollFn; + children: React.ReactElement; +} + +/** + * A top-level wrapper that provides the app with an instance of the + * ScrollBehavior object. scroll-behavior is a library for managing the + * scroll position of a single-page app in the same way the browser would + * normally do for a multi-page app. This means it'll scroll back to top + * when navigating to a new page, and will restore the scroll position + * when navigating e.g. using `history.back`. + * The library keeps a record of scroll positions in session storage. + * + * This component is a port of the unmaintained https://github.com/ytase/react-router-scroll/ + */ + +export const ScrollContext: React.FC = ({ + children, + shouldUpdateScroll = defaultShouldUpdateScroll, +}) => { + const location = useLocation(); + const history = useHistory(); + + /** + * Keep the current location in a mutable ref so that ScrollBehavior's + * `getCurrentLocation` can access it without having to recreate the + * whole ScrollBehavior object + */ + const currentLocationRef = useRef(location); + useEffect(() => { + currentLocationRef.current = location; + }, [location]); + + /** + * Initialise ScrollBehavior object once – using state rather + * than a ref to simplify the types and ensure it's defined immediately. + */ + const [scrollBehavior] = useState( + (): ScrollBehaviorInstance => + new ScrollBehavior({ + addNavigationListener: history.listen.bind(history), + stateStorage: new SessionStorage(), + getCurrentLocation: () => + currentLocationRef.current as unknown as LocationBase, + shouldUpdateScroll: ( + prevLocationContext: MastodonLocation | null, + locationContext: MastodonLocation, + ) => + // Hack to allow accessing scrollBehavior._stateStorage + shouldUpdateScroll.call( + scrollBehavior, + prevLocationContext, + locationContext, + ), + }), + ); + + /** + * Handle scroll update when location changes + */ + const prevLocation = usePrevious(location) ?? null; + useEffect(() => { + scrollBehavior.updateScroll(prevLocation, location); + }, [location, prevLocation, scrollBehavior]); + + /** + * Stop Scrollbehavior on unmount + */ + useEffect(() => { + return () => { + scrollBehavior.stop(); + }; + }, [scrollBehavior]); + + /** + * Provide the app with a way to register separately scrollable + * elements to also be tracked by ScrollBehavior. (By default + * ScrollBehavior only handles scrolling on the main document body.) + */ + const contextValue = useMemo( + () => ({ + registerElement: (key, element, shouldUpdateScroll) => { + scrollBehavior.registerElement( + key, + element, + shouldUpdateScroll, + location, + ); + }, + unregisterElement: (key) => { + scrollBehavior.unregisterElement(key); + }, + scrollBehavior, + }), + [location, scrollBehavior], + ); + + return ( + + {React.Children.only(children)} + + ); +}; diff --git a/app/javascript/flavours/glitch/containers/scroll_container/state_storage.ts b/app/javascript/flavours/glitch/containers/scroll_container/state_storage.ts new file mode 100644 index 00000000000000..fe8a208aae4390 --- /dev/null +++ b/app/javascript/flavours/glitch/containers/scroll_container/state_storage.ts @@ -0,0 +1,46 @@ +import type { LocationBase, ScrollPosition } from 'scroll-behavior'; + +const STATE_KEY_PREFIX = '@@scroll|'; + +interface LocationBaseWithKey extends LocationBase { + key?: string; +} + +/** + * This module is part of our port of https://github.com/ytase/react-router-scroll/ + * and handles storing scroll positions in SessionStorage. + * Stored positions (`[x, y]`) are keyed by the location key and an optional + * `scrollKey` that's used for to track separately scrollable elements other + * than the document body. + */ + +export class SessionStorage { + read( + location: LocationBaseWithKey, + key: string | null, + ): ScrollPosition | null { + const stateKey = this.getStateKey(location, key); + + try { + const value = sessionStorage.getItem(stateKey); + return value ? (JSON.parse(value) as ScrollPosition) : null; + } catch { + return null; + } + } + + save(location: LocationBaseWithKey, key: string | null, value: unknown) { + const stateKey = this.getStateKey(location, key); + const storedValue = JSON.stringify(value); + + try { + sessionStorage.setItem(stateKey, storedValue); + } catch {} + } + + getStateKey(location: LocationBaseWithKey, key: string | null) { + const locationKey = location.key; + const stateKeyBase = `${STATE_KEY_PREFIX}${locationKey}`; + return key == null ? stateKeyBase : `${stateKeyBase}|${key}`; + } +} diff --git a/app/javascript/flavours/glitch/features/directory/index.tsx b/app/javascript/flavours/glitch/features/directory/index.tsx index 689f924b8f76c5..3b402bd3917337 100644 --- a/app/javascript/flavours/glitch/features/directory/index.tsx +++ b/app/javascript/flavours/glitch/features/directory/index.tsx @@ -24,7 +24,7 @@ import { ColumnHeader } from 'flavours/glitch/components/column_header'; import { LoadMore } from 'flavours/glitch/components/load_more'; import { LoadingIndicator } from 'flavours/glitch/components/loading_indicator'; import { RadioButton } from 'flavours/glitch/components/radio_button'; -import ScrollContainer from 'flavours/glitch/containers/scroll_container'; +import { ScrollContainer } from 'flavours/glitch/containers/scroll_container'; import { useSearchParam } from 'flavours/glitch/hooks/useSearchParam'; import { useAppDispatch, useAppSelector } from 'flavours/glitch/store'; @@ -209,7 +209,6 @@ export const Directory: React.FC<{ /> {multiColumn && !pinned ? ( - // @ts-expect-error ScrollContainer is not properly typed yet {scrollableArea} diff --git a/app/javascript/flavours/glitch/features/status/index.jsx b/app/javascript/flavours/glitch/features/status/index.jsx index d196dff11ac75f..a04fce60e436e3 100644 --- a/app/javascript/flavours/glitch/features/status/index.jsx +++ b/app/javascript/flavours/glitch/features/status/index.jsx @@ -17,7 +17,7 @@ import VisibilityOffIcon from '@/material-icons/400-24px/visibility_off.svg?reac import { Hotkeys } from 'flavours/glitch/components/hotkeys'; import { Icon } from 'flavours/glitch/components/icon'; import { LoadingIndicator } from 'flavours/glitch/components/loading_indicator'; -import ScrollContainer from 'flavours/glitch/containers/scroll_container'; +import { ScrollContainer } from 'flavours/glitch/containers/scroll_container'; import BundleColumnError from 'flavours/glitch/features/ui/components/bundle_column_error'; import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context'; import { autoUnfoldCW } from 'flavours/glitch/utils/content_warning'; @@ -551,9 +551,9 @@ class Status extends ImmutablePureComponent { this.setState({ fullscreen: isFullscreen() }); }; - shouldUpdateScroll = (prevRouterProps, { location }) => { + shouldUpdateScroll = (prevLocation, location) => { // Do not change scroll when opening a modal - if (location.state?.mastodonModalKey !== prevRouterProps?.location?.state?.mastodonModalKey) { + if (location.state?.mastodonModalKey !== prevLocation?.state?.mastodonModalKey) { return false; } From 364aced99ec94538b5a00fd96b1b3408e54e70f9 Mon Sep 17 00:00:00 2001 From: diondiondion Date: Thu, 25 Sep 2025 18:14:49 +0200 Subject: [PATCH 027/853] [Glitch] Allow accessing ref of ScrollContainer's child Port 11bd51564898854c652451c9a28d8f73afc6a293 to glitch-soc Signed-off-by: Claire --- .../glitch/components/scrollable_list.jsx | 2 +- .../glitch/containers/scroll_container/index.tsx | 16 +++++++++++++++- .../flavours/glitch/features/status/index.jsx | 2 +- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/app/javascript/flavours/glitch/components/scrollable_list.jsx b/app/javascript/flavours/glitch/components/scrollable_list.jsx index d1a0ab991cc320..a7c1dccb0ad51d 100644 --- a/app/javascript/flavours/glitch/components/scrollable_list.jsx +++ b/app/javascript/flavours/glitch/components/scrollable_list.jsx @@ -399,7 +399,7 @@ class ScrollableList extends PureComponent { if (trackScroll) { return ( - + {scrollableArea} ); diff --git a/app/javascript/flavours/glitch/containers/scroll_container/index.tsx b/app/javascript/flavours/glitch/containers/scroll_container/index.tsx index e7d27267157aac..0d0ab364dc0b9c 100644 --- a/app/javascript/flavours/glitch/containers/scroll_container/index.tsx +++ b/app/javascript/flavours/glitch/containers/scroll_container/index.tsx @@ -1,4 +1,9 @@ -import React, { useContext, useEffect, useRef } from 'react'; +import React, { + useContext, + useEffect, + useImperativeHandle, + useRef, +} from 'react'; import { defaultShouldUpdateScroll } from './default_should_update_scroll'; import type { ShouldUpdateScrollFn } from './default_should_update_scroll'; @@ -11,6 +16,7 @@ interface ScrollContainerProps { */ scrollKey: string; shouldUpdateScroll?: ShouldUpdateScrollFn; + childRef?: React.ForwardedRef; children: React.ReactElement; } @@ -23,12 +29,20 @@ interface ScrollContainerProps { export const ScrollContainer: React.FC = ({ children, scrollKey, + childRef, shouldUpdateScroll = defaultShouldUpdateScroll, }) => { const scrollBehaviorContext = useContext(ScrollBehaviorContext); const containerRef = useRef(); + /** + * If a childRef is passed, sync it with the containerRef. This + * is necessary because in this component's return statement, + * we're overwriting the immediate child component's ref prop. + */ + useImperativeHandle(childRef, () => containerRef.current, []); + /** * Register/unregister scrollable element with ScrollBehavior */ diff --git a/app/javascript/flavours/glitch/features/status/index.jsx b/app/javascript/flavours/glitch/features/status/index.jsx index a04fce60e436e3..d4dfe4074754fc 100644 --- a/app/javascript/flavours/glitch/features/status/index.jsx +++ b/app/javascript/flavours/glitch/features/status/index.jsx @@ -634,7 +634,7 @@ class Status extends ImmutablePureComponent { )} /> - +
{ancestors} From 381fc173c7d7a37af9273e0bab28d7c123f1f887 Mon Sep 17 00:00:00 2001 From: Brad Dunbar Date: Fri, 26 Sep 2025 04:53:08 -0400 Subject: [PATCH 028/853] [Glitch] Refactor `getFocusedItemIndex` to avoid conditionals that `closest` already handles Port 238d74fe81b960de974c8a7459ec81f832842261 to glitch-soc Signed-off-by: Claire --- .../glitch/features/ui/util/focusUtils.ts | 20 +++++-------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/app/javascript/flavours/glitch/features/ui/util/focusUtils.ts b/app/javascript/flavours/glitch/features/ui/util/focusUtils.ts index 54601a0e24828f..9eb1740cabc58a 100644 --- a/app/javascript/flavours/glitch/features/ui/util/focusUtils.ts +++ b/app/javascript/flavours/glitch/features/ui/util/focusUtils.ts @@ -60,23 +60,13 @@ export function focusColumn({ * Get the index of the currently focused item in one of our item lists */ export function getFocusedItemIndex() { - const focusedElement = document.activeElement; - const itemList = focusedElement?.closest('.item-list'); - - if (!focusedElement || !itemList) { - return -1; - } - - let focusedItem: HTMLElement | null = null; - if (focusedElement.parentElement === itemList) { - focusedItem = focusedElement as HTMLElement; - } else { - focusedItem = focusedElement.closest('.item-list > *'); - } - + const focusedItem = document.activeElement?.closest('.item-list > *'); if (!focusedItem) return -1; - const items = Array.from(itemList.children); + const { parentElement } = focusedItem; + if (!parentElement) return -1; + + const items = Array.from(parentElement.children); return items.indexOf(focusedItem); } From eea86088cf6112f1a5f064913b0c26c05c886196 Mon Sep 17 00:00:00 2001 From: diondiondion Date: Fri, 26 Sep 2025 11:23:30 +0200 Subject: [PATCH 029/853] [Glitch] Fix page being vertically scrollable in Advanced UI Port 1571514e49ec02a57c050612b3bca856f54933fb to glitch-soc Signed-off-by: Claire --- app/javascript/flavours/glitch/styles/components.scss | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/javascript/flavours/glitch/styles/components.scss b/app/javascript/flavours/glitch/styles/components.scss index 72c11300e6c1dc..04286c16a60f4d 100644 --- a/app/javascript/flavours/glitch/styles/components.scss +++ b/app/javascript/flavours/glitch/styles/components.scss @@ -3037,8 +3037,12 @@ a.account__display-name { justify-content: flex-start; position: relative; - &.unscrollable { - overflow-x: hidden; + .layout-multiple-columns & { + overflow-x: auto; + + &.unscrollable { + overflow-x: hidden; + } } &__panels { From 8cccabb71437ca9e8486eab260bb018c565c1b96 Mon Sep 17 00:00:00 2001 From: Echo Date: Fri, 26 Sep 2025 11:50:59 +0200 Subject: [PATCH 030/853] [Glitch] Adds new HTMLBlock component Port e07b9dfdc12adb9c8b79d89f80049335053c3324 to glitch-soc Signed-off-by: Claire --- app/javascript/config/html-tags.json | 21 ++- .../html_block/html_block.stories.tsx | 40 ++++++ .../glitch/components/html_block/index.tsx | 50 +++++++ .../flavours/glitch/features/emoji/hooks.ts | 29 +--- .../glitch/features/emoji/normalize.ts | 23 +++- app/javascript/flavours/glitch/utils/html.ts | 124 +++++++++++------- 6 files changed, 209 insertions(+), 78 deletions(-) create mode 100644 app/javascript/flavours/glitch/components/html_block/html_block.stories.tsx create mode 100644 app/javascript/flavours/glitch/components/html_block/index.tsx diff --git a/app/javascript/config/html-tags.json b/app/javascript/config/html-tags.json index c788113487c6c2..cf5c96540a5e72 100644 --- a/app/javascript/config/html-tags.json +++ b/app/javascript/config/html-tags.json @@ -21,17 +21,29 @@ "href": true, "rel": true, "translate": true, - "target": true + "target": true, + "title": true + } + }, + "abbr": { + "attributes": { + "title": true } }, "del": {}, "s": {}, "pre": {}, - "blockquote": {}, + "blockquote": { + "attributes": { + "cite": true + } + }, "code": {}, "b": {}, "strong": {}, "u": {}, + "sub": {}, + "sup": {}, "i": {}, "img": { "children": false, @@ -42,6 +54,11 @@ } }, "em": {}, + "h1": {}, + "h2": {}, + "h3": {}, + "h4": {}, + "h5": {}, "ul": {}, "ol": { "attributes": { diff --git a/app/javascript/flavours/glitch/components/html_block/html_block.stories.tsx b/app/javascript/flavours/glitch/components/html_block/html_block.stories.tsx new file mode 100644 index 00000000000000..9c104ba45cb68e --- /dev/null +++ b/app/javascript/flavours/glitch/components/html_block/html_block.stories.tsx @@ -0,0 +1,40 @@ +import type { Meta, StoryObj } from '@storybook/react-vite'; +import { expect } from 'storybook/test'; + +import { HTMLBlock } from './index'; + +const meta = { + title: 'Components/HTMLBlock', + component: HTMLBlock, + args: { + contents: + '

Hello, world!

\n

A link

\n

This should be filtered out:

', + }, + render(args) { + return ( + // Just for visual clarity in Storybook. +
+ +
+ ); + }, +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + async play({ canvas }) { + const link = canvas.queryByRole('link'); + await expect(link).toBeInTheDocument(); + const button = canvas.queryByRole('button'); + await expect(button).not.toBeInTheDocument(); + }, +}; diff --git a/app/javascript/flavours/glitch/components/html_block/index.tsx b/app/javascript/flavours/glitch/components/html_block/index.tsx new file mode 100644 index 00000000000000..8072937331471a --- /dev/null +++ b/app/javascript/flavours/glitch/components/html_block/index.tsx @@ -0,0 +1,50 @@ +import type { FC, ReactNode } from 'react'; +import { useMemo } from 'react'; + +import { cleanExtraEmojis } from '@/flavours/glitch/features/emoji/normalize'; +import type { CustomEmojiMapArg } from '@/flavours/glitch/features/emoji/types'; +import { createLimitedCache } from '@/flavours/glitch/utils/cache'; + +import { htmlStringToComponents } from '../../utils/html'; + +// Use a module-level cache to avoid re-rendering the same HTML multiple times. +const cache = createLimitedCache({ maxSize: 1000 }); + +interface HTMLBlockProps { + contents: string; + extraEmojis?: CustomEmojiMapArg; +} + +export const HTMLBlock: FC = ({ + contents: raw, + extraEmojis, +}) => { + const customEmojis = useMemo( + () => cleanExtraEmojis(extraEmojis), + [extraEmojis], + ); + const contents = useMemo(() => { + const key = JSON.stringify({ raw, customEmojis }); + if (cache.has(key)) { + return cache.get(key); + } + + const rendered = htmlStringToComponents(raw, { + onText, + extraArgs: { customEmojis }, + }); + + cache.set(key, rendered); + return rendered; + }, [raw, customEmojis]); + + return contents; +}; + +function onText( + text: string, + // eslint-disable-next-line @typescript-eslint/no-unused-vars -- Doesn't do anything, just showing how typing would work. + { customEmojis }: { customEmojis: CustomEmojiMapArg | null }, +) { + return text; +} diff --git a/app/javascript/flavours/glitch/features/emoji/hooks.ts b/app/javascript/flavours/glitch/features/emoji/hooks.ts index 9c9eeb7d17d6a2..47baacef4d5852 100644 --- a/app/javascript/flavours/glitch/features/emoji/hooks.ts +++ b/app/javascript/flavours/glitch/features/emoji/hooks.ts @@ -1,19 +1,13 @@ import { useCallback, useLayoutEffect, useMemo, useState } from 'react'; -import { isList } from 'immutable'; - -import type { ApiCustomEmojiJSON } from '@/flavours/glitch/api_types/custom_emoji'; import { useAppSelector } from '@/flavours/glitch/store'; import { isModernEmojiEnabled } from '@/flavours/glitch/utils/environment'; import { toSupportedLocale } from './locale'; import { determineEmojiMode } from './mode'; +import { cleanExtraEmojis } from './normalize'; import { emojifyElement, emojifyText } from './render'; -import type { - CustomEmojiMapArg, - EmojiAppState, - ExtraCustomEmojiMap, -} from './types'; +import type { CustomEmojiMapArg, EmojiAppState } from './types'; import { stringHasAnyEmoji } from './utils'; interface UseEmojifyOptions { @@ -30,20 +24,7 @@ export function useEmojify({ const [emojifiedText, setEmojifiedText] = useState(null); const appState = useEmojiAppState(); - const extra: ExtraCustomEmojiMap = useMemo(() => { - if (!extraEmojis) { - return {}; - } - if (isList(extraEmojis)) { - return ( - extraEmojis.toJS() as ApiCustomEmojiJSON[] - ).reduce( - (acc, emoji) => ({ ...acc, [emoji.shortcode]: emoji }), - {}, - ); - } - return extraEmojis; - }, [extraEmojis]); + const extra = useMemo(() => cleanExtraEmojis(extraEmojis), [extraEmojis]); const emojify = useCallback( async (input: string) => { @@ -51,11 +32,11 @@ export function useEmojify({ if (deep) { const wrapper = document.createElement('div'); wrapper.innerHTML = input; - if (await emojifyElement(wrapper, appState, extra)) { + if (await emojifyElement(wrapper, appState, extra ?? {})) { result = wrapper.innerHTML; } } else { - result = await emojifyText(text, appState, extra); + result = await emojifyText(text, appState, extra ?? {}); } if (result) { setEmojifiedText(result); diff --git a/app/javascript/flavours/glitch/features/emoji/normalize.ts b/app/javascript/flavours/glitch/features/emoji/normalize.ts index 6a64c3b8bfabc2..959732f9856d19 100644 --- a/app/javascript/flavours/glitch/features/emoji/normalize.ts +++ b/app/javascript/flavours/glitch/features/emoji/normalize.ts @@ -1,3 +1,5 @@ +import { isList } from 'immutable'; + import { VARIATION_SELECTOR_CODE, KEYCAP_CODE, @@ -7,7 +9,11 @@ import { EMOJIS_WITH_DARK_BORDER, EMOJIS_WITH_LIGHT_BORDER, } from './constants'; -import type { TwemojiBorderInfo } from './types'; +import type { + CustomEmojiMapArg, + ExtraCustomEmojiMap, + TwemojiBorderInfo, +} from './types'; // Misc codes that have special handling const SKIER_CODE = 0x26f7; @@ -150,6 +156,21 @@ export function twemojiToUnicodeInfo( return hexNumbersToString(mappedCodes); } +export function cleanExtraEmojis(extraEmojis?: CustomEmojiMapArg) { + if (!extraEmojis) { + return null; + } + if (!isList(extraEmojis)) { + return extraEmojis; + } + return extraEmojis + .toJSON() + .reduce( + (acc, emoji) => ({ ...acc, [emoji.shortcode]: emoji }), + {}, + ); +} + function hexStringToNumbers(hexString: string): number[] { return hexString .split('-') diff --git a/app/javascript/flavours/glitch/utils/html.ts b/app/javascript/flavours/glitch/utils/html.ts index 16863223007abf..52b0fb7b7e7dcd 100644 --- a/app/javascript/flavours/glitch/utils/html.ts +++ b/app/javascript/flavours/glitch/utils/html.ts @@ -1,5 +1,7 @@ import React from 'react'; +import htmlConfig from '../../../config/html-tags.json'; + // NB: This function can still return unsafe HTML export const unescapeHTML = (html: string) => { const wrapper = document.createElement('div'); @@ -10,64 +12,49 @@ export const unescapeHTML = (html: string) => { return wrapper.textContent; }; +interface AllowedTag { + /* True means allow, false disallows global attributes, string renames the attribute name for React. */ + attributes?: Record; + /* If false, the tag cannot have children. Undefined or true means allowed. */ + children?: boolean; +} + +type AllowedTagsType = { + [Tag in keyof React.ReactHTML]?: AllowedTag; +}; + +const globalAttributes: Record = htmlConfig.global; +const defaultAllowedTags: AllowedTagsType = htmlConfig.tags; + interface QueueItem { node: Node; parent: React.ReactNode[]; depth: number; } -interface Options { +export interface HTMLToStringOptions> { maxDepth?: number; - onText?: (text: string) => React.ReactNode; + onText?: (text: string, extra: Arg) => React.ReactNode; onElement?: ( element: HTMLElement, children: React.ReactNode[], + extra: Arg, ) => React.ReactNode; onAttribute?: ( name: string, value: string, tagName: string, + extra: Arg, ) => [string, unknown] | null; - allowedTags?: Set; + allowedTags?: AllowedTagsType; + extraArgs?: Arg; } -const DEFAULT_ALLOWED_TAGS: ReadonlySet = new Set([ - 'a', - 'abbr', - 'b', - 'blockquote', - 'br', - 'cite', - 'code', - 'del', - 'dfn', - 'dl', - 'dt', - 'em', - 'h1', - 'h2', - 'h3', - 'h4', - 'h5', - 'h6', - 'hr', - 'i', - 'li', - 'ol', - 'p', - 'pre', - 'small', - 'span', - 'strong', - 'sub', - 'sup', - 'time', - 'u', - 'ul', -]); - -export function htmlStringToComponents( + +let uniqueIdCounter = 0; + +export function htmlStringToComponents>( htmlString: string, - options: Options = {}, + options: HTMLToStringOptions = {}, ) { const wrapper = document.createElement('template'); wrapper.innerHTML = htmlString; @@ -79,10 +66,11 @@ export function htmlStringToComponents( const { maxDepth = 10, - allowedTags = DEFAULT_ALLOWED_TAGS, + allowedTags = defaultAllowedTags, onAttribute, onElement, onText, + extraArgs = {} as Arg, } = options; while (queue.length > 0) { @@ -109,9 +97,9 @@ export function htmlStringToComponents( // Text can be added directly if it has any non-whitespace content. case Node.TEXT_NODE: { const text = node.textContent; - if (text && text.trim() !== '') { + if (text) { if (onText) { - parent.push(onText(text)); + parent.push(onText(text, extraArgs)); } else { parent.push(text); } @@ -127,7 +115,9 @@ export function htmlStringToComponents( } // If the tag is not allowed, skip it and its children. - if (!allowedTags.has(node.tagName.toLowerCase())) { + const tagName = node.tagName.toLowerCase(); + const tagInfo = allowedTags[tagName as keyof typeof allowedTags]; + if (!tagInfo) { continue; } @@ -137,7 +127,8 @@ export function htmlStringToComponents( // If onElement is provided, use it to create the element. if (onElement) { - const component = onElement(node, children); + const component = onElement(node, children, extraArgs); + // Check for undefined to allow returning null. if (component !== undefined) { element = component; @@ -147,25 +138,56 @@ export function htmlStringToComponents( // If the element wasn't created, use the default conversion. if (element === undefined) { const props: Record = {}; + props.key = `html-${uniqueIdCounter++}`; // Get the current key and then increment it. for (const attr of node.attributes) { + let name = attr.name.toLowerCase(); + + // Custom attribute handler. if (onAttribute) { const result = onAttribute( - attr.name, + name, attr.value, node.tagName.toLowerCase(), + extraArgs, ); if (result) { - const [name, value] = result; - props[name] = value; + const [cbName, value] = result; + props[cbName] = value; } } else { - props[attr.name] = attr.value; + // Check global attributes first, then tag-specific ones. + const globalAttr = globalAttributes[name]; + const tagAttr = tagInfo.attributes?.[name]; + + // Exit if neither global nor tag-specific attribute is allowed. + if (!globalAttr && !tagAttr) { + continue; + } + + // Rename if needed. + if (typeof tagAttr === 'string') { + name = tagAttr; + } else if (typeof globalAttr === 'string') { + name = globalAttr; + } + + let value: string | boolean | number = attr.value; + + // Handle boolean attributes. + if (value === 'true') { + value = true; + } else if (value === 'false') { + value = false; + } + + props[name] = value; } } + element = React.createElement( - node.tagName.toLowerCase(), + tagName, props, - children, + tagInfo.children !== false ? children : undefined, ); } From a4dc785de326ce60402952e05dc66fb76583d9c4 Mon Sep 17 00:00:00 2001 From: diondiondion Date: Fri, 26 Sep 2025 12:00:50 +0200 Subject: [PATCH 031/853] [Glitch] Update "Follow" button labels Port cb5bbbfb051e175afb538bf9b83a7ca2d2b2b867 to glitch-soc Signed-off-by: Claire --- .../glitch/components/follow_button.tsx | 65 ++++++++- .../directory/components/account_card.tsx | 124 +----------------- .../components/inline_follow_suggestions.tsx | 2 - .../features/ui/hooks/useBreakpoint.tsx | 3 +- 4 files changed, 68 insertions(+), 126 deletions(-) diff --git a/app/javascript/flavours/glitch/components/follow_button.tsx b/app/javascript/flavours/glitch/components/follow_button.tsx index e574b43b2521aa..7e84a2580e8b98 100644 --- a/app/javascript/flavours/glitch/components/follow_button.tsx +++ b/app/javascript/flavours/glitch/components/follow_button.tsx @@ -8,6 +8,8 @@ import { useIdentity } from '@/flavours/glitch/identity_context'; import { fetchRelationships, followAccount, + unblockAccount, + unmuteAccount, } from 'flavours/glitch/actions/accounts'; import { openModal } from 'flavours/glitch/actions/modal'; import { Button } from 'flavours/glitch/components/button'; @@ -15,17 +17,49 @@ import { LoadingIndicator } from 'flavours/glitch/components/loading_indicator'; import { me } from 'flavours/glitch/initial_state'; import { useAppDispatch, useAppSelector } from 'flavours/glitch/store'; -const messages = defineMessages({ +import { useBreakpoint } from '../features/ui/hooks/useBreakpoint'; + +const longMessages = defineMessages({ unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' }, + unblock: { id: 'account.unblock_short', defaultMessage: 'Unblock' }, + unmute: { id: 'account.unmute_short', defaultMessage: 'Unmute' }, follow: { id: 'account.follow', defaultMessage: 'Follow' }, followBack: { id: 'account.follow_back', defaultMessage: 'Follow back' }, + followRequest: { + id: 'account.follow_request', + defaultMessage: 'Request to follow', + }, + followRequestCancel: { + id: 'account.follow_request_cancel', + defaultMessage: 'Cancel request', + }, edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' }, }); +const shortMessages = { + ...longMessages, // Align type signature of shortMessages and longMessages + ...defineMessages({ + followBack: { + id: 'account.follow_back_short', + defaultMessage: 'Follow back', + }, + followRequest: { + id: 'account.follow_request_short', + defaultMessage: 'Request', + }, + followRequestCancel: { + id: 'account.follow_request_cancel_short', + defaultMessage: 'Cancel', + }, + editProfile: { id: 'account.edit_profile_short', defaultMessage: 'Edit' }, + }), +}; + export const FollowButton: React.FC<{ accountId?: string; compact?: boolean; -}> = ({ accountId, compact }) => { + labelLength?: 'auto' | 'short' | 'long'; +}> = ({ accountId, compact, labelLength = 'auto' }) => { const intl = useIntl(); const dispatch = useAppDispatch(); const { signedIn } = useIdentity(); @@ -60,29 +94,48 @@ export const FollowButton: React.FC<{ if (accountId === me) { return; + } else if (relationship.muting) { + dispatch(unmuteAccount(accountId)); } else if (account && (relationship.following || relationship.requested)) { dispatch( openModal({ modalType: 'CONFIRM_UNFOLLOW', modalProps: { account } }), ); + } else if (relationship.blocking) { + dispatch(unblockAccount(accountId)); } else { dispatch(followAccount(accountId)); } }, [dispatch, accountId, relationship, account, signedIn]); + const isNarrow = useBreakpoint('narrow'); + const useShortLabel = + labelLength === 'short' || (labelLength === 'auto' && isNarrow); + const messages = useShortLabel ? shortMessages : longMessages; + + const followMessage = account?.locked + ? messages.followRequest + : messages.follow; + let label; if (!signedIn) { - label = intl.formatMessage(messages.follow); + label = intl.formatMessage(followMessage); } else if (accountId === me) { label = intl.formatMessage(messages.edit_profile); } else if (!relationship) { label = ; - } else if (relationship.following || relationship.requested) { + } else if (relationship.muting) { + label = intl.formatMessage(messages.unmute); + } else if (relationship.following) { label = intl.formatMessage(messages.unfollow); - } else if (relationship.followed_by) { + } else if (relationship.blocking) { + label = intl.formatMessage(messages.unblock); + } else if (relationship.requested) { + label = intl.formatMessage(messages.followRequestCancel); + } else if (relationship.followed_by && !account?.locked) { label = intl.formatMessage(messages.followBack); } else { - label = intl.formatMessage(messages.follow); + label = intl.formatMessage(followMessage); } if (accountId === me) { diff --git a/app/javascript/flavours/glitch/features/directory/components/account_card.tsx b/app/javascript/flavours/glitch/features/directory/components/account_card.tsx index deb4f4832d1566..b07928573e8142 100644 --- a/app/javascript/flavours/glitch/features/directory/components/account_card.tsx +++ b/app/javascript/flavours/glitch/features/directory/components/account_card.tsx @@ -1,134 +1,22 @@ -import { useCallback } from 'react'; +import { FormattedMessage } from 'react-intl'; -import { FormattedMessage, defineMessages, useIntl } from 'react-intl'; - -import classNames from 'classnames'; - -import { - followAccount, - unblockAccount, - unmuteAccount, -} from 'flavours/glitch/actions/accounts'; -import { openModal } from 'flavours/glitch/actions/modal'; import { Avatar } from 'flavours/glitch/components/avatar'; -import { Button } from 'flavours/glitch/components/button'; import { DisplayName } from 'flavours/glitch/components/display_name'; +import { FollowButton } from 'flavours/glitch/components/follow_button'; import { Permalink } from 'flavours/glitch/components/permalink'; import { ShortNumber } from 'flavours/glitch/components/short_number'; -import { autoPlayGif, me } from 'flavours/glitch/initial_state'; +import { autoPlayGif } from 'flavours/glitch/initial_state'; import type { Account } from 'flavours/glitch/models/account'; import { makeGetAccount } from 'flavours/glitch/selectors'; -import { useAppDispatch, useAppSelector } from 'flavours/glitch/store'; - -const messages = defineMessages({ - unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' }, - follow: { id: 'account.follow', defaultMessage: 'Follow' }, - cancel_follow_request: { - id: 'account.cancel_follow_request', - defaultMessage: 'Withdraw follow request', - }, - requested: { - id: 'account.requested', - defaultMessage: 'Awaiting approval. Click to cancel follow request', - }, - unblock: { id: 'account.unblock_short', defaultMessage: 'Unblock' }, - unmute: { id: 'account.unmute_short', defaultMessage: 'Unmute' }, - edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' }, -}); +import { useAppSelector } from 'flavours/glitch/store'; const getAccount = makeGetAccount(); export const AccountCard: React.FC<{ accountId: string }> = ({ accountId }) => { - const intl = useIntl(); const account = useAppSelector((s) => getAccount(s, accountId)); - const dispatch = useAppDispatch(); - - const handleFollow = useCallback(() => { - if (!account) return; - - if ( - account.getIn(['relationship', 'following']) || - account.getIn(['relationship', 'requested']) - ) { - dispatch( - openModal({ modalType: 'CONFIRM_UNFOLLOW', modalProps: { account } }), - ); - } else { - dispatch(followAccount(account.get('id'))); - } - }, [account, dispatch]); - - const handleBlock = useCallback(() => { - if (account?.relationship?.blocking) { - dispatch(unblockAccount(account.get('id'))); - } - }, [account, dispatch]); - - const handleMute = useCallback(() => { - if (account?.relationship?.muting) { - dispatch(unmuteAccount(account.get('id'))); - } - }, [account, dispatch]); - - const handleEditProfile = useCallback(() => { - window.open('/settings/profile', '_blank'); - }, []); if (!account) return null; - let actionBtn; - - if (me !== account.get('id')) { - if (!account.get('relationship')) { - // Wait until the relationship is loaded - actionBtn = ''; - } else if (account.getIn(['relationship', 'requested'])) { - actionBtn = ( -
-
{actionBtn}
+
+ +
); diff --git a/app/javascript/flavours/glitch/features/home_timeline/components/inline_follow_suggestions.tsx b/app/javascript/flavours/glitch/features/home_timeline/components/inline_follow_suggestions.tsx index e5aa8d0297874f..bcbb0962fbd8d5 100644 --- a/app/javascript/flavours/glitch/features/home_timeline/components/inline_follow_suggestions.tsx +++ b/app/javascript/flavours/glitch/features/home_timeline/components/inline_follow_suggestions.tsx @@ -25,8 +25,6 @@ import { domain } from 'flavours/glitch/initial_state'; import { useAppDispatch, useAppSelector } from 'flavours/glitch/store'; const messages = defineMessages({ - follow: { id: 'account.follow', defaultMessage: 'Follow' }, - unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' }, previous: { id: 'lightbox.previous', defaultMessage: 'Previous' }, next: { id: 'lightbox.next', defaultMessage: 'Next' }, dismiss: { diff --git a/app/javascript/flavours/glitch/features/ui/hooks/useBreakpoint.tsx b/app/javascript/flavours/glitch/features/ui/hooks/useBreakpoint.tsx index af96ab3766345c..cb7b3551f222f0 100644 --- a/app/javascript/flavours/glitch/features/ui/hooks/useBreakpoint.tsx +++ b/app/javascript/flavours/glitch/features/ui/hooks/useBreakpoint.tsx @@ -1,11 +1,12 @@ import { useState, useEffect } from 'react'; const breakpoints = { + narrow: 479, // Device width under which horizontal space is constrained openable: 759, // Device width at which the sidebar becomes an openable hamburger menu full: 1174, // Device width at which all 3 columns can be displayed }; -type Breakpoint = 'openable' | 'full'; +type Breakpoint = keyof typeof breakpoints; export const useBreakpoint = (breakpoint: Breakpoint) => { const [isMatching, setIsMatching] = useState(false); From aae9a5528a1677177a65891a058870f2e763e176 Mon Sep 17 00:00:00 2001 From: Brad Dunbar Date: Mon, 29 Sep 2025 05:10:27 -0400 Subject: [PATCH 032/853] Remove shallow prop from Wrapper (#36275) --- app/javascript/mastodon/features/emoji/emoji_html.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/javascript/mastodon/features/emoji/emoji_html.tsx b/app/javascript/mastodon/features/emoji/emoji_html.tsx index 08d62b2c37aa9a..b4c352073cec33 100644 --- a/app/javascript/mastodon/features/emoji/emoji_html.tsx +++ b/app/javascript/mastodon/features/emoji/emoji_html.tsx @@ -51,7 +51,14 @@ export const EmojiHTML = ( if (isModernEmojiEnabled()) { return ; } - const { as: asElement, htmlString, extraEmojis, className, ...rest } = props; + const { + as: asElement, + htmlString, + extraEmojis, + className, + shallow: _, + ...rest + } = props; const Wrapper = asElement ?? 'div'; return ( Date: Mon, 29 Sep 2025 11:16:16 +0200 Subject: [PATCH 033/853] New Crowdin Translations (automated) (#36276) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/af.json | 1 - app/javascript/mastodon/locales/an.json | 1 - app/javascript/mastodon/locales/ar.json | 1 - app/javascript/mastodon/locales/az.json | 1 - app/javascript/mastodon/locales/be.json | 7 +++- app/javascript/mastodon/locales/bg.json | 1 - app/javascript/mastodon/locales/bn.json | 1 - app/javascript/mastodon/locales/br.json | 1 - app/javascript/mastodon/locales/ca.json | 1 - app/javascript/mastodon/locales/ckb.json | 1 - app/javascript/mastodon/locales/co.json | 1 - app/javascript/mastodon/locales/cs.json | 7 +++- app/javascript/mastodon/locales/cy.json | 14 +++++++- app/javascript/mastodon/locales/da.json | 7 +++- app/javascript/mastodon/locales/de.json | 7 +++- app/javascript/mastodon/locales/el.json | 7 +++- app/javascript/mastodon/locales/en-GB.json | 1 - app/javascript/mastodon/locales/eo.json | 1 - app/javascript/mastodon/locales/es-AR.json | 7 +++- app/javascript/mastodon/locales/es-MX.json | 7 +++- app/javascript/mastodon/locales/es.json | 7 +++- app/javascript/mastodon/locales/et.json | 7 +++- app/javascript/mastodon/locales/eu.json | 1 - app/javascript/mastodon/locales/fa.json | 1 - app/javascript/mastodon/locales/fi.json | 7 +++- app/javascript/mastodon/locales/fil.json | 1 - app/javascript/mastodon/locales/fo.json | 7 +++- app/javascript/mastodon/locales/fr-CA.json | 1 - app/javascript/mastodon/locales/fr.json | 1 - app/javascript/mastodon/locales/fy.json | 1 - app/javascript/mastodon/locales/ga.json | 7 +++- app/javascript/mastodon/locales/gd.json | 1 - app/javascript/mastodon/locales/gl.json | 7 +++- app/javascript/mastodon/locales/he.json | 7 +++- app/javascript/mastodon/locales/hi.json | 1 - app/javascript/mastodon/locales/hr.json | 1 - app/javascript/mastodon/locales/hu.json | 1 - app/javascript/mastodon/locales/hy.json | 1 - app/javascript/mastodon/locales/ia.json | 7 +++- app/javascript/mastodon/locales/id.json | 1 - app/javascript/mastodon/locales/ie.json | 1 - app/javascript/mastodon/locales/io.json | 1 - app/javascript/mastodon/locales/is.json | 20 +++++++++-- app/javascript/mastodon/locales/it.json | 1 - app/javascript/mastodon/locales/ja.json | 1 - app/javascript/mastodon/locales/ka.json | 1 - app/javascript/mastodon/locales/kab.json | 17 ++++++++-- app/javascript/mastodon/locales/kk.json | 1 - app/javascript/mastodon/locales/kn.json | 1 - app/javascript/mastodon/locales/ko.json | 1 - app/javascript/mastodon/locales/ku.json | 1 - app/javascript/mastodon/locales/kw.json | 1 - app/javascript/mastodon/locales/lad.json | 1 - app/javascript/mastodon/locales/lt.json | 1 - app/javascript/mastodon/locales/lv.json | 1 - app/javascript/mastodon/locales/mk.json | 1 - app/javascript/mastodon/locales/ml.json | 1 - app/javascript/mastodon/locales/mr.json | 1 - app/javascript/mastodon/locales/ms.json | 1 - app/javascript/mastodon/locales/my.json | 1 - app/javascript/mastodon/locales/nan.json | 16 ++++++++- app/javascript/mastodon/locales/ne.json | 1 - app/javascript/mastodon/locales/nl.json | 7 +++- app/javascript/mastodon/locales/nn.json | 1 - app/javascript/mastodon/locales/no.json | 1 - app/javascript/mastodon/locales/oc.json | 1 - app/javascript/mastodon/locales/pa.json | 1 - app/javascript/mastodon/locales/pl.json | 1 - app/javascript/mastodon/locales/pt-BR.json | 1 - app/javascript/mastodon/locales/pt-PT.json | 7 +++- app/javascript/mastodon/locales/ro.json | 1 - app/javascript/mastodon/locales/ru.json | 1 - app/javascript/mastodon/locales/ry.json | 1 - app/javascript/mastodon/locales/sa.json | 1 - app/javascript/mastodon/locales/sc.json | 1 - app/javascript/mastodon/locales/sco.json | 1 - app/javascript/mastodon/locales/si.json | 1 - app/javascript/mastodon/locales/sk.json | 1 - app/javascript/mastodon/locales/sl.json | 1 - app/javascript/mastodon/locales/sq.json | 1 - app/javascript/mastodon/locales/sr-Latn.json | 1 - app/javascript/mastodon/locales/sr.json | 1 - app/javascript/mastodon/locales/sv.json | 1 - app/javascript/mastodon/locales/szl.json | 1 - app/javascript/mastodon/locales/ta.json | 1 - app/javascript/mastodon/locales/tai.json | 1 - app/javascript/mastodon/locales/te.json | 1 - app/javascript/mastodon/locales/th.json | 1 - app/javascript/mastodon/locales/tok.json | 1 - app/javascript/mastodon/locales/tr.json | 7 +++- app/javascript/mastodon/locales/tt.json | 1 - app/javascript/mastodon/locales/ug.json | 1 - app/javascript/mastodon/locales/uk.json | 1 - app/javascript/mastodon/locales/ur.json | 1 - app/javascript/mastodon/locales/uz.json | 1 - app/javascript/mastodon/locales/vi.json | 7 +++- app/javascript/mastodon/locales/zgh.json | 1 - app/javascript/mastodon/locales/zh-CN.json | 1 - app/javascript/mastodon/locales/zh-HK.json | 1 - app/javascript/mastodon/locales/zh-TW.json | 7 +++- config/locales/kab.yml | 24 ++++++++++++-- config/locales/nan.yml | 35 ++++++++++++++++++-- 102 files changed, 234 insertions(+), 108 deletions(-) diff --git a/app/javascript/mastodon/locales/af.json b/app/javascript/mastodon/locales/af.json index 6df4608528097a..7ab1d793ed4aaa 100644 --- a/app/javascript/mastodon/locales/af.json +++ b/app/javascript/mastodon/locales/af.json @@ -44,7 +44,6 @@ "account.posts": "Plasings", "account.posts_with_replies": "Plasings en antwoorde", "account.report": "Rapporteer @{name}", - "account.requested": "Wag op goedkeuring. Klik om volgversoek te kanselleer", "account.requested_follow": "{name} het versoek om jou te volg", "account.share": "Deel @{name} se profiel", "account.show_reblogs": "Wys aangestuurde plasings van @{name}", diff --git a/app/javascript/mastodon/locales/an.json b/app/javascript/mastodon/locales/an.json index 661a1bebdb3fa4..bd4c061266a64e 100644 --- a/app/javascript/mastodon/locales/an.json +++ b/app/javascript/mastodon/locales/an.json @@ -44,7 +44,6 @@ "account.posts": "Publicacions", "account.posts_with_replies": "Publicacions y respuestas", "account.report": "Denunciar a @{name}", - "account.requested": "Esperando l'aprebación", "account.requested_follow": "{name} ha demandau seguir-te", "account.share": "Compartir lo perfil de @{name}", "account.show_reblogs": "Amostrar retutz de @{name}", diff --git a/app/javascript/mastodon/locales/ar.json b/app/javascript/mastodon/locales/ar.json index eb4933e1880625..affadf671f295c 100644 --- a/app/javascript/mastodon/locales/ar.json +++ b/app/javascript/mastodon/locales/ar.json @@ -70,7 +70,6 @@ "account.posts_with_replies": "المنشورات والرُدود", "account.remove_from_followers": "إزالة {name} من المتابعين", "account.report": "الإبلاغ عن @{name}", - "account.requested": "في انتظار القبول. اضغط لإلغاء طلب المُتابعة", "account.requested_follow": "لقد طلب {name} متابعتك", "account.requests_to_follow_you": "طلبات المتابعة", "account.share": "شارِك الملف التعريفي لـ @{name}", diff --git a/app/javascript/mastodon/locales/az.json b/app/javascript/mastodon/locales/az.json index 4c7a61746f3124..a6b11dd910b272 100644 --- a/app/javascript/mastodon/locales/az.json +++ b/app/javascript/mastodon/locales/az.json @@ -70,7 +70,6 @@ "account.posts_with_replies": "Paylaşım və cavablar", "account.remove_from_followers": "{name} - izləyicilərdən çıxart", "account.report": "@{name} istifadəçisini şikayət et", - "account.requested": "Təsdiq edilməsi gözlənilir. İzləmə sorğusunu ləğv etmək üçün kliklə", "account.requested_follow": "{name} sizi izləmək sorğusu göndərib", "account.requests_to_follow_you": "Sizi izləmək istəyir", "account.share": "@{name} profilini paylaş", diff --git a/app/javascript/mastodon/locales/be.json b/app/javascript/mastodon/locales/be.json index 6086fbf77f04ea..56430cee50de2c 100644 --- a/app/javascript/mastodon/locales/be.json +++ b/app/javascript/mastodon/locales/be.json @@ -28,6 +28,7 @@ "account.disable_notifications": "Не паведамляць мне пра публікацыі @{name}", "account.domain_blocking": "Блакіраванне дамена", "account.edit_profile": "Рэдагаваць профіль", + "account.edit_profile_short": "Рэдагаваць", "account.enable_notifications": "Апавяшчаць мяне пра допісы @{name}", "account.endorse": "Паказваць у профілі", "account.familiar_followers_many": "Мае сярод падпісчыкаў {name1}, {name2}, і {othersCount, plural, one {яшчэ # чалавека, знаёмага вам} few {яшчэ # чалавекі, знаёмыя вам} many {яшчэ # чалавек, знаёмых вам} other {яшчэ # чалавекі, знаёмыя вам}}", @@ -40,6 +41,11 @@ "account.featured_tags.last_status_never": "Няма допісаў", "account.follow": "Падпісацца", "account.follow_back": "Падпісацца ў адказ", + "account.follow_back_short": "Падпісацца ў адказ", + "account.follow_request": "Даслаць запыт на падпіску", + "account.follow_request_cancel": "Скасаваць запыт", + "account.follow_request_cancel_short": "Скасаваць", + "account.follow_request_short": "Запыт", "account.followers": "Падпісчыкі", "account.followers.empty": "Ніхто пакуль не падпісаны на гэтага карыстальніка.", "account.followers_counter": "{count, plural, one {{counter} падпісчык} few {{counter} падпісчыкі} many {{counter} падпісчыкаў} other {{counter} падпісчыка}}", @@ -70,7 +76,6 @@ "account.posts_with_replies": "Допісы і адказы", "account.remove_from_followers": "Выдаліць {name} з падпісчыкаў", "account.report": "Паскардзіцца на @{name}", - "account.requested": "Чакаецца ўхваленне. Націсніце, каб скасаваць запыт на падпіску", "account.requested_follow": "{name} адправіў(-ла) запыт на падпіску", "account.requests_to_follow_you": "Хоча падпісацца на вас", "account.share": "Абагуліць профіль @{name}", diff --git a/app/javascript/mastodon/locales/bg.json b/app/javascript/mastodon/locales/bg.json index b148994b552979..259d6e71e0b9ad 100644 --- a/app/javascript/mastodon/locales/bg.json +++ b/app/javascript/mastodon/locales/bg.json @@ -70,7 +70,6 @@ "account.posts_with_replies": "Публ. и отговори", "account.remove_from_followers": "Премахване на {name} от последователи", "account.report": "Докладване на @{name}", - "account.requested": "Чака се одобрение. Щракнете за отмяна на заявката за последване", "account.requested_follow": "{name} поиска да ви последва", "account.requests_to_follow_you": "Заявки да ви последват", "account.share": "Споделяне на профила на @{name}", diff --git a/app/javascript/mastodon/locales/bn.json b/app/javascript/mastodon/locales/bn.json index 4caa8bc3953a74..e6c4ae0e7db440 100644 --- a/app/javascript/mastodon/locales/bn.json +++ b/app/javascript/mastodon/locales/bn.json @@ -53,7 +53,6 @@ "account.posts": "পোষ্টসমূহ", "account.posts_with_replies": "টুট এবং মতামত", "account.report": "@{name} কে রিপোর্ট করুন", - "account.requested": "অনুমতির অপেক্ষা। অনুসরণ করার অনুরোধ বাতিল করতে এখানে ক্লিক করুন", "account.requested_follow": "{name} আপনাকে অনুসরণ করার জন্য অনুরোধ করেছে", "account.share": "@{name} র প্রোফাইল অন্যদের দেখান", "account.show_reblogs": "@{name} র সমর্থনগুলো দেখান", diff --git a/app/javascript/mastodon/locales/br.json b/app/javascript/mastodon/locales/br.json index 5a4828daf53c25..b3e9d220279f64 100644 --- a/app/javascript/mastodon/locales/br.json +++ b/app/javascript/mastodon/locales/br.json @@ -68,7 +68,6 @@ "account.posts_with_replies": "Embannadurioù ha respontoù", "account.remove_from_followers": "Dilemel {name} eus an heulierien·ezed", "account.report": "Disklêriañ @{name}", - "account.requested": "O c'hortoz an asant. Klikit evit nullañ ar goulenn heuliañ", "account.requested_follow": "Gant {name} eo bet goulennet ho heuliañ", "account.requests_to_follow_you": "Rekedoù d'ho heuliañ", "account.share": "Skignañ profil @{name}", diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json index ee6e5050a8d49a..712adc59bbc9bf 100644 --- a/app/javascript/mastodon/locales/ca.json +++ b/app/javascript/mastodon/locales/ca.json @@ -70,7 +70,6 @@ "account.posts_with_replies": "Tuts i respostes", "account.remove_from_followers": "Elimina {name} dels seguidors", "account.report": "Informa sobre @{name}", - "account.requested": "S'espera l'aprovació. Clica per a cancel·lar la petició de seguiment", "account.requested_follow": "{name} ha demanat de seguir-te", "account.requests_to_follow_you": "Peticions de seguir-vos", "account.share": "Comparteix el perfil de @{name}", diff --git a/app/javascript/mastodon/locales/ckb.json b/app/javascript/mastodon/locales/ckb.json index 0188b67e2742b4..00e946256944f4 100644 --- a/app/javascript/mastodon/locales/ckb.json +++ b/app/javascript/mastodon/locales/ckb.json @@ -52,7 +52,6 @@ "account.posts": "نووسراوەکان", "account.posts_with_replies": "توتس و وەڵامەکان", "account.report": "گوزارشت @{name}", - "account.requested": "چاوەڕێی ڕەزامەندین. کرتە بکە بۆ هەڵوەشاندنەوەی داواکاری شوێنکەوتن", "account.requested_follow": "{name} داوای کردووە شوێنت بکەوێت", "account.share": "پرۆفایلی @{name} هاوبەش بکە", "account.show_reblogs": "پیشاندانی بەرزکردنەوەکان لە @{name}", diff --git a/app/javascript/mastodon/locales/co.json b/app/javascript/mastodon/locales/co.json index 7a0306bc31c64c..c8df1d444c3cc1 100644 --- a/app/javascript/mastodon/locales/co.json +++ b/app/javascript/mastodon/locales/co.json @@ -24,7 +24,6 @@ "account.posts": "Statuti", "account.posts_with_replies": "Statuti è risposte", "account.report": "Palisà @{name}", - "account.requested": "In attesa d'apprubazione. Cliccate per annullà a dumanda", "account.share": "Sparte u prufile di @{name}", "account.show_reblogs": "Vede spartere da @{name}", "account.unblock": "Sbluccà @{name}", diff --git a/app/javascript/mastodon/locales/cs.json b/app/javascript/mastodon/locales/cs.json index d972d4705b3645..5ec5fa7bb54c04 100644 --- a/app/javascript/mastodon/locales/cs.json +++ b/app/javascript/mastodon/locales/cs.json @@ -28,6 +28,7 @@ "account.disable_notifications": "Přestat mě upozorňovat, když @{name} zveřejní příspěvek", "account.domain_blocking": "Blokované domény", "account.edit_profile": "Upravit profil", + "account.edit_profile_short": "Upravit", "account.enable_notifications": "Oznamovat mi příspěvky @{name}", "account.endorse": "Zvýraznit na profilu", "account.familiar_followers_many": "Sleduje je {name1}, {name2} a {othersCount, plural, one {jeden další, které znáte} few {# další, které znáte} many {# dalších, které znáte} other {# dalších, které znáte}}", @@ -40,6 +41,11 @@ "account.featured_tags.last_status_never": "Žádné příspěvky", "account.follow": "Sledovat", "account.follow_back": "Také sledovat", + "account.follow_back_short": "Také sledovat", + "account.follow_request": "Požádat o sledování", + "account.follow_request_cancel": "Zrušit požadavek", + "account.follow_request_cancel_short": "Zrušit", + "account.follow_request_short": "Požádat", "account.followers": "Sledující", "account.followers.empty": "Tohoto uživatele zatím nikdo nesleduje.", "account.followers_counter": "{count, plural, one {{counter} sledující} few {{counter} sledující} many {{counter} sledujících} other {{counter} sledujících}}", @@ -70,7 +76,6 @@ "account.posts_with_replies": "Příspěvky a odpovědi", "account.remove_from_followers": "Odebrat {name} ze sledujících", "account.report": "Nahlásit @{name}", - "account.requested": "Čeká na schválení. Kliknutím žádost o sledování zrušíte", "account.requested_follow": "{name} tě požádal o sledování", "account.requests_to_follow_you": "Žádosti o sledování", "account.share": "Sdílet profil @{name}", diff --git a/app/javascript/mastodon/locales/cy.json b/app/javascript/mastodon/locales/cy.json index 851ec1d5594f09..941bc016c9717f 100644 --- a/app/javascript/mastodon/locales/cy.json +++ b/app/javascript/mastodon/locales/cy.json @@ -28,6 +28,7 @@ "account.disable_notifications": "Stopiwch fy hysbysu pan fydd @{name} yn postio", "account.domain_blocking": "Parthau'n cael eu rhwystro", "account.edit_profile": "Golygu'r proffil", + "account.edit_profile_short": "Golygu", "account.enable_notifications": "Rhowch wybod i fi pan fydd @{name} yn postio", "account.endorse": "Dangos ar fy mhroffil", "account.familiar_followers_many": "Yn cael ei ddilyn gan {name1},{name2}, a {othersCount, plural, one {one other you know} other{# others you know}}", @@ -40,6 +41,11 @@ "account.featured_tags.last_status_never": "Dim postiadau", "account.follow": "Dilyn", "account.follow_back": "Dilyn nôl", + "account.follow_back_short": "Dilyn nôl", + "account.follow_request": "Cais i ddilyn", + "account.follow_request_cancel": "Diddymu cais", + "account.follow_request_cancel_short": "Diddymu", + "account.follow_request_short": "Gofyn", "account.followers": "Dilynwyr", "account.followers.empty": "Does neb yn dilyn y defnyddiwr hwn eto.", "account.followers_counter": "{count, plural, one {{counter} dilynwr} two {{counter} ddilynwr} other {{counter} dilynwr}}", @@ -70,7 +76,6 @@ "account.posts_with_replies": "Postiadau ac ymatebion", "account.remove_from_followers": "Tynnu {name} o'ch dilynwyr", "account.report": "Adrodd @{name}", - "account.requested": "Aros am gymeradwyaeth. Cliciwch er mwyn canslo cais dilyn", "account.requested_follow": "Mae {name} wedi gwneud cais i'ch dilyn", "account.requests_to_follow_you": "Ceisiadau i'ch dilyn", "account.share": "Rhannu proffil @{name}", @@ -865,6 +870,13 @@ "status.cannot_quote": "Does dim caniatâd i chi ddyfynnu'r postiad hwn", "status.cannot_reblog": "Does dim modd hybu'r postiad hwn", "status.contains_quote": "Yn cynnwys dyfyniad", + "status.context.loading": "Yn llwytho mwy o atebion", + "status.context.loading_error": "Wedi methu llwytho atebion newydd", + "status.context.loading_more": "Yn llwytho mwy o atebion", + "status.context.loading_success": "Wedi llwytho'r holl atebion", + "status.context.more_replies_found": "Mwy o atebion wedi'u canfod", + "status.context.retry": "Ceisio eto", + "status.context.show": "Dangos", "status.continued_thread": "Edefyn parhaus", "status.copy": "Copïo dolen i'r post", "status.delete": "Dileu", diff --git a/app/javascript/mastodon/locales/da.json b/app/javascript/mastodon/locales/da.json index b22190881f10aa..0180e2bf7eeff1 100644 --- a/app/javascript/mastodon/locales/da.json +++ b/app/javascript/mastodon/locales/da.json @@ -28,6 +28,7 @@ "account.disable_notifications": "Giv mig ikke længere en notifikation, når @{name} laver indlæg", "account.domain_blocking": "Blokerer domæne", "account.edit_profile": "Redigér profil", + "account.edit_profile_short": "Redigér", "account.enable_notifications": "Giv mig besked, når @{name} laver indlæg", "account.endorse": "Fremhæv på profil", "account.familiar_followers_many": "Følges af {name1}, {name2} og {othersCount, plural, one {# mere, man kender} other {# mere, du kender}}", @@ -40,6 +41,11 @@ "account.featured_tags.last_status_never": "Ingen indlæg", "account.follow": "Følg", "account.follow_back": "Følg tilbage", + "account.follow_back_short": "Følg tilbage", + "account.follow_request": "Anmod om at følge", + "account.follow_request_cancel": "Annuller anmodning", + "account.follow_request_cancel_short": "Annullér", + "account.follow_request_short": "Anmod", "account.followers": "Følgere", "account.followers.empty": "Ingen følger denne bruger endnu.", "account.followers_counter": "{count, plural, one {{counter} følger} other {{counter} følgere}}", @@ -70,7 +76,6 @@ "account.posts_with_replies": "Indlæg og svar", "account.remove_from_followers": "Fjern {name} fra følgere", "account.report": "Anmeld @{name}", - "account.requested": "Afventer godkendelse. Tryk for at annullere følgeanmodning", "account.requested_follow": "{name} har anmodet om at følge dig", "account.requests_to_follow_you": "Anmodninger om at følge dig", "account.share": "Del @{name}s profil", diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json index e756b6bab61a96..80c3820508e447 100644 --- a/app/javascript/mastodon/locales/de.json +++ b/app/javascript/mastodon/locales/de.json @@ -28,6 +28,7 @@ "account.disable_notifications": "Höre auf mich zu benachrichtigen wenn @{name} etwas postet", "account.domain_blocking": "Domain blockiert", "account.edit_profile": "Profil bearbeiten", + "account.edit_profile_short": "Bearbeiten", "account.enable_notifications": "Benachrichtige mich wenn @{name} etwas postet", "account.endorse": "Im Profil vorstellen", "account.familiar_followers_many": "Gefolgt von {name1}, {name2} und {othersCount, plural, one {einem weiteren Profil, das dir bekannt ist} other {# weiteren Profilen, die dir bekannt sind}}", @@ -40,6 +41,11 @@ "account.featured_tags.last_status_never": "Keine Beiträge", "account.follow": "Folgen", "account.follow_back": "Ebenfalls folgen", + "account.follow_back_short": "Ebenfalls folgen", + "account.follow_request": "Anfrage zum Folgen", + "account.follow_request_cancel": "Anfrage zurückziehen", + "account.follow_request_cancel_short": "Abbrechen", + "account.follow_request_short": "Anfragen", "account.followers": "Follower", "account.followers.empty": "Diesem Profil folgt noch niemand.", "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Follower}}", @@ -70,7 +76,6 @@ "account.posts_with_replies": "Beiträge und Antworten", "account.remove_from_followers": "{name} als Follower entfernen", "account.report": "@{name} melden", - "account.requested": "Die Genehmigung steht noch aus. Klicke hier, um die Follower-Anfrage zurückzuziehen", "account.requested_follow": "{name} möchte dir folgen", "account.requests_to_follow_you": "Möchte dir folgen", "account.share": "Profil von @{name} teilen", diff --git a/app/javascript/mastodon/locales/el.json b/app/javascript/mastodon/locales/el.json index 9b5479feeb0ed7..f52a480c900102 100644 --- a/app/javascript/mastodon/locales/el.json +++ b/app/javascript/mastodon/locales/el.json @@ -28,6 +28,7 @@ "account.disable_notifications": "Σταμάτα να με ειδοποιείς όταν δημοσιεύει ο @{name}", "account.domain_blocking": "Αποκλείεται ο τομέας", "account.edit_profile": "Επεξεργασία προφίλ", + "account.edit_profile_short": "Επεξεργασία", "account.enable_notifications": "Ειδοποίησέ με όταν δημοσιεύει ο @{name}", "account.endorse": "Προβολή στο προφίλ", "account.familiar_followers_many": "Ακολουθείται από {name1}, {name2}, και {othersCount, plural, one {ένας ακόμα που ξέρεις} other {# ακόμα που ξέρεις}}", @@ -40,6 +41,11 @@ "account.featured_tags.last_status_never": "Καμία ανάρτηση", "account.follow": "Ακολούθησε", "account.follow_back": "Ακολούθησε και εσύ", + "account.follow_back_short": "Ακολούθησε και εσύ", + "account.follow_request": "Αίτημα για ακολούθηση", + "account.follow_request_cancel": "Ακύρωση αιτήματος", + "account.follow_request_cancel_short": "Ακύρωση", + "account.follow_request_short": "Αίτημα", "account.followers": "Ακόλουθοι", "account.followers.empty": "Κανείς δεν ακολουθεί αυτόν τον χρήστη ακόμα.", "account.followers_counter": "{count, plural, one {{counter} ακόλουθος} other {{counter} ακόλουθοι}}", @@ -70,7 +76,6 @@ "account.posts_with_replies": "Τουτ και απαντήσεις", "account.remove_from_followers": "Κατάργηση {name} από τους ακόλουθους", "account.report": "Κατάγγειλε @{name}", - "account.requested": "Εκκρεμεί έγκριση. Κάνε κλικ για να ακυρώσεις το αίτημα παρακολούθησης", "account.requested_follow": "Ο/Η {name} αιτήθηκε να σε ακολουθήσει", "account.requests_to_follow_you": "Αιτήματα για να σε ακολουθήσουν", "account.share": "Κοινοποίηση του προφίλ @{name}", diff --git a/app/javascript/mastodon/locales/en-GB.json b/app/javascript/mastodon/locales/en-GB.json index 60f4e0d8f9d82d..bea3c988af11f6 100644 --- a/app/javascript/mastodon/locales/en-GB.json +++ b/app/javascript/mastodon/locales/en-GB.json @@ -70,7 +70,6 @@ "account.posts_with_replies": "Posts and replies", "account.remove_from_followers": "Remove {name} from followers", "account.report": "Report @{name}", - "account.requested": "Awaiting approval. Click to cancel follow request", "account.requested_follow": "{name} has requested to follow you", "account.requests_to_follow_you": "Requests to follow you", "account.share": "Share @{name}'s profile", diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json index c1d650e3a10d74..a1f21855287aca 100644 --- a/app/javascript/mastodon/locales/eo.json +++ b/app/javascript/mastodon/locales/eo.json @@ -69,7 +69,6 @@ "account.posts_with_replies": "Afiŝoj kaj respondoj", "account.remove_from_followers": "Forigi {name}-n de sekvantoj", "account.report": "Raporti @{name}", - "account.requested": "Atendo de aprobo. Klaku por nuligi la peton por sekvado", "account.requested_follow": "{name} petis sekvi vin", "account.requests_to_follow_you": "Petoj sekvi vin", "account.share": "Diskonigi la profilon de @{name}", diff --git a/app/javascript/mastodon/locales/es-AR.json b/app/javascript/mastodon/locales/es-AR.json index 3bd5172e13e869..8f49351a91e086 100644 --- a/app/javascript/mastodon/locales/es-AR.json +++ b/app/javascript/mastodon/locales/es-AR.json @@ -28,6 +28,7 @@ "account.disable_notifications": "Dejar de notificarme cuando @{name} envíe mensajes", "account.domain_blocking": "Dominio bloqueado", "account.edit_profile": "Editar perfil", + "account.edit_profile_short": "Editar", "account.enable_notifications": "Notificarme cuando @{name} envíe mensajes", "account.endorse": "Destacar en el perfil", "account.familiar_followers_many": "Seguido por {name1}, {name2} y {othersCount, plural, one {# cuenta más que conocés} other {# cuentas más que conocés}}", @@ -40,6 +41,11 @@ "account.featured_tags.last_status_never": "Sin mensajes", "account.follow": "Seguir", "account.follow_back": "Seguir", + "account.follow_back_short": "Seguir", + "account.follow_request": "Solicitud para seguir", + "account.follow_request_cancel": "Cancelar solicitud", + "account.follow_request_cancel_short": "Cancelar", + "account.follow_request_short": "Solicitar", "account.followers": "Seguidores", "account.followers.empty": "Todavía nadie sigue a este usuario.", "account.followers_counter": "{count, plural, one {{counter} seguidor} other {{counter} seguidores}}", @@ -70,7 +76,6 @@ "account.posts_with_replies": "Mnsjs y resp. públicas", "account.remove_from_followers": "Quitar a {name} de tus seguidores", "account.report": "Denunciar a @{name}", - "account.requested": "Esperando aprobación. Hacé clic para cancelar la solicitud de seguimiento", "account.requested_follow": "{name} solicitó seguirte", "account.requests_to_follow_you": "Solicita seguirte", "account.share": "Compartir el perfil de @{name}", diff --git a/app/javascript/mastodon/locales/es-MX.json b/app/javascript/mastodon/locales/es-MX.json index 9c37456a3e0ba2..d06d67c4d88b10 100644 --- a/app/javascript/mastodon/locales/es-MX.json +++ b/app/javascript/mastodon/locales/es-MX.json @@ -28,6 +28,7 @@ "account.disable_notifications": "Dejar de notificarme cuando @{name} publique algo", "account.domain_blocking": "Bloqueando dominio", "account.edit_profile": "Editar perfil", + "account.edit_profile_short": "Editar", "account.enable_notifications": "Notificarme cuando @{name} publique algo", "account.endorse": "Destacar en mi perfil", "account.familiar_followers_many": "Seguido por {name1}, {name2} y {othersCount, plural,one {# más que conoces}other {# más que conoces}}", @@ -40,6 +41,11 @@ "account.featured_tags.last_status_never": "Sin publicaciones", "account.follow": "Seguir", "account.follow_back": "Seguir también", + "account.follow_back_short": "Seguir también", + "account.follow_request": "Solicitud de seguimiento", + "account.follow_request_cancel": "Cancelar solicitud", + "account.follow_request_cancel_short": "Cancelar", + "account.follow_request_short": "Solicitar", "account.followers": "Seguidores", "account.followers.empty": "Nadie sigue a este usuario todavía.", "account.followers_counter": "{count, plural, one {{counter} seguidor} other {{counter} seguidores}}", @@ -70,7 +76,6 @@ "account.posts_with_replies": "Publicaciones y respuestas", "account.remove_from_followers": "Eliminar {name} de tus seguidores", "account.report": "Denunciar a @{name}", - "account.requested": "Esperando aprobación. Haz clic para cancelar la solicitud de seguimiento", "account.requested_follow": "{name} ha solicitado seguirte", "account.requests_to_follow_you": "Solicita seguirte", "account.share": "Compartir el perfil de @{name}", diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json index 67eda71cf95ad6..9d1f34c91bf2d8 100644 --- a/app/javascript/mastodon/locales/es.json +++ b/app/javascript/mastodon/locales/es.json @@ -28,6 +28,7 @@ "account.disable_notifications": "Dejar de notificarme cuando @{name} publique algo", "account.domain_blocking": "Bloqueando dominio", "account.edit_profile": "Editar perfil", + "account.edit_profile_short": "Editar", "account.enable_notifications": "Notificarme cuando @{name} publique algo", "account.endorse": "Destacar en el perfil", "account.familiar_followers_many": "Seguido por {name1}, {name2} y {othersCount, plural,one {# más que conoces}other {# más que conoces}}", @@ -40,6 +41,11 @@ "account.featured_tags.last_status_never": "Sin publicaciones", "account.follow": "Seguir", "account.follow_back": "Seguir también", + "account.follow_back_short": "Seguir también", + "account.follow_request": "Solicitud de seguimiento", + "account.follow_request_cancel": "Cancelar solicitud", + "account.follow_request_cancel_short": "Cancelar", + "account.follow_request_short": "Solicitar", "account.followers": "Seguidores", "account.followers.empty": "Todavía nadie sigue a este usuario.", "account.followers_counter": "{count, plural, one {{counter} seguidor} other {{counter} seguidores}}", @@ -70,7 +76,6 @@ "account.posts_with_replies": "Publicaciones y respuestas", "account.remove_from_followers": "Eliminar {name} de tus seguidores", "account.report": "Reportar a @{name}", - "account.requested": "Esperando aprobación. Haz clic para cancelar la solicitud de seguimiento", "account.requested_follow": "{name} ha solicitado seguirte", "account.requests_to_follow_you": "Solicita seguirte", "account.share": "Compartir el perfil de @{name}", diff --git a/app/javascript/mastodon/locales/et.json b/app/javascript/mastodon/locales/et.json index b6e02a0ba6225c..1811f7b939b1a6 100644 --- a/app/javascript/mastodon/locales/et.json +++ b/app/javascript/mastodon/locales/et.json @@ -28,6 +28,7 @@ "account.disable_notifications": "Peata teavitused @{name} postitustest", "account.domain_blocking": "Blokeeritud domeen", "account.edit_profile": "Muuda profiili", + "account.edit_profile_short": "Muuda", "account.enable_notifications": "Teavita mind @{name} postitustest", "account.endorse": "Too profiilil esile", "account.familiar_followers_many": "Jälgijateks {name1}, {name2} ja veel {othersCount, plural, one {üks kasutaja, keda tead} other {# kasutajat, keda tead}}", @@ -40,6 +41,11 @@ "account.featured_tags.last_status_never": "Postitusi pole", "account.follow": "Jälgi", "account.follow_back": "Jälgi vastu", + "account.follow_back_short": "Jälgi vastu", + "account.follow_request": "Jälgimispäring", + "account.follow_request_cancel": "Tühista päring", + "account.follow_request_cancel_short": "Katkesta", + "account.follow_request_short": "Koosta päring", "account.followers": "Jälgijad", "account.followers.empty": "Keegi ei jälgi veel seda kasutajat.", "account.followers_counter": "{count, plural, one {{counter} jälgija} other {{counter} jälgijat}}", @@ -70,7 +76,6 @@ "account.posts_with_replies": "Postitused ja vastused", "account.remove_from_followers": "Eemalda {name} jälgijate seast", "account.report": "Raporteeri @{name}", - "account.requested": "Ootab kinnitust. Klõpsa jälgimise soovi tühistamiseks", "account.requested_follow": "{name} on taodelnud sinu jälgimist", "account.requests_to_follow_you": "soovib sind jälgida", "account.share": "Jaga @{name} profiili", diff --git a/app/javascript/mastodon/locales/eu.json b/app/javascript/mastodon/locales/eu.json index 579701a525ec10..f4101a5ba0308a 100644 --- a/app/javascript/mastodon/locales/eu.json +++ b/app/javascript/mastodon/locales/eu.json @@ -70,7 +70,6 @@ "account.posts_with_replies": "Bidalketak eta erantzunak", "account.remove_from_followers": "Kendu {name} zure jarraitzaileengandik", "account.report": "Salatu @{name}", - "account.requested": "Onarpenaren zain. Egin klik jarraipen-eskaera ezeztatzeko", "account.requested_follow": "{name}-(e)k zu jarraitzeko eskaera egin du", "account.requests_to_follow_you": "Zu jarraitzeko eskaera egin du", "account.share": "Partekatu @{name} erabiltzailearen profila", diff --git a/app/javascript/mastodon/locales/fa.json b/app/javascript/mastodon/locales/fa.json index 64e3ec83d1d947..91afee6e241f20 100644 --- a/app/javascript/mastodon/locales/fa.json +++ b/app/javascript/mastodon/locales/fa.json @@ -70,7 +70,6 @@ "account.posts_with_replies": "فرسته‌ها و پاسخ‌ها", "account.remove_from_followers": "برداشتن {name} از پی‌گیران", "account.report": "گزارش ‎@{name}", - "account.requested": "منتظر پذیرش است. برای لغو درخواست پی‌گیری کلیک کنید", "account.requested_follow": "{name} درخواست پی‌گیریتان را داد", "account.requests_to_follow_you": "درخواست پی‌گیریتان را دارد", "account.share": "هم‌رسانی نمایهٔ ‎@{name}", diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json index aad79c9fe96e46..553727da959fcc 100644 --- a/app/javascript/mastodon/locales/fi.json +++ b/app/javascript/mastodon/locales/fi.json @@ -28,6 +28,7 @@ "account.disable_notifications": "Lopeta ilmoittamasta minulle, kun @{name} julkaisee", "account.domain_blocking": "Verkkotunnus estetty", "account.edit_profile": "Muokkaa profiilia", + "account.edit_profile_short": "Muokkaa", "account.enable_notifications": "Ilmoita minulle, kun @{name} julkaisee", "account.endorse": "Suosittele profiilissa", "account.familiar_followers_many": "Seuraajina {name1}, {name2} ja {othersCount, plural, one {1 muu, jonka tunnet} other {# muuta, jotka tunnet}}", @@ -40,6 +41,11 @@ "account.featured_tags.last_status_never": "Ei julkaisuja", "account.follow": "Seuraa", "account.follow_back": "Seuraa takaisin", + "account.follow_back_short": "Seuraa takaisin", + "account.follow_request": "Pyydä lupaa seurata", + "account.follow_request_cancel": "Peruuta pyyntö", + "account.follow_request_cancel_short": "Peruuta", + "account.follow_request_short": "Pyyntö", "account.followers": "Seuraajat", "account.followers.empty": "Kukaan ei seuraa tätä käyttäjää vielä.", "account.followers_counter": "{count, plural, one {{counter} seuraaja} other {{counter} seuraajaa}}", @@ -70,7 +76,6 @@ "account.posts_with_replies": "Julkaisut ja vastaukset", "account.remove_from_followers": "Poista {name} seuraajista", "account.report": "Raportoi @{name}", - "account.requested": "Odottaa hyväksyntää. Peruuta seurantapyyntö napsauttamalla", "account.requested_follow": "{name} on pyytänyt lupaa seurata sinua", "account.requests_to_follow_you": "Pyynnöt seurata sinua", "account.share": "Jaa käyttäjän @{name} profiili", diff --git a/app/javascript/mastodon/locales/fil.json b/app/javascript/mastodon/locales/fil.json index f8425dd8efd185..37db5a1b1596cb 100644 --- a/app/javascript/mastodon/locales/fil.json +++ b/app/javascript/mastodon/locales/fil.json @@ -60,7 +60,6 @@ "account.open_original_page": "Buksan ang pinagmulang pahina", "account.posts": "Mga post", "account.report": "I-ulat si/ang @{name}", - "account.requested": "Naghihintay ng pag-apruba. I-click upang ikansela ang hiling sa pagsunod", "account.requested_follow": "Hinihiling ni {name} na sundan ka", "account.share": "Ibahagi ang profile ni @{name}", "account.show_reblogs": "Ipakita ang mga pagpapalakas mula sa/kay {name}", diff --git a/app/javascript/mastodon/locales/fo.json b/app/javascript/mastodon/locales/fo.json index 938db30d7a87ae..7b956dc38a3d21 100644 --- a/app/javascript/mastodon/locales/fo.json +++ b/app/javascript/mastodon/locales/fo.json @@ -28,6 +28,7 @@ "account.disable_notifications": "Ikki boða mær frá, tá @{name} skrivar", "account.domain_blocking": "Banni økisnavn", "account.edit_profile": "Broyt vanga", + "account.edit_profile_short": "Rætta", "account.enable_notifications": "Boða mær frá, tá @{name} skrivar", "account.endorse": "Víst á vangamyndini", "account.familiar_followers_many": "{name1}, {name2} og {othersCount, plural, one {ein annar/onnur tú kennir} other {# onnur tú kennir}} fylgja", @@ -40,6 +41,11 @@ "account.featured_tags.last_status_never": "Einki uppslag", "account.follow": "Fylg", "account.follow_back": "Fylg aftur", + "account.follow_back_short": "Fylg aftur", + "account.follow_request": "Umbønir um at fylgja tær", + "account.follow_request_cancel": "Strika víðaribeining", + "account.follow_request_cancel_short": "Ógilda", + "account.follow_request_short": "Áheitan", "account.followers": "Fylgjarar", "account.followers.empty": "Ongar fylgjarar enn.", "account.followers_counter": "{count, plural, one {{counter} fylgjari} other {{counter} fylgjarar}}", @@ -70,7 +76,6 @@ "account.posts_with_replies": "Uppsløg og svar", "account.remove_from_followers": "Strika {name} av fylgjaralista", "account.report": "Melda @{name}", - "account.requested": "Bíðar eftir góðkenning. Trýst fyri at angra umbønina", "account.requested_follow": "{name} hevur biðið um at fylgja tær", "account.requests_to_follow_you": "Umbønir um at fylgja tær", "account.share": "Deil vanga @{name}'s", diff --git a/app/javascript/mastodon/locales/fr-CA.json b/app/javascript/mastodon/locales/fr-CA.json index 742d502fd58edb..81ea95a97499c1 100644 --- a/app/javascript/mastodon/locales/fr-CA.json +++ b/app/javascript/mastodon/locales/fr-CA.json @@ -70,7 +70,6 @@ "account.posts_with_replies": "Publications et réponses", "account.remove_from_followers": "Retirer {name} des suiveurs", "account.report": "Signaler @{name}", - "account.requested": "En attente d’approbation. Cliquez pour annuler la demande", "account.requested_follow": "{name} a demandé à vous suivre", "account.requests_to_follow_you": "Demande a vous suivre", "account.share": "Partager le profil de @{name}", diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json index 38a1215fd430af..4ecfcfab7fdcaa 100644 --- a/app/javascript/mastodon/locales/fr.json +++ b/app/javascript/mastodon/locales/fr.json @@ -70,7 +70,6 @@ "account.posts_with_replies": "Messages et réponses", "account.remove_from_followers": "Retirer {name} des suiveurs", "account.report": "Signaler @{name}", - "account.requested": "En attente d’approbation. Cliquez pour annuler la demande", "account.requested_follow": "{name} a demandé à vous suivre", "account.requests_to_follow_you": "Demande a vous suivre", "account.share": "Partager le profil de @{name}", diff --git a/app/javascript/mastodon/locales/fy.json b/app/javascript/mastodon/locales/fy.json index d0da2af6bb16c2..cb68231583e5af 100644 --- a/app/javascript/mastodon/locales/fy.json +++ b/app/javascript/mastodon/locales/fy.json @@ -70,7 +70,6 @@ "account.posts_with_replies": "Berjochten en reaksjes", "account.remove_from_followers": "{name} as folger fuortsmite", "account.report": "@{name} rapportearje", - "account.requested": "Wacht op goedkarring. Klik om it folchfersyk te annulearjen", "account.requested_follow": "{name} hat dy in folchfersyk stjoerd", "account.requests_to_follow_you": "Fersiken om jo te folgjen", "account.share": "Profyl fan @{name} diele", diff --git a/app/javascript/mastodon/locales/ga.json b/app/javascript/mastodon/locales/ga.json index 88d03ea43c1ac5..5a25ef9f47b079 100644 --- a/app/javascript/mastodon/locales/ga.json +++ b/app/javascript/mastodon/locales/ga.json @@ -28,6 +28,7 @@ "account.disable_notifications": "Éirigh as ag cuir mé in eol nuair bpostálann @{name}", "account.domain_blocking": "Fearann a bhlocáil", "account.edit_profile": "Cuir an phróifíl in eagar", + "account.edit_profile_short": "Cuir in Eagar", "account.enable_notifications": "Cuir mé in eol nuair bpostálann @{name}", "account.endorse": "Cuir ar an phróifíl mar ghné", "account.familiar_followers_many": "Ina dhiaidh sin ag {name1}, {name2}, agus {othersCount, plural, \n one {duine eile atá aithnid duit} \n two {# duine eile atá aithnid duit} \n few {# dhuine eile atá aithnid duit} \n many {# nduine eile atá aithnid duit} \n other {# duine eile atá aithnid duit}}", @@ -40,6 +41,11 @@ "account.featured_tags.last_status_never": "Gan aon phoist", "account.follow": "Lean", "account.follow_back": "Leanúint ar ais", + "account.follow_back_short": "Lean ar ais", + "account.follow_request": "Iarratas chun leanúint", + "account.follow_request_cancel": "Cealaigh an t-iarratas", + "account.follow_request_cancel_short": "Cealaigh", + "account.follow_request_short": "Iarratas", "account.followers": "Leantóirí", "account.followers.empty": "Ní leanann éinne an t-úsáideoir seo fós.", "account.followers_counter": "{count, plural, one {{counter} leantóir} other {{counter} leantóirí}}", @@ -70,7 +76,6 @@ "account.posts_with_replies": "Postálacha agus freagraí", "account.remove_from_followers": "Bain {name} de na leantóirí", "account.report": "Tuairiscigh @{name}", - "account.requested": "Ag fanacht le ceadú. Cliceáil chun an iarratas leanúnaí a chealú", "account.requested_follow": "D'iarr {name} ort do chuntas a leanúint", "account.requests_to_follow_you": "Iarratais chun tú a leanúint", "account.share": "Roinn próifíl @{name}", diff --git a/app/javascript/mastodon/locales/gd.json b/app/javascript/mastodon/locales/gd.json index 0b582c6fda9e18..4c3ab7d2a51b62 100644 --- a/app/javascript/mastodon/locales/gd.json +++ b/app/javascript/mastodon/locales/gd.json @@ -70,7 +70,6 @@ "account.posts_with_replies": "Postaichean ’s freagairtean", "account.remove_from_followers": "Thoir {name} air falbh on luchd-leantainn", "account.report": "Dèan gearan mu @{name}", - "account.requested": "A’ feitheamh air aontachadh. Briog airson sgur dhen iarrtas leantainn", "account.requested_follow": "Dh’iarr {name} ’gad leantainn", "account.requests_to_follow_you": "Iarrtasan leantainn", "account.share": "Co-roinn a’ phròifil aig @{name}", diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json index c724e3d9cf1e36..3f20dfb82d8996 100644 --- a/app/javascript/mastodon/locales/gl.json +++ b/app/javascript/mastodon/locales/gl.json @@ -28,6 +28,7 @@ "account.disable_notifications": "Deixar de notificarme cando @{name} publica", "account.domain_blocking": "Bloqueo do dominio", "account.edit_profile": "Editar perfil", + "account.edit_profile_short": "Editar", "account.enable_notifications": "Noficarme cando @{name} publique", "account.endorse": "Amosar no perfil", "account.familiar_followers_many": "Seguida por {name1}, {name2}, e {othersCount, plural, one {outra conta que coñeces} other {outras # contas que coñeces}}", @@ -40,6 +41,11 @@ "account.featured_tags.last_status_never": "Sen publicacións", "account.follow": "Seguir", "account.follow_back": "Seguir tamén", + "account.follow_back_short": "Seguir tamén", + "account.follow_request": "Solicitar seguir", + "account.follow_request_cancel": "Desbotar a petición", + "account.follow_request_cancel_short": "Desbotar", + "account.follow_request_short": "Solicitar", "account.followers": "Seguidoras", "account.followers.empty": "Aínda ninguén segue esta usuaria.", "account.followers_counter": "{count, plural, one {{counter} seguidora} other {{counter} seguidoras}}", @@ -70,7 +76,6 @@ "account.posts_with_replies": "Publicacións e respostas", "account.remove_from_followers": "Retirar a {name} das seguidoras", "account.report": "Informar sobre @{name}", - "account.requested": "Agardando aprobación. Preme para desbotar a solicitude", "account.requested_follow": "{name} solicitou seguirte", "account.requests_to_follow_you": "Solicita seguirte", "account.share": "Compartir o perfil de @{name}", diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json index 6adcc4b406c7e9..e7839cdea57023 100644 --- a/app/javascript/mastodon/locales/he.json +++ b/app/javascript/mastodon/locales/he.json @@ -28,6 +28,7 @@ "account.disable_notifications": "הפסק לשלוח לי התראות כש@{name} מפרסמים", "account.domain_blocking": "רשימת השרתים החסומים", "account.edit_profile": "עריכת פרופיל", + "account.edit_profile_short": "עריכה", "account.enable_notifications": "שלח לי התראות כש@{name} מפרסם", "account.endorse": "קדם את החשבון בפרופיל", "account.familiar_followers_many": "החשבון נעקב על ידי {name1}, {name2} ועוד {othersCount, plural,one {אחד נוסף שמוכר לך}other {# נוספים שמוכרים לך}}", @@ -40,6 +41,11 @@ "account.featured_tags.last_status_never": "אין חצרוצים", "account.follow": "לעקוב", "account.follow_back": "לעקוב בחזרה", + "account.follow_back_short": "לעקוב בחזרה", + "account.follow_request": "בקשה לעקוב אחרי", + "account.follow_request_cancel": "ביטול בקשה", + "account.follow_request_cancel_short": "ביטול", + "account.follow_request_short": "בקשה", "account.followers": "עוקבים", "account.followers.empty": "אף אחד לא עוקב אחר המשתמש הזה עדיין.", "account.followers_counter": "{count, plural,one {עוקב אחד} other {{counter} עוקבים}}", @@ -70,7 +76,6 @@ "account.posts_with_replies": "הודעות ותגובות", "account.remove_from_followers": "הסרת {name} מעוקבי", "account.report": "דווח על @{name}", - "account.requested": "בהמתנה לאישור. לחצי כדי לבטל בקשת מעקב", "account.requested_follow": "{name} ביקשו לעקוב אחריך", "account.requests_to_follow_you": "ביקשו לעקוב אחריך", "account.share": "שתף את הפרופיל של @{name}", diff --git a/app/javascript/mastodon/locales/hi.json b/app/javascript/mastodon/locales/hi.json index ca56ad484e2057..bc71c80068c5c0 100644 --- a/app/javascript/mastodon/locales/hi.json +++ b/app/javascript/mastodon/locales/hi.json @@ -52,7 +52,6 @@ "account.posts": "टूट्स", "account.posts_with_replies": "टूट्स एवं जवाब", "account.report": "रिपोर्ट @{name}", - "account.requested": "मंजूरी का इंतजार। फॉलो रिक्वेस्ट को रद्द करने के लिए क्लिक करें", "account.requested_follow": "{name} ने आपको फॉलो करने के लिए अनुरोध किया है", "account.share": "@{name} की प्रोफाइल शेयर करे", "account.show_reblogs": "@{name} के बूस्ट दिखाए", diff --git a/app/javascript/mastodon/locales/hr.json b/app/javascript/mastodon/locales/hr.json index cb3f25de0699fe..0cde3da84b4043 100644 --- a/app/javascript/mastodon/locales/hr.json +++ b/app/javascript/mastodon/locales/hr.json @@ -51,7 +51,6 @@ "account.posts": "Objave", "account.posts_with_replies": "Objave i odgovori", "account.report": "Prijavi @{name}", - "account.requested": "Čekanje na potvrdu. Kliknite za poništavanje zahtjeva za praćenje", "account.requested_follow": "{name} zatražio/la je praćenje", "account.share": "Podijeli profil @{name}", "account.show_reblogs": "Prikaži boostove od @{name}", diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json index 80693f586e3a7a..1d3764e8e895b6 100644 --- a/app/javascript/mastodon/locales/hu.json +++ b/app/javascript/mastodon/locales/hu.json @@ -70,7 +70,6 @@ "account.posts_with_replies": "Bejegyzések és válaszok", "account.remove_from_followers": "{name} eltávolítása a követők közül", "account.report": "@{name} jelentése", - "account.requested": "Jóváhagyásra vár. Kattints a követési kérés visszavonásához", "account.requested_follow": "{name} kérte, hogy követhessen", "account.requests_to_follow_you": "Kéri, hogy követhessen", "account.share": "@{name} profiljának megosztása", diff --git a/app/javascript/mastodon/locales/hy.json b/app/javascript/mastodon/locales/hy.json index 62669eda9b5d20..bd9fd71c2392bf 100644 --- a/app/javascript/mastodon/locales/hy.json +++ b/app/javascript/mastodon/locales/hy.json @@ -43,7 +43,6 @@ "account.posts": "Գրառումներ", "account.posts_with_replies": "Գրառումներ եւ պատասխաններ", "account.report": "Բողոքել @{name}֊ի մասին", - "account.requested": "Հաստատման կարիք ունի։ Սեղմիր՝ հետեւելու հայցը չեղարկելու համար։", "account.requested_follow": "{name}-ը ցանկանում է հետեւել քեզ", "account.share": "Կիսուել @{name}֊ի էջով", "account.show_reblogs": "Ցուցադրել @{name}֊ի տարածածները", diff --git a/app/javascript/mastodon/locales/ia.json b/app/javascript/mastodon/locales/ia.json index 9b3c8f8ed48555..f9325b623cbf75 100644 --- a/app/javascript/mastodon/locales/ia.json +++ b/app/javascript/mastodon/locales/ia.json @@ -28,6 +28,7 @@ "account.disable_notifications": "Non plus notificar me quando @{name} publica", "account.domain_blocking": "Dominio blocate", "account.edit_profile": "Modificar profilo", + "account.edit_profile_short": "Modificar", "account.enable_notifications": "Notificar me quando @{name} publica", "account.endorse": "Evidentiar sur le profilo", "account.familiar_followers_many": "Sequite per {name1}, {name2}, e {othersCount, plural, one {un altere que tu cognosce} other {# alteres que tu cognosce}}", @@ -40,6 +41,11 @@ "account.featured_tags.last_status_never": "Necun message", "account.follow": "Sequer", "account.follow_back": "Sequer in retorno", + "account.follow_back_short": "Sequer in retorno", + "account.follow_request": "Requestar de sequer", + "account.follow_request_cancel": "Cancellar requesta", + "account.follow_request_cancel_short": "Cancellar", + "account.follow_request_short": "Requesta", "account.followers": "Sequitores", "account.followers.empty": "Necuno seque ancora iste usator.", "account.followers_counter": "{count, plural, one {{counter} sequitor} other {{counter} sequitores}}", @@ -70,7 +76,6 @@ "account.posts_with_replies": "Messages e responsas", "account.remove_from_followers": "Remover {name} del sequitores", "account.report": "Reportar @{name}", - "account.requested": "Attendente le approbation. Clicca pro cancellar le requesta de sequer", "account.requested_follow": "{name} ha requestate de sequer te", "account.requests_to_follow_you": "Requestas de sequer te", "account.share": "Compartir profilo de @{name}", diff --git a/app/javascript/mastodon/locales/id.json b/app/javascript/mastodon/locales/id.json index 7c5c816c67dde4..253a9d93c41365 100644 --- a/app/javascript/mastodon/locales/id.json +++ b/app/javascript/mastodon/locales/id.json @@ -64,7 +64,6 @@ "account.posts": "Kiriman", "account.posts_with_replies": "Kiriman dan balasan", "account.report": "Laporkan @{name}", - "account.requested": "Menunggu persetujuan. Klik untuk membatalkan permintaan", "account.requested_follow": "{name} ingin mengikuti Anda", "account.share": "Bagikan profil @{name}", "account.show_reblogs": "Tampilkan boost dari @{name}", diff --git a/app/javascript/mastodon/locales/ie.json b/app/javascript/mastodon/locales/ie.json index 4a464ef16e2e0c..bbb85ee2ad1068 100644 --- a/app/javascript/mastodon/locales/ie.json +++ b/app/javascript/mastodon/locales/ie.json @@ -52,7 +52,6 @@ "account.posts": "Postas", "account.posts_with_replies": "Postas e replicas", "account.report": "Raportar @{name}", - "account.requested": "Atendent aprobation. Cliccar por anullar li petition de sequer", "account.requested_follow": "{name} ha petit sequer te", "account.share": "Distribuer li profil de @{name}", "account.show_reblogs": "Monstrar boosts de @{name}", diff --git a/app/javascript/mastodon/locales/io.json b/app/javascript/mastodon/locales/io.json index b51d32d05a772d..15c10af863ed0b 100644 --- a/app/javascript/mastodon/locales/io.json +++ b/app/javascript/mastodon/locales/io.json @@ -55,7 +55,6 @@ "account.posts": "Mesaji", "account.posts_with_replies": "Afishi e respondi", "account.report": "Denuncar @{name}", - "account.requested": "Vartante aprobo", "account.requested_follow": "{name} demandis sequar tu", "account.share": "Partigez profilo di @{name}", "account.show_reblogs": "Montrez repeti de @{name}", diff --git a/app/javascript/mastodon/locales/is.json b/app/javascript/mastodon/locales/is.json index 92bae015319096..012b3c313e0fd4 100644 --- a/app/javascript/mastodon/locales/is.json +++ b/app/javascript/mastodon/locales/is.json @@ -28,6 +28,7 @@ "account.disable_notifications": "Hætta að láta mig vita þegar @{name} sendir inn", "account.domain_blocking": "Útiloka lén", "account.edit_profile": "Breyta notandasniði", + "account.edit_profile_short": "Breyta", "account.enable_notifications": "Láta mig vita þegar @{name} sendir inn", "account.endorse": "Birta á notandasniði", "account.familiar_followers_many": "Fylgt af {name1}, {name2} og {othersCount, plural, one {einum öðrum sem þú þekkir} other {# öðrum sem þú þekkir}}", @@ -40,6 +41,11 @@ "account.featured_tags.last_status_never": "Engar færslur", "account.follow": "Fylgjast með", "account.follow_back": "Fylgjast með til baka", + "account.follow_back_short": "Fylgjast með til baka", + "account.follow_request": "Beiðni um að fylgjast með", + "account.follow_request_cancel": "Hætta við beiðni", + "account.follow_request_cancel_short": "Hætta við", + "account.follow_request_short": "Beiðni", "account.followers": "Fylgjendur", "account.followers.empty": "Ennþá fylgist enginn með þessum notanda.", "account.followers_counter": "{count, plural, one {Fylgjandi: {counter}} other {Fylgjendur: {counter}}}", @@ -70,7 +76,6 @@ "account.posts_with_replies": "Færslur og svör", "account.remove_from_followers": "Fjarlægja {name} úr fylgjendum", "account.report": "Kæra @{name}", - "account.requested": "Bíður eftir samþykki. Smelltu til að hætta við beiðni um að fylgjast með", "account.requested_follow": "{name} hefur beðið um að fylgjast með þér", "account.requests_to_follow_you": "Bað um að fylgjast með þér", "account.share": "Deila notandasniði fyrir @{name}", @@ -864,6 +869,14 @@ "status.cancel_reblog_private": "Taka úr endurbirtingu", "status.cannot_quote": "Þú hefur ekki heimild til að vitna í þessa færslu", "status.cannot_reblog": "Þessa færslu er ekki hægt að endurbirta", + "status.contains_quote": "Inniheldur tilvitnun", + "status.context.loading": "Hleð inn fleiri svörum", + "status.context.loading_error": "Gat ekki hlaðið inn nýjum svörum", + "status.context.loading_more": "Hleð inn fleiri svörum", + "status.context.loading_success": "Öllum svörum hlaðið inn", + "status.context.more_replies_found": "Fleiri svör fundust", + "status.context.retry": "Reyna aftur", + "status.context.show": "Sýna", "status.continued_thread": "Hélt samtali áfram", "status.copy": "Afrita tengil í færslu", "status.delete": "Eyða", @@ -893,12 +906,15 @@ "status.quote": "Tilvitnun", "status.quote.cancel": "Hætta við tilvitnun", "status.quote_error.filtered": "Falið vegna einnar síu sem er virk", + "status.quote_error.limited_account_hint.action": "Birta samt", + "status.quote_error.limited_account_hint.title": "Þessi notandaaðgangur hefur verið falinn af stjórnendum á {domain}.", "status.quote_error.not_available": "Færsla ekki tiltæk", "status.quote_error.pending_approval": "Færsla í bið", "status.quote_error.pending_approval_popout.body": "Á Mastodon geturðu stjórnað því hvort aðrir geti vitnað í þig. Þessi færsla bíður eftir samþykki upprunalegs höfundar.", "status.quote_error.revoked": "Færsla fjarlægð af höfundi", "status.quote_followers_only": "Einungis fylgjendur geta vitnað í þessa færslu", "status.quote_manual_review": "Höfundur mun yfirfara handvirkt", + "status.quote_noun": "Tilvitnun", "status.quote_policy_change": "Breyttu því hver getur tilvitnað", "status.quote_post_author": "Vitnaði í færslu frá @{name}", "status.quote_private": "Ekki er hægt að vitna í einkafærslur", @@ -990,7 +1006,7 @@ "visibility_modal.helper.privacy_private_self_quote": "Tilvitnanir í sjálfan sig úr einkaspjallfærslum er ekki hægt að gera opinberar.", "visibility_modal.helper.private_quoting": "Ekki er hægt að vitna í færslur einungis til fylgjenda sem skrifaðar eru á Mastodon.", "visibility_modal.helper.unlisted_quoting": "Þegar fólk vitnar í þig verða færslurnar þeirr einnig faldar á vinsældatímalínum.", - "visibility_modal.instructions": ". Stýrðu því hverjir geta átt við þessa færslu. Þú getur líka ákvarðað stillingar fyrir allar færslur í framtíðinni með því að fara í Kjörstillingar > Sjálfgefin gildi við gerð færslna.", + "visibility_modal.instructions": "Stýrðu því hverjir geta átt við þessa færslu. Þú getur líka ákvarðað stillingar fyrir allar færslur í framtíðinni með því að fara í Kjörstillingar > Sjálfgefin gildi við gerð færslna.", "visibility_modal.privacy_label": "Sýnileiki", "visibility_modal.quote_followers": "Einungis fylgjendur", "visibility_modal.quote_label": "Hverjir geta gert tilvitnanir", diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json index 3dde3f5775c4e6..aa5f47a4c14a2f 100644 --- a/app/javascript/mastodon/locales/it.json +++ b/app/javascript/mastodon/locales/it.json @@ -70,7 +70,6 @@ "account.posts_with_replies": "Post e risposte", "account.remove_from_followers": "Rimuovi {name} dai seguaci", "account.report": "Segnala @{name}", - "account.requested": "In attesa d'approvazione. Clicca per annullare la richiesta di seguire", "account.requested_follow": "{name} ha richiesto di seguirti", "account.requests_to_follow_you": "Richieste di seguirti", "account.share": "Condividi il profilo di @{name}", diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json index 22377dc7867462..6acfbac133b9f8 100644 --- a/app/javascript/mastodon/locales/ja.json +++ b/app/javascript/mastodon/locales/ja.json @@ -70,7 +70,6 @@ "account.posts_with_replies": "投稿と返信", "account.remove_from_followers": "{name}さんをフォロワーから削除", "account.report": "@{name}さんを通報", - "account.requested": "フォロー承認待ちです。クリックしてキャンセル", "account.requested_follow": "{name}さんがあなたにフォローリクエストしました", "account.requests_to_follow_you": "フォローリクエスト", "account.share": "@{name}さんのプロフィールを共有する", diff --git a/app/javascript/mastodon/locales/ka.json b/app/javascript/mastodon/locales/ka.json index ea7375fd00be70..a6a3758a0bd4de 100644 --- a/app/javascript/mastodon/locales/ka.json +++ b/app/javascript/mastodon/locales/ka.json @@ -21,7 +21,6 @@ "account.posts": "პოსტები", "account.posts_with_replies": "ტუტები და პასუხები", "account.report": "დაარეპორტე @{name}", - "account.requested": "დამტკიცების მოლოდინში. დააწკაპუნეთ რომ უარყოთ დადევნების მოთხონვა", "account.share": "გააზიარე @{name}-ის პროფილი", "account.show_reblogs": "აჩვენე ბუსტები @{name}-სგან", "account.unblock": "განბლოკე @{name}", diff --git a/app/javascript/mastodon/locales/kab.json b/app/javascript/mastodon/locales/kab.json index f14f3b5c701ec7..d508320d3b0a73 100644 --- a/app/javascript/mastodon/locales/kab.json +++ b/app/javascript/mastodon/locales/kab.json @@ -63,7 +63,6 @@ "account.posts_with_replies": "Tisuffaɣ d tririyin", "account.remove_from_followers": "Kkes {name} seg ineḍfaren", "account.report": "Cetki ɣef @{name}", - "account.requested": "Di laɛḍil ad yettwaqbel. Ssit i wakken ad yefsex usuter n uḍfar", "account.requested_follow": "{name} yessuter ad k·m-yeḍfer", "account.share": "Bḍu amaɣnu n @{name}", "account.show_reblogs": "Ssken-d inebḍa n @{name}", @@ -267,6 +266,7 @@ "explore.trending_links": "Isallen", "explore.trending_statuses": "Tisuffaɣ", "explore.trending_tags": "Ihacṭagen", + "featured_carousel.header": "{count, plural, one {n tsuffeɣt tunṭiḍt} other {n tsuffaɣ tunṭiḍin}}", "featured_carousel.next": "Uḍfiṛ", "featured_carousel.post": "Tasuffeɣt", "featured_carousel.previous": "Uzwir", @@ -352,6 +352,7 @@ "keyboard_shortcuts.direct": "to open direct messages column", "keyboard_shortcuts.down": "i kennu ɣer wadda n tebdart", "keyboard_shortcuts.enter": "i tildin n tsuffeɣt", + "keyboard_shortcuts.favourite": "Smenyef tassuɣeft", "keyboard_shortcuts.favourites": "Ldi tabdert n yismenyifen", "keyboard_shortcuts.federated": "i tildin n tsuddemt tamatut n yisallen", "keyboard_shortcuts.heading": "Inegzumen n unasiw", @@ -364,8 +365,9 @@ "keyboard_shortcuts.my_profile": "akken ad d-teldiḍ amaɣnu-ik", "keyboard_shortcuts.notifications": "Ad d-yeldi ajgu n yilɣa", "keyboard_shortcuts.open_media": "i tiɣwalin yeldin", - "keyboard_shortcuts.pinned": "akken ad teldiḍ tabdart n tjewwiqin yettwasentḍen", + "keyboard_shortcuts.pinned": "akken ad teldiḍ tabdart n tsuffaɣ tunṭiḍin", "keyboard_shortcuts.profile": "akken ad d-teldiḍ amaɣnu n umeskar", + "keyboard_shortcuts.quote": "Tanebdurt n tsuffeɣt", "keyboard_shortcuts.reply": "i tririt", "keyboard_shortcuts.requests": "akken ad d-teldiḍ tabdert n yisuturen n teḍfeṛt", "keyboard_shortcuts.search": "to focus search", @@ -444,6 +446,7 @@ "navigation_bar.privacy_and_reach": "Tabḍnit akked wagwaḍ", "navigation_bar.search": "Nadi", "navigation_bar.search_trends": "Anadi / Anezzuɣ", + "navigation_panel.collapse_lists": "Sneḍfes umuɣ n tebdart", "not_signed_in_indicator.not_signed_in": "You need to sign in to access this resource.", "notification.admin.report": "Yemla-t-id {name} {target}", "notification.admin.sign_up": "Ijerred {name}", @@ -464,6 +467,7 @@ "notification.moderation_warning.action_suspend": "Yettwaseḥbes umiḍan-ik.", "notification.own_poll": "Tafrant-ik·im tfuk", "notification.reblog": "{name} yebḍa tajewwiqt-ik i tikelt-nniḍen", + "notification.reblog.name_and_others_with_link": "{name} akked {count, plural, one {# nnayeḍ} other {# nniḍen}} zzuzren tasuffeɣt-ik·im", "notification.relationships_severance_event.learn_more": "Issin ugar", "notification.status": "{name} akken i d-yessufeɣ", "notification_requests.accept": "Qbel", @@ -555,6 +559,8 @@ "regeneration_indicator.please_stand_by": "Ttxil rǧu.", "regeneration_indicator.preparing_your_home_feed": "Ha-tt-an tsuddemt-ik·im tagejdant tettwaheggay…", "relative_time.days": "{number}u", + "relative_time.full.days": "{number, plural, one {# n wass} other {# n wussan}} aya", + "relative_time.full.hours": "{number, plural, one {# n usrag} other {# n yesragen}} aya", "relative_time.full.just_now": "tura kan", "relative_time.hours": "{number}isr", "relative_time.just_now": "tura", @@ -562,6 +568,7 @@ "relative_time.seconds": "{number}tas", "relative_time.today": "ass-a", "remove_quote_hint.button_label": "Gziɣ-t", + "remove_quote_hint.title": "D tidet, tebɣiḍ ad tekkseḍ tasuffeɣt-inek·inem i d-yettwabedren?", "reply_indicator.attachments": "{count, plural, one {# n umedday} other {# n imeddayen}}", "reply_indicator.cancel": "Sefsex", "reply_indicator.poll": "Afmiḍi", @@ -630,6 +637,7 @@ "search_results.title": "Igemmaḍ n unadi ɣef \"{q}\"", "server_banner.active_users": "iseqdacen urmiden", "server_banner.administered_by": "Yettwadbel sɣur :", + "server_banner.is_one_of_many": "{domain} d yiwen seg seg waṭṭas n iqeddacen imzurag n Mastodon i tzemreḍ ad tsqesdceḍ i wakken ad tettekkiḍ deg fediverse.", "server_banner.server_stats": "Tidaddanin n uqeddac:", "sign_in_banner.create_account": "Snulfu-d amiḍan", "sign_in_banner.sign_in": "Qqen", @@ -639,6 +647,8 @@ "status.bookmark": "Creḍ", "status.cancel_reblog_private": "Sefsex beṭṭu", "status.cannot_reblog": "Tasuffeɣt-a ur tezmir ara ad tettwabḍu tikelt-nniḍen", + "status.context.retry": "Ɛreḍ tikkelt nniḍen", + "status.context.show": "Sken-d", "status.continued_thread": "Asqerdec yettkemmil", "status.copy": "Nɣel assaɣ ɣer tasuffeɣt", "status.delete": "Kkes", @@ -667,7 +677,10 @@ "status.quote": "Tanebdurt", "status.quote.cancel": "Semmet tanebdurt", "status.quote_error.limited_account_hint.action": "Sken-d akken ibɣu yili", + "status.quote_error.not_available": "Tasuffeɣt-a ulac-itt", "status.quote_error.revoked": "Tasuffeɣt-a yekkes-itt umeskar-is", + "status.quote_noun": "Tanebdurt", + "status.quote_policy_change": "Snifel anwa i izemren ad d-yebder", "status.quote_post_author": "Yebder-d tasuffeɣt sɣur @{name}", "status.read_more": "Issin ugar", "status.reblog": "Bḍu", diff --git a/app/javascript/mastodon/locales/kk.json b/app/javascript/mastodon/locales/kk.json index b04790d9a1200f..c549bddd3f20df 100644 --- a/app/javascript/mastodon/locales/kk.json +++ b/app/javascript/mastodon/locales/kk.json @@ -65,7 +65,6 @@ "account.posts_with_replies": "Постар мен жауаптар", "account.remove_from_followers": "{name} жазылушылардан жою", "account.report": "Шағымдану @{name}", - "account.requested": "Растауын күтіңіз. Жазылудан бас тарту үшін басыңыз", "account.requested_follow": "{name} сізге жазылуға сұраныс жіберді", "account.requests_to_follow_you": "Сізге жазылу сұраныстары", "account.share": "@{name} профилін бөлісу\"", diff --git a/app/javascript/mastodon/locales/kn.json b/app/javascript/mastodon/locales/kn.json index ae4e4dd7b33326..1d383c6b276510 100644 --- a/app/javascript/mastodon/locales/kn.json +++ b/app/javascript/mastodon/locales/kn.json @@ -13,7 +13,6 @@ "account.followers": "ಹಿಂಬಾಲಕರು", "account.posts": "ಟೂಟ್‌ಗಳು", "account.posts_with_replies": "Toots and replies", - "account.requested": "Awaiting approval", "account.unblock_domain": "Unhide {domain}", "account_note.placeholder": "Click to add a note", "alert.unexpected.title": "ಅಯ್ಯೋ!", diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json index 89137643f3f9ef..0a200369070a61 100644 --- a/app/javascript/mastodon/locales/ko.json +++ b/app/javascript/mastodon/locales/ko.json @@ -70,7 +70,6 @@ "account.posts_with_replies": "게시물과 답장", "account.remove_from_followers": "팔로워에서 {name} 제거", "account.report": "@{name} 신고", - "account.requested": "승인 대기 중. 클릭해서 취소하기", "account.requested_follow": "{name} 님이 팔로우 요청을 보냈습니다", "account.requests_to_follow_you": "팔로우 요청", "account.share": "@{name}의 프로필 공유", diff --git a/app/javascript/mastodon/locales/ku.json b/app/javascript/mastodon/locales/ku.json index 3518959e2b4c0f..a6a9a8f1e0288f 100644 --- a/app/javascript/mastodon/locales/ku.json +++ b/app/javascript/mastodon/locales/ku.json @@ -58,7 +58,6 @@ "account.posts": "Şandî", "account.posts_with_replies": "Şandî û bersiv", "account.report": "@{name} ragihîne", - "account.requested": "Li benda erêkirinê ye. Ji bo betal kirina daxwazê pêl bikin", "account.requested_follow": "{name} dixwaze te bişopîne", "account.share": "Profîla @{name} parve bike", "account.show_reblogs": "Bilindkirinên ji @{name} nîşan bike", diff --git a/app/javascript/mastodon/locales/kw.json b/app/javascript/mastodon/locales/kw.json index b1116a7a317c81..6af6652a54418a 100644 --- a/app/javascript/mastodon/locales/kw.json +++ b/app/javascript/mastodon/locales/kw.json @@ -25,7 +25,6 @@ "account.posts": "Postow", "account.posts_with_replies": "Postow ha gorthebow", "account.report": "Reportya @{name}", - "account.requested": "Ow kortos komendyans. Klyckyewgh dhe hedhi govyn holya", "account.share": "Kevrenna profil @{name}", "account.show_reblogs": "Diskwedhes kenerthow a @{name}", "account.unblock": "Anlettya @{name}", diff --git a/app/javascript/mastodon/locales/lad.json b/app/javascript/mastodon/locales/lad.json index 754f6eb3c6b190..d8d0a06718dbe6 100644 --- a/app/javascript/mastodon/locales/lad.json +++ b/app/javascript/mastodon/locales/lad.json @@ -63,7 +63,6 @@ "account.posts": "Publikasyones", "account.posts_with_replies": "Kon repuestas", "account.report": "Raporta @{name}", - "account.requested": "Asperando achetasion. Klika para anular la solisitud de segimiento", "account.requested_follow": "{name} tiene solisitado segirte", "account.requests_to_follow_you": "Solisita segirte", "account.share": "Partaja el profil de @{name}", diff --git a/app/javascript/mastodon/locales/lt.json b/app/javascript/mastodon/locales/lt.json index 5f4d357f0d2217..f02af533fdc8f9 100644 --- a/app/javascript/mastodon/locales/lt.json +++ b/app/javascript/mastodon/locales/lt.json @@ -64,7 +64,6 @@ "account.posts_with_replies": "Įrašai ir atsakymai", "account.remove_from_followers": "Šalinti {name} iš sekėjų", "account.report": "Pranešti apie @{name}", - "account.requested": "Laukiama patvirtinimo. Spustelėk, kad atšauktum sekimo prašymą", "account.requested_follow": "{name} paprašė tave sekti", "account.requests_to_follow_you": "Prašymai sekti jus", "account.share": "Bendrinti @{name} profilį", diff --git a/app/javascript/mastodon/locales/lv.json b/app/javascript/mastodon/locales/lv.json index ff532bb295c643..eb0a6cbe8a1817 100644 --- a/app/javascript/mastodon/locales/lv.json +++ b/app/javascript/mastodon/locales/lv.json @@ -70,7 +70,6 @@ "account.posts_with_replies": "Ieraksti un atbildes", "account.remove_from_followers": "Dzēst sekotāju {name}", "account.report": "Ziņot par @{name}", - "account.requested": "Gaida apstiprinājumu. Nospied, lai atceltu sekošanas pieparasījumu", "account.requested_follow": "{name} nosūtīja Tev sekošanas pieprasījumu", "account.requests_to_follow_you": "Sekošanas pieprasījumi", "account.share": "Dalīties ar @{name} profilu", diff --git a/app/javascript/mastodon/locales/mk.json b/app/javascript/mastodon/locales/mk.json index 67e561dceefd20..83153d4d73a3ac 100644 --- a/app/javascript/mastodon/locales/mk.json +++ b/app/javascript/mastodon/locales/mk.json @@ -33,7 +33,6 @@ "account.posts": "Тутови", "account.posts_with_replies": "Тутови и реплики", "account.report": "Пријави @{name}", - "account.requested": "Се чека одобрување. Кликни за да одкажиш барање за следење", "account.share": "Сподели @{name} профил", "account.show_reblogs": "Прикажи бустови од @{name}", "account.unblock": "Одблокирај @{name}", diff --git a/app/javascript/mastodon/locales/ml.json b/app/javascript/mastodon/locales/ml.json index 63fc97c8abb85e..16c183b4924d74 100644 --- a/app/javascript/mastodon/locales/ml.json +++ b/app/javascript/mastodon/locales/ml.json @@ -44,7 +44,6 @@ "account.posts": "പോസ്റ്റുകൾ", "account.posts_with_replies": "പോസ്റ്റുകളും മറുപടികളും", "account.report": "റിപ്പോർട്ട് ചെയ്യുക @{name}", - "account.requested": "അനുവാദത്തിനായി കാത്തിരിക്കുന്നു. പിന്തുടരാനുള്ള അപേക്ഷ റദ്ദാക്കുവാൻ ഞെക്കുക", "account.share": "@{name} ന്റെ പ്രൊഫൈൽ പങ്കിടുക", "account.show_reblogs": "@{name} ൽ നിന്നുള്ള ബൂസ്റ്റുകൾ കാണിക്കുക", "account.unblock": "@{name} തടഞ്ഞത് മാറ്റുക", diff --git a/app/javascript/mastodon/locales/mr.json b/app/javascript/mastodon/locales/mr.json index 28d3ae9ab37a64..6a762c15273a56 100644 --- a/app/javascript/mastodon/locales/mr.json +++ b/app/javascript/mastodon/locales/mr.json @@ -49,7 +49,6 @@ "account.posts": "Toots", "account.posts_with_replies": "Toots and replies", "account.report": "@{name} ची तक्रार करा", - "account.requested": "Awaiting approval", "account.requested_follow": "{name} ने आपल्याला फॉलो करण्याची रिक्वेस्ट केली आहे", "account.share": "@{name} चे प्रोफाइल शेअर करा", "account.show_reblogs": "{name}चे सर्व बुस्ट्स दाखवा", diff --git a/app/javascript/mastodon/locales/ms.json b/app/javascript/mastodon/locales/ms.json index 2ffdf6cfd0b4bf..da72a2fc14d6b1 100644 --- a/app/javascript/mastodon/locales/ms.json +++ b/app/javascript/mastodon/locales/ms.json @@ -58,7 +58,6 @@ "account.posts": "Hantaran", "account.posts_with_replies": "Hantaran dan balasan", "account.report": "Laporkan @{name}", - "account.requested": "Menunggu kelulusan. Klik untuk batalkan permintaan ikut", "account.requested_follow": "{name} has requested to follow you", "account.share": "Kongsi profil @{name}", "account.show_reblogs": "Tunjukkan galakan daripada @{name}", diff --git a/app/javascript/mastodon/locales/my.json b/app/javascript/mastodon/locales/my.json index a65eab5aa708cd..66af87dc62c0ce 100644 --- a/app/javascript/mastodon/locales/my.json +++ b/app/javascript/mastodon/locales/my.json @@ -51,7 +51,6 @@ "account.posts": "ပို့စ်များ", "account.posts_with_replies": "ပို့စ်နှင့် ရီပလိုင်းများ", "account.report": "တိုင်ကြားမည်{name}", - "account.requested": "ခွင့်ပြုချက်စောင့်နေသည်။ ဖော်လိုးပယ်ဖျက်ရန်နှိပ်ပါ", "account.requested_follow": "{name} က သင့်ကို စောင့်ကြည့်ရန် တောင်းဆိုထားသည်", "account.share": "{name}၏ပရိုဖိုင်ကိုမျှဝေပါ", "account.show_reblogs": "@{name} မှ မျှ၀ေမှုများကို ပြပါ\n", diff --git a/app/javascript/mastodon/locales/nan.json b/app/javascript/mastodon/locales/nan.json index b070566564b771..0ee1958d5bb86e 100644 --- a/app/javascript/mastodon/locales/nan.json +++ b/app/javascript/mastodon/locales/nan.json @@ -28,6 +28,7 @@ "account.disable_notifications": "停止佇 {name} PO文ê時通知我", "account.domain_blocking": "Teh封鎖ê網域", "account.edit_profile": "編輯個人資料", + "account.edit_profile_short": "編輯", "account.enable_notifications": "佇 {name} PO文ê時通知我", "account.endorse": "用個人資料推薦對方", "account.familiar_followers_many": "Hōo {name1}、{name2},kap {othersCount, plural, other {其他 lí熟似ê # ê lâng}} 跟tuè", @@ -40,6 +41,11 @@ "account.featured_tags.last_status_never": "無PO文", "account.follow": "跟tuè", "account.follow_back": "Tuè tńg去", + "account.follow_back_short": "Tuè tńg去", + "account.follow_request": "請求跟tuè lí", + "account.follow_request_cancel": "取消跟tuè", + "account.follow_request_cancel_short": "取消", + "account.follow_request_short": "請求", "account.followers": "跟tuè lí ê", "account.followers.empty": "Tsit ê用者iáu bô lâng跟tuè。", "account.followers_counter": "Hōo {count, plural, other {{count} ê lâng}}跟tuè", @@ -70,7 +76,6 @@ "account.posts_with_replies": "PO文kap回應", "account.remove_from_followers": "Kā {name} tuì跟tuè lí ê ê內底suá掉", "account.report": "檢舉 @{name}", - "account.requested": "Teh等待審查。Tshi̍h tsi̍t-ē 通取消跟tuè請求", "account.requested_follow": "{name} 請求跟tuè lí", "account.requests_to_follow_you": "請求跟tuè lí", "account.share": "分享 @{name} ê個人資料", @@ -864,6 +869,14 @@ "status.cancel_reblog_private": "取消轉送", "status.cannot_quote": "Lí bô允准引用tsit篇PO文。", "status.cannot_reblog": "Tsit篇PO文bē當轉送", + "status.contains_quote": "包含引用", + "status.context.loading": "載入其他回應", + "status.context.loading_error": "Bē當載入新回應", + "status.context.loading_more": "載入其他回應", + "status.context.loading_success": "回應lóng載入ah", + "status.context.more_replies_found": "Tshuē-tio̍h其他回應", + "status.context.retry": "Koh試", + "status.context.show": "顯示", "status.continued_thread": "接續ê討論線", "status.copy": "Khóo-pih PO文ê連結", "status.delete": "Thâi掉", @@ -900,6 +913,7 @@ "status.quote_error.revoked": "PO文已經hōo作者thâi掉", "status.quote_followers_only": "Kan-ta tuè我ê ē當引用PO文", "status.quote_manual_review": "作者ē hōo lâng人工審核", + "status.quote_noun": "引用", "status.quote_policy_change": "改通引用ê lâng", "status.quote_post_author": "引用 @{name} ê PO文ah", "status.quote_private": "私人PO文bē當引用", diff --git a/app/javascript/mastodon/locales/ne.json b/app/javascript/mastodon/locales/ne.json index a0b99c597385e0..297feb2ce1ea03 100644 --- a/app/javascript/mastodon/locales/ne.json +++ b/app/javascript/mastodon/locales/ne.json @@ -57,7 +57,6 @@ "account.posts_with_replies": "पोस्ट र जवाफहरू", "account.remove_from_followers": "{name}लाई फलोअरहरूबाट हटाउनुहोस्", "account.report": "@{name}लाई रिपोर्ट गर्नुहोस्", - "account.requested": "स्वीकृतिको पर्खाइमा। फलो अनुरोध रद्द गर्न क्लिक गर्नुहोस्", "account.requested_follow": "{name} ले तपाईंलाई फलो गर्न अनुरोध गर्नुभएको छ", "account.share": "@{name} को प्रोफाइल सेयर गर्नुहोस्", "account.show_reblogs": "@{name} को बूस्टहरू देखाउनुहोस्", diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json index 4250040040efbd..289b49c39b6a0f 100644 --- a/app/javascript/mastodon/locales/nl.json +++ b/app/javascript/mastodon/locales/nl.json @@ -28,6 +28,7 @@ "account.disable_notifications": "Geen melding meer geven wanneer @{name} een bericht plaatst", "account.domain_blocking": "Server geblokkeerd", "account.edit_profile": "Profiel bewerken", + "account.edit_profile_short": "Bewerken", "account.enable_notifications": "Geef een melding wanneer @{name} een bericht plaatst", "account.endorse": "Op profiel weergeven", "account.familiar_followers_many": "Gevolgd door {name1}, {name2} en {othersCount, plural, one {één ander bekend account} other {# andere bekende accounts}}", @@ -40,6 +41,11 @@ "account.featured_tags.last_status_never": "Geen berichten", "account.follow": "Volgen", "account.follow_back": "Terugvolgen", + "account.follow_back_short": "Terugvolgen", + "account.follow_request": "Verzoeken om te volgen", + "account.follow_request_cancel": "Verzoek annuleren", + "account.follow_request_cancel_short": "Annuleren", + "account.follow_request_short": "Verzoek", "account.followers": "Volgers", "account.followers.empty": "Deze gebruiker heeft nog geen volgers of heeft deze verborgen.", "account.followers_counter": "{count, plural, one {{counter} volger} other {{counter} volgers}}", @@ -70,7 +76,6 @@ "account.posts_with_replies": "Reacties", "account.remove_from_followers": "{name} als volger verwijderen", "account.report": "@{name} rapporteren", - "account.requested": "Wachten op goedkeuring. Klik om het volgverzoek te annuleren", "account.requested_follow": "{name} wil jou graag volgen", "account.requests_to_follow_you": "Wil jou graag volgen", "account.share": "Account van @{name} delen", diff --git a/app/javascript/mastodon/locales/nn.json b/app/javascript/mastodon/locales/nn.json index fe2c5fc925e907..4a38a01e7890b5 100644 --- a/app/javascript/mastodon/locales/nn.json +++ b/app/javascript/mastodon/locales/nn.json @@ -70,7 +70,6 @@ "account.posts_with_replies": "Tut og svar", "account.remove_from_followers": "Fjern {name} frå fylgjarane dine", "account.report": "Rapporter @{name}", - "account.requested": "Ventar på aksept. Klikk for å avbryta fylgjeførespurnaden", "account.requested_follow": "{name} har bedt om å få fylgja deg", "account.requests_to_follow_you": "Folk som vil fylgja deg", "account.share": "Del @{name} sin profil", diff --git a/app/javascript/mastodon/locales/no.json b/app/javascript/mastodon/locales/no.json index fa03560194ca4d..7c574e7d8c9d45 100644 --- a/app/javascript/mastodon/locales/no.json +++ b/app/javascript/mastodon/locales/no.json @@ -70,7 +70,6 @@ "account.posts_with_replies": "Innlegg med svar", "account.remove_from_followers": "Fjern {name} fra følgere", "account.report": "Rapporter @{name}", - "account.requested": "Venter på godkjennelse. Klikk for å avbryte forespørselen", "account.requested_follow": "{name} har bedt om å få følge deg", "account.requests_to_follow_you": "Forespørsler om å følge deg", "account.share": "Del @{name} sin profil", diff --git a/app/javascript/mastodon/locales/oc.json b/app/javascript/mastodon/locales/oc.json index 0d87228ea1a412..87793d14fe5701 100644 --- a/app/javascript/mastodon/locales/oc.json +++ b/app/javascript/mastodon/locales/oc.json @@ -50,7 +50,6 @@ "account.posts": "Tuts", "account.posts_with_replies": "Tuts e responsas", "account.report": "Senhalar @{name}", - "account.requested": "Invitacion mandada. Clicatz per anullar", "account.requested_follow": "{name} a demandat a vos sègre", "account.share": "Partejar lo perfil a @{name}", "account.show_reblogs": "Mostrar los partatges de @{name}", diff --git a/app/javascript/mastodon/locales/pa.json b/app/javascript/mastodon/locales/pa.json index cd20e4bce04656..83614973fe52e6 100644 --- a/app/javascript/mastodon/locales/pa.json +++ b/app/javascript/mastodon/locales/pa.json @@ -56,7 +56,6 @@ "account.posts": "ਪੋਸਟਾਂ", "account.posts_with_replies": "ਪੋਸਟਾਂ ਅਤੇ ਜਵਾਬ", "account.report": "{name} ਬਾਰੇ ਰਿਪੋਰਟ ਕਰੋ", - "account.requested": "ਮਨਜ਼ੂਰੀ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ। ਫ਼ਾਲੋ ਬੇਨਤੀਆਂ ਨੂੰ ਰੱਦ ਕਰਨ ਲਈ ਕਲਿੱਕ ਕਰੋ", "account.requested_follow": "{name} ਨੇ ਤੁਹਾਨੂੰ ਫ਼ਾਲੋ ਕਰਨ ਦੀ ਬੇਨਤੀ ਕੀਤੀ ਹੈ", "account.share": "{name} ਦਾ ਪਰੋਫ਼ਾਇਲ ਸਾਂਝਾ ਕਰੋ", "account.statuses_counter": "{count, plural, one {{counter} ਪੋਸਟ} other {{counter} ਪੋਸਟਾਂ}}", diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json index 2fb0a6f1bd2c69..ef6769d6f7cca5 100644 --- a/app/javascript/mastodon/locales/pl.json +++ b/app/javascript/mastodon/locales/pl.json @@ -70,7 +70,6 @@ "account.posts_with_replies": "Wpisy i odpowiedzi", "account.remove_from_followers": "Usuń {name} z obserwujących", "account.report": "Zgłoś @{name}", - "account.requested": "Oczekująca prośba, kliknij aby anulować", "account.requested_follow": "{name} chce cię zaobserwować", "account.requests_to_follow_you": "Prośby o obserwowanie", "account.share": "Udostępnij profil @{name}", diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json index e550b7463aece9..fb3b403d45130c 100644 --- a/app/javascript/mastodon/locales/pt-BR.json +++ b/app/javascript/mastodon/locales/pt-BR.json @@ -70,7 +70,6 @@ "account.posts_with_replies": "Com respostas", "account.remove_from_followers": "Remover {name} dos seguidores", "account.report": "Denunciar @{name}", - "account.requested": "Aguardando aprovação. Clique para cancelar a solicitação", "account.requested_follow": "{name} quer te seguir", "account.requests_to_follow_you": "Pediu para seguir você", "account.share": "Compartilhar perfil de @{name}", diff --git a/app/javascript/mastodon/locales/pt-PT.json b/app/javascript/mastodon/locales/pt-PT.json index 8167b9b49ec250..7646bd226de107 100644 --- a/app/javascript/mastodon/locales/pt-PT.json +++ b/app/javascript/mastodon/locales/pt-PT.json @@ -28,6 +28,7 @@ "account.disable_notifications": "Parar de me notificar das publicações de @{name}", "account.domain_blocking": "A bloquear domínio", "account.edit_profile": "Editar perfil", + "account.edit_profile_short": "Editar", "account.enable_notifications": "Notificar-me das publicações de @{name}", "account.endorse": "Destacar no perfil", "account.familiar_followers_many": "Seguido por {name1}, {name2} e {othersCount, plural,one {mais uma pessoa que conhece} other {# outras pessoas que conhece}}", @@ -40,6 +41,11 @@ "account.featured_tags.last_status_never": "Sem publicações", "account.follow": "Seguir", "account.follow_back": "Seguir também", + "account.follow_back_short": "Seguir de volta", + "account.follow_request": "Pedir para seguir", + "account.follow_request_cancel": "Cancelar pedido", + "account.follow_request_cancel_short": "Cancelar", + "account.follow_request_short": "Pedido", "account.followers": "Seguidores", "account.followers.empty": "Ainda ninguém segue este utilizador.", "account.followers_counter": "{count, plural, one {{counter} seguidor} other {{counter} seguidores}}", @@ -70,7 +76,6 @@ "account.posts_with_replies": "Publicações e respostas", "account.remove_from_followers": "Remover {name} dos seguidores", "account.report": "Denunciar @{name}", - "account.requested": "A aguardar aprovação. Clica para cancelar o pedido para seguir", "account.requested_follow": "{name} pediu para seguir-te", "account.requests_to_follow_you": "Pediu para seguir-te", "account.share": "Partilhar o perfil @{name}", diff --git a/app/javascript/mastodon/locales/ro.json b/app/javascript/mastodon/locales/ro.json index ce3dde8eeaf207..9259226ee609f1 100644 --- a/app/javascript/mastodon/locales/ro.json +++ b/app/javascript/mastodon/locales/ro.json @@ -55,7 +55,6 @@ "account.posts": "Postări", "account.posts_with_replies": "Postări și răspunsuri", "account.report": "Raportează pe @{name}", - "account.requested": "Se așteaptă aprobarea. Apasă pentru a anula cererea de urmărire", "account.requested_follow": "{name} A cerut să vă urmărească", "account.share": "Distribuie profilul lui @{name}", "account.show_reblogs": "Afișează distribuirile de la @{name}", diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json index 1416198a42ba29..e8c96ac25f140a 100644 --- a/app/javascript/mastodon/locales/ru.json +++ b/app/javascript/mastodon/locales/ru.json @@ -70,7 +70,6 @@ "account.posts_with_replies": "Посты и ответы", "account.remove_from_followers": "Убрать {name} из подписчиков", "account.report": "Пожаловаться на @{name}", - "account.requested": "Ожидает подтверждения. Нажмите для отмены запроса", "account.requested_follow": "{name} отправил(а) вам запрос на подписку", "account.requests_to_follow_you": "Отправил(а) вам запрос на подписку", "account.share": "Поделиться профилем @{name}", diff --git a/app/javascript/mastodon/locales/ry.json b/app/javascript/mastodon/locales/ry.json index 20cc8e8e4eb708..9426a9c5c07662 100644 --- a/app/javascript/mastodon/locales/ry.json +++ b/app/javascript/mastodon/locales/ry.json @@ -51,7 +51,6 @@ "account.posts": "Публикації", "account.posts_with_replies": "Публикації тай удповіді", "account.report": "Скарговати ся на {name}", - "account.requested": "Чекат ся на пудтвердженя. Нажміт убы удмінити запрос на слідованя", "account.requested_follow": "Хосновач {name} просит ся пудписати ся на вас", "account.share": "Пошырити профіл хосновача {name}", "account.show_reblogs": "Указати друленя уд {name}", diff --git a/app/javascript/mastodon/locales/sa.json b/app/javascript/mastodon/locales/sa.json index b9c13df0581965..1cd3cdb61634c5 100644 --- a/app/javascript/mastodon/locales/sa.json +++ b/app/javascript/mastodon/locales/sa.json @@ -46,7 +46,6 @@ "account.posts": "पत्राणि", "account.posts_with_replies": "पत्राणि प्रत्युत्तराणि च", "account.report": "आविद्यताम् @{name}", - "account.requested": "स्वीकृतिः प्रतीक्ष्यते । नश्यतामित्यस्मिन्नुद्यतां निराकर्तुम् ।", "account.requested_follow": "{name} त्वामनुसर्तुमयाचीत्", "account.share": "@{name} मित्रस्य विवरणं विभाज्यताम्", "account.show_reblogs": "@{name} मित्रस्य प्रकाशनानि दृश्यन्ताम्", diff --git a/app/javascript/mastodon/locales/sc.json b/app/javascript/mastodon/locales/sc.json index d126379384efd4..781ea7c01439b8 100644 --- a/app/javascript/mastodon/locales/sc.json +++ b/app/javascript/mastodon/locales/sc.json @@ -69,7 +69,6 @@ "account.posts_with_replies": "Publicatziones e rispostas", "account.remove_from_followers": "Cantzella a {name} dae is sighiduras", "account.report": "Signala @{name}", - "account.requested": "Abetende s'aprovatzione. Incarca pro annullare sa rechesta de sighidura", "account.requested_follow": "{name} at dimandadu de ti sighire", "account.requests_to_follow_you": "Rechestas de sighidura", "account.share": "Cumpartzi su profilu de @{name}", diff --git a/app/javascript/mastodon/locales/sco.json b/app/javascript/mastodon/locales/sco.json index 52445feced9435..de24b5cdeea5bc 100644 --- a/app/javascript/mastodon/locales/sco.json +++ b/app/javascript/mastodon/locales/sco.json @@ -44,7 +44,6 @@ "account.posts": "Posts", "account.posts_with_replies": "Posts an repones", "account.report": "Clype @{name}", - "account.requested": "Haudin fir approval. Chap tae cancel follae request", "account.share": "Share @{name}'s profile", "account.show_reblogs": "Shaw heezes frae @{name}", "account.unblock": "Undingie @{name}", diff --git a/app/javascript/mastodon/locales/si.json b/app/javascript/mastodon/locales/si.json index 107ef3f1cf6901..92216ed074894a 100644 --- a/app/javascript/mastodon/locales/si.json +++ b/app/javascript/mastodon/locales/si.json @@ -68,7 +68,6 @@ "account.posts_with_replies": "ලිපි සහ පිළිතුරු", "account.remove_from_followers": "අනුගාමිකයින්ගෙන් {name} ඉවත් කරන්න", "account.report": "@{name} වාර්තා කරන්න", - "account.requested": "අනුමැතිය බලාපොරොත්තුවෙන්. අනුගමනය කිරීමේ ඉල්ලීම අවලංගු කිරීමට ක්ලික් කරන්න.", "account.requested_follow": "{name} ඔබව අනුගමනය කිරීමට ඉල්ලා ඇත.", "account.requests_to_follow_you": "ඔබව අනුගමනය කිරීමට ඉල්ලීම්", "account.share": "@{name} ගේ පැතිකඩ බෙදාගන්න", diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json index 771f52618c4390..9a408657b15247 100644 --- a/app/javascript/mastodon/locales/sk.json +++ b/app/javascript/mastodon/locales/sk.json @@ -64,7 +64,6 @@ "account.posts": "Príspevky", "account.posts_with_replies": "Príspevky a odpovede", "account.report": "Nahlásiť @{name}", - "account.requested": "Čaká na schválenie. Žiadosť zrušíte kliknutím sem", "account.requested_follow": "{name} vás chce sledovať", "account.share": "Zdieľaj profil @{name}", "account.show_reblogs": "Zobrazovať zdieľania od @{name}", diff --git a/app/javascript/mastodon/locales/sl.json b/app/javascript/mastodon/locales/sl.json index 9127605dbafed5..a87648bf7ad5c2 100644 --- a/app/javascript/mastodon/locales/sl.json +++ b/app/javascript/mastodon/locales/sl.json @@ -55,7 +55,6 @@ "account.posts": "Objave", "account.posts_with_replies": "Objave in odgovori", "account.report": "Prijavi @{name}", - "account.requested": "Čakanje na odobritev. Kliknite, da prekličete prošnjo za sledenje", "account.requested_follow": "{name} vam želi slediti", "account.share": "Deli profil osebe @{name}", "account.show_reblogs": "Pokaži izpostavitve osebe @{name}", diff --git a/app/javascript/mastodon/locales/sq.json b/app/javascript/mastodon/locales/sq.json index 56db9a5ac3645c..8ad097427b3f52 100644 --- a/app/javascript/mastodon/locales/sq.json +++ b/app/javascript/mastodon/locales/sq.json @@ -70,7 +70,6 @@ "account.posts_with_replies": "Mesazhe dhe përgjigje", "account.remove_from_followers": "Hiqe {name} nga ndjekësit", "account.report": "Raportojeni @{name}", - "account.requested": "Në pritje të miratimit. Që të anuloni kërkesën për ndjekje, klikojeni", "account.requested_follow": "{name} ka kërkuar t’ju ndjekë", "account.requests_to_follow_you": "Kërkesa për t’ju ndjekur", "account.share": "Ndajeni profilin e @{name} me të tjerët", diff --git a/app/javascript/mastodon/locales/sr-Latn.json b/app/javascript/mastodon/locales/sr-Latn.json index 8cb2e30cb5f82e..0db607b12c1c0e 100644 --- a/app/javascript/mastodon/locales/sr-Latn.json +++ b/app/javascript/mastodon/locales/sr-Latn.json @@ -54,7 +54,6 @@ "account.posts": "Objave", "account.posts_with_replies": "Objave i odgovori", "account.report": "Prijavi @{name}", - "account.requested": "Čekanje odobrenja. Kliknite za otkazivanje zahteva za praćenje", "account.requested_follow": "{name} je zatražio da vas prati", "account.share": "Podeli profil korisnika @{name}", "account.show_reblogs": "Prikaži podržavanja od korisnika @{name}", diff --git a/app/javascript/mastodon/locales/sr.json b/app/javascript/mastodon/locales/sr.json index 485109105b8e7b..48e6b4996830bd 100644 --- a/app/javascript/mastodon/locales/sr.json +++ b/app/javascript/mastodon/locales/sr.json @@ -54,7 +54,6 @@ "account.posts": "Објаве", "account.posts_with_replies": "Објаве и одговори", "account.report": "Пријави @{name}", - "account.requested": "Чекање одобрења. Кликните за отказивање захтева за праћење", "account.requested_follow": "{name} је затражио да вас прати", "account.share": "Подели профил корисника @{name}", "account.show_reblogs": "Прикажи подржавања од корисника @{name}", diff --git a/app/javascript/mastodon/locales/sv.json b/app/javascript/mastodon/locales/sv.json index e56c9da32636c3..97a4b6fd4f5ec5 100644 --- a/app/javascript/mastodon/locales/sv.json +++ b/app/javascript/mastodon/locales/sv.json @@ -70,7 +70,6 @@ "account.posts_with_replies": "Inlägg och svar", "account.remove_from_followers": "Ta bort {name} från följare", "account.report": "Rapportera @{name}", - "account.requested": "Inväntar godkännande. Klicka för att ta tillbaka din begäran om att få följa", "account.requested_follow": "{name} har begärt att följa dig", "account.requests_to_follow_you": "Fråga om att följa dig", "account.share": "Dela @{name}s profil", diff --git a/app/javascript/mastodon/locales/szl.json b/app/javascript/mastodon/locales/szl.json index 55913be9246493..709b0f9e891273 100644 --- a/app/javascript/mastodon/locales/szl.json +++ b/app/javascript/mastodon/locales/szl.json @@ -19,7 +19,6 @@ "account.mute": "Wycisz @{name}", "account.posts": "Toots", "account.posts_with_replies": "Toots and replies", - "account.requested": "Awaiting approval", "account_note.placeholder": "Click to add a note", "column.pins": "Pinned toot", "community.column_settings.media_only": "Media only", diff --git a/app/javascript/mastodon/locales/ta.json b/app/javascript/mastodon/locales/ta.json index 10d461e9e83481..8ebbd171171845 100644 --- a/app/javascript/mastodon/locales/ta.json +++ b/app/javascript/mastodon/locales/ta.json @@ -37,7 +37,6 @@ "account.posts": "டூட்டுகள்", "account.posts_with_replies": "Toots மற்றும் பதில்கள்", "account.report": "@{name} -ஐப் புகாரளி", - "account.requested": "ஒப்புதலுக்காகக் காத்திருக்கிறது. பின்தொடரும் கோரிக்கையை நீக்க அழுத்தவும்", "account.share": "@{name} உடைய விவரத்தை பகிர்", "account.show_reblogs": "காட்டு boosts இருந்து @{name}", "account.unblock": "@{name} மீது தடை நீக்குக", diff --git a/app/javascript/mastodon/locales/tai.json b/app/javascript/mastodon/locales/tai.json index 3799455050865d..507894ba142b76 100644 --- a/app/javascript/mastodon/locales/tai.json +++ b/app/javascript/mastodon/locales/tai.json @@ -8,7 +8,6 @@ "account.mention": "Thê-khí @{name}", "account.posts": "Huah-siann", "account.posts_with_replies": "Huah-siann kah huê-ìng", - "account.requested": "Tán-thāi phue-tsún", "account_note.placeholder": "Tiám tsi̍t-ē ka-thiam pī-tsù", "column.pins": "Tah thâu-tsîng ê huah-siann", "community.column_settings.media_only": "Kan-na muî-thé", diff --git a/app/javascript/mastodon/locales/te.json b/app/javascript/mastodon/locales/te.json index cbdea417b71543..015fe3f12aeda8 100644 --- a/app/javascript/mastodon/locales/te.json +++ b/app/javascript/mastodon/locales/te.json @@ -24,7 +24,6 @@ "account.posts": "టూట్లు", "account.posts_with_replies": "టూట్లు మరియు ప్రత్యుత్తరములు", "account.report": "@{name}పై ఫిర్యాదుచేయు", - "account.requested": "ఆమోదం కోసం వేచి ఉంది. అభ్యర్థనను రద్దు చేయడానికి క్లిక్ చేయండి", "account.share": "@{name} యొక్క ప్రొఫైల్ను పంచుకోండి", "account.show_reblogs": "@{name}నుంచి బూస్ట్ లను చూపించు", "account.unblock": "@{name}పై బ్లాక్ ను తొలగించు", diff --git a/app/javascript/mastodon/locales/th.json b/app/javascript/mastodon/locales/th.json index a1fade41ca66c0..ed71791f73bca6 100644 --- a/app/javascript/mastodon/locales/th.json +++ b/app/javascript/mastodon/locales/th.json @@ -64,7 +64,6 @@ "account.posts": "โพสต์", "account.posts_with_replies": "โพสต์และการตอบกลับ", "account.report": "รายงาน @{name}", - "account.requested": "กำลังรอการอนุมัติ คลิกเพื่อยกเลิกคำขอติดตาม", "account.requested_follow": "{name} ได้ขอติดตามคุณ", "account.share": "แชร์โปรไฟล์ของ @{name}", "account.show_reblogs": "แสดงการดันจาก @{name}", diff --git a/app/javascript/mastodon/locales/tok.json b/app/javascript/mastodon/locales/tok.json index dbc6b4b871c73d..3eaf22911c1277 100644 --- a/app/javascript/mastodon/locales/tok.json +++ b/app/javascript/mastodon/locales/tok.json @@ -70,7 +70,6 @@ "account.posts_with_replies": "toki ale", "account.remove_from_followers": "sijelo kute la o weka e sijelo \"{name}\".", "account.report": "jan @{name} la o toki e ike tawa lawa", - "account.requested": "jan ni o ken e kute sina", "account.requested_follow": "jan {name} li wile kute e sina", "account.requests_to_follow_you": "jan ni li wile kute e sina", "account.share": "o pana e lipu jan @{name}", diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json index cc94d324d78485..335fa07d80ae68 100644 --- a/app/javascript/mastodon/locales/tr.json +++ b/app/javascript/mastodon/locales/tr.json @@ -28,6 +28,7 @@ "account.disable_notifications": "@{name} kişisinin gönderi bildirimlerini kapat", "account.domain_blocking": "Alan adını engelleme", "account.edit_profile": "Profili düzenle", + "account.edit_profile_short": "Düzenle", "account.enable_notifications": "@{name} kişisinin gönderi bildirimlerini aç", "account.endorse": "Profilimde öne çıkar", "account.familiar_followers_many": "{name1}, {name2}, {othersCount, plural, one {# diğer} other {# diğer}} bildiğiniz kişi tarafından takip ediliyor", @@ -40,6 +41,11 @@ "account.featured_tags.last_status_never": "Gönderi yok", "account.follow": "Takip et", "account.follow_back": "Geri takip et", + "account.follow_back_short": "Geri takip et", + "account.follow_request": "Takip isteği gönder", + "account.follow_request_cancel": "İsteği iptal et", + "account.follow_request_cancel_short": "İptal", + "account.follow_request_short": "İstek", "account.followers": "Takipçi", "account.followers.empty": "Henüz kimse bu kullanıcıyı takip etmiyor.", "account.followers_counter": "{count, plural, one {{counter} takipçi} other {{counter} takipçi}}", @@ -70,7 +76,6 @@ "account.posts_with_replies": "Gönderiler ve yanıtlar", "account.remove_from_followers": "{name} takipçilerinden kaldır", "account.report": "@{name} adlı kişiyi bildir", - "account.requested": "Onay bekleniyor. Takip isteğini iptal etmek için tıklayın", "account.requested_follow": "{name} size takip isteği gönderdi", "account.requests_to_follow_you": "Size takip isteği gönderdi", "account.share": "@{name} adlı kişinin profilini paylaş", diff --git a/app/javascript/mastodon/locales/tt.json b/app/javascript/mastodon/locales/tt.json index 4c454c37fb23be..d1ef3cd3b09d33 100644 --- a/app/javascript/mastodon/locales/tt.json +++ b/app/javascript/mastodon/locales/tt.json @@ -49,7 +49,6 @@ "account.posts": "Язма", "account.posts_with_replies": "Язма һәм җавап", "account.report": "@{name} кулланучыга шикаять итү", - "account.requested": "Awaiting approval", "account.requested_follow": "{name} Сезгә язылу соравын җиберде", "account.share": "@{name} профиле белән уртаклашу", "account.show_reblogs": "Күрсәтергә көчәйтү нче @{name}", diff --git a/app/javascript/mastodon/locales/ug.json b/app/javascript/mastodon/locales/ug.json index 527457ca378a60..c87d8ee5dd82f5 100644 --- a/app/javascript/mastodon/locales/ug.json +++ b/app/javascript/mastodon/locales/ug.json @@ -13,7 +13,6 @@ "account.posts": "يازما", "account.posts_with_replies": "يازما ۋە ئىنكاس", "account.report": "@{name} نى پاش قىل", - "account.requested": "Awaiting approval", "account_note.placeholder": "چېكىلسە ئىزاھات قوشىدۇ", "column.pins": "چوققىلانغان يازما", "community.column_settings.media_only": "ۋاسىتەلا", diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json index 02370341df6c70..99dd177b2b5599 100644 --- a/app/javascript/mastodon/locales/uk.json +++ b/app/javascript/mastodon/locales/uk.json @@ -61,7 +61,6 @@ "account.posts": "Дописи", "account.posts_with_replies": "Дописи й відповіді", "account.report": "Поскаржитися на @{name}", - "account.requested": "Очікує підтвердження. Натисніть, щоб скасувати запит на підписку", "account.requested_follow": "{name} надсилає запит на стеження", "account.share": "Поділитися профілем @{name}", "account.show_reblogs": "Показати поширення від @{name}", diff --git a/app/javascript/mastodon/locales/ur.json b/app/javascript/mastodon/locales/ur.json index b1db5d819f6ce5..e06ec34e6ea17c 100644 --- a/app/javascript/mastodon/locales/ur.json +++ b/app/javascript/mastodon/locales/ur.json @@ -46,7 +46,6 @@ "account.posts": "ٹوٹ", "account.posts_with_replies": "ٹوٹ اور جوابات", "account.report": "@{name} اطلاع کریں", - "account.requested": "منظوری کا منتظر۔ درخواستِ پیروی منسوخ کرنے کیلئے کلک کریں", "account.requested_follow": "{name} آپ کو فالو کرنا چھاتا ہے۔", "account.share": "@{name} کے مشخص کو بانٹیں", "account.show_reblogs": "@{name} کی افزائشات کو دکھائیں", diff --git a/app/javascript/mastodon/locales/uz.json b/app/javascript/mastodon/locales/uz.json index d4b37a32f7b7bc..2e4038edd3b215 100644 --- a/app/javascript/mastodon/locales/uz.json +++ b/app/javascript/mastodon/locales/uz.json @@ -44,7 +44,6 @@ "account.posts": "Postlar", "account.posts_with_replies": "Xabarlar va javoblar", "account.report": "@{name} xabar berish", - "account.requested": "Tasdiqlash kutilmoqda. Kuzatuv soʻrovini bekor qilish uchun bosing", "account.requested_follow": "{name} sizni kuzatishni soʻradi", "account.share": "@{name} profilini ulashing", "account.show_reblogs": "@{name} dan bootlarni ko'rsatish", diff --git a/app/javascript/mastodon/locales/vi.json b/app/javascript/mastodon/locales/vi.json index c4e21bbe7ea045..72a1cd23ae5763 100644 --- a/app/javascript/mastodon/locales/vi.json +++ b/app/javascript/mastodon/locales/vi.json @@ -28,6 +28,7 @@ "account.disable_notifications": "Tắt thông báo khi @{name} đăng tút", "account.domain_blocking": "Máy chủ đang chủ", "account.edit_profile": "Sửa hồ sơ", + "account.edit_profile_short": "Sửa", "account.enable_notifications": "Nhận thông báo khi @{name} đăng tút", "account.endorse": "Nêu bật người này", "account.familiar_followers_many": "Theo dõi bởi {name1}, {name2} và {othersCount, plural, other {# người khác mà bạn biết}}", @@ -40,6 +41,11 @@ "account.featured_tags.last_status_never": "Chưa có tút", "account.follow": "Theo dõi", "account.follow_back": "Theo dõi lại", + "account.follow_back_short": "Theo dõi lại", + "account.follow_request": "Yêu cầu theo dõi", + "account.follow_request_cancel": "Hủy yêu cầu", + "account.follow_request_cancel_short": "Hủy bỏ", + "account.follow_request_short": "Yêu cầu", "account.followers": "Người theo dõi", "account.followers.empty": "Chưa có người theo dõi nào.", "account.followers_counter": "{count, plural, other {{counter} Người theo dõi}}", @@ -70,7 +76,6 @@ "account.posts_with_replies": "Trả lời", "account.remove_from_followers": "Xóa người theo dõi {name}", "account.report": "Báo cáo @{name}", - "account.requested": "Đang chờ chấp thuận. Nhấp vào đây để hủy yêu cầu theo dõi", "account.requested_follow": "{name} yêu cầu theo dõi bạn", "account.requests_to_follow_you": "Yêu cầu theo dõi bạn", "account.share": "Chia sẻ @{name}", diff --git a/app/javascript/mastodon/locales/zgh.json b/app/javascript/mastodon/locales/zgh.json index ff37d75a07c42b..0f0be9da423b34 100644 --- a/app/javascript/mastodon/locales/zgh.json +++ b/app/javascript/mastodon/locales/zgh.json @@ -14,7 +14,6 @@ "account.muted": "ⵉⵜⵜⵓⵥⵉⵥⵏ", "account.posts": "Toots", "account.posts_with_replies": "Toots and replies", - "account.requested": "Awaiting approval", "account.share": "ⴱⴹⵓ ⵉⴼⵔⵙ ⵏ @{name}", "account.unfollow": "ⴽⴽⵙ ⴰⴹⴼⴼⵓⵕ", "account_note.placeholder": "Click to add a note", diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json index 1c52a6334fb7d4..a73a218fa55119 100644 --- a/app/javascript/mastodon/locales/zh-CN.json +++ b/app/javascript/mastodon/locales/zh-CN.json @@ -70,7 +70,6 @@ "account.posts_with_replies": "嘟文和回复", "account.remove_from_followers": "从关注者中移除 {name}", "account.report": "举报 @{name}", - "account.requested": "正在等待对方同意。点击取消发送关注请求", "account.requested_follow": "{name} 向你发送了关注请求", "account.requests_to_follow_you": "请求关注你", "account.share": "分享 @{name} 的个人资料", diff --git a/app/javascript/mastodon/locales/zh-HK.json b/app/javascript/mastodon/locales/zh-HK.json index 1637e1cf589219..5a113ae8ae1fbb 100644 --- a/app/javascript/mastodon/locales/zh-HK.json +++ b/app/javascript/mastodon/locales/zh-HK.json @@ -65,7 +65,6 @@ "account.posts": "帖文", "account.posts_with_replies": "帖文與回覆", "account.report": "檢舉 @{name}", - "account.requested": "正在等待核准。按一下以取消追蹤請求", "account.requested_follow": "{name} 要求追蹤你", "account.share": "分享 @{name} 的個人檔案", "account.show_reblogs": "顯示 @{name} 的轉推", diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json index 02edd5f45256d4..d0da9aa7187640 100644 --- a/app/javascript/mastodon/locales/zh-TW.json +++ b/app/javascript/mastodon/locales/zh-TW.json @@ -28,6 +28,7 @@ "account.disable_notifications": "取消來自 @{name} 嘟文的通知", "account.domain_blocking": "封鎖中網域", "account.edit_profile": "編輯個人檔案", + "account.edit_profile_short": "編輯", "account.enable_notifications": "當 @{name} 嘟文時通知我", "account.endorse": "於個人檔案推薦對方", "account.familiar_followers_many": "被 {name1}、{name2}、及 {othersCount, plural, other {其他您認識的 # 人}} 跟隨", @@ -40,6 +41,11 @@ "account.featured_tags.last_status_never": "沒有嘟文", "account.follow": "跟隨", "account.follow_back": "跟隨回去", + "account.follow_back_short": "跟隨回去", + "account.follow_request": "要求跟隨您", + "account.follow_request_cancel": "取消跟隨請求", + "account.follow_request_cancel_short": "取消", + "account.follow_request_short": "跟隨請求", "account.followers": "跟隨者", "account.followers.empty": "尚未有人跟隨這位使用者。", "account.followers_counter": "被 {count, plural, other {{count} 人}}跟隨", @@ -70,7 +76,6 @@ "account.posts_with_replies": "嘟文與回覆", "account.remove_from_followers": "自跟隨者中移除 {name}", "account.report": "檢舉 @{name}", - "account.requested": "正在等候審核。按一下以取消跟隨請求", "account.requested_follow": "{name} 要求跟隨您", "account.requests_to_follow_you": "要求跟隨您", "account.share": "分享 @{name} 的個人檔案", diff --git a/config/locales/kab.yml b/config/locales/kab.yml index 9ec00b897aa910..61fb800301dba8 100644 --- a/config/locales/kab.yml +++ b/config/locales/kab.yml @@ -33,6 +33,11 @@ kab: new_email: Imayl amaynut submit: Beddel imayl title: Beddel imayl-ik s %{username} + change_role: + edit_roles: Sefrek timlilin n usqdac + label: Snifel tamlilt + no_role: War tamlilt + title: Snifel tamlilt n %{username} confirm: Sentem confirmed: Yettwasentem confirming: Asentem @@ -95,6 +100,7 @@ kab: reset: Wennez reset_password: Beddel awal uffir resubscribe: Ales ajerred + role: Tamlilt search: Nadi search_same_ip: Imseqdacen-nniḍen s tansa IP am tinn-ik security: Taɣellist @@ -121,6 +127,7 @@ kab: whitelisted: Deg tebdert tamellalt action_logs: action_types: + change_role_user: Snifel tamlilt n useqdac confirm_user: Sentem aseqdac create_announcement: Rnu-d ulɣu create_custom_emoji: Rnu imujit udmawan @@ -128,6 +135,7 @@ kab: create_domain_block: Rnu-d asewḥel n taɣult create_ip_block: Rnu alugen n IP create_unavailable_domain: Rnu-d taɣult ur nelli ara + create_user_role: Snulfu-d tamlilt destroy_announcement: Kkes ulɣu destroy_custom_emoji: Kkes imujit udmawan destroy_domain_allow: Kkes taɣult yettusirgen @@ -135,6 +143,7 @@ kab: destroy_ip_block: Kkes alugen n IP destroy_status: Kkes tasufeɣt destroy_unavailable_domain: Kkes taɣult ur nelli ara + destroy_user_role: Senger tamlilt disable_2fa_user: Gdel 2FA disable_custom_emoji: Sens imujit udmawan disable_user: Sens aseqdac @@ -150,6 +159,7 @@ kab: update_custom_emoji: Leqqem imuji udmawan update_domain_block: Leqqem iḥder n taɣult update_status: Leqqem tasufeɣt + update_user_role: Leqqem tamlilt actions: assigned_to_self_report_html: "%{name} imudd aneqqis %{target} i yiman-nsen" create_account_warning_html: "%{name} yuzen alɣu i %{target}" @@ -400,7 +410,10 @@ kab: privileges: administrator: Anedbal manage_federation: Sefrek Tafidiralit + manage_roles: Sefrek ilugan + manage_rules: Sefrek ilugan manage_settings: Asefrek n iɣewwaṛen + manage_users: Sefrek iqeddacen view_dashboard: Timẓriwt n tfelwit rules: add_new: Rnu alugen @@ -566,10 +579,10 @@ kab: migrate_account: Gujj ɣer umiḍan nniḍen or_log_in_with: Neɣ eqqen s progress: - confirm: Sentem imayl - details: Isalli-inek + confirm: Asentem n imayl + details: Isalli-inek·inem review: Tamuɣli-nneɣ - rules: Qbel ilugan + rules: Abal n ilugan providers: cas: CAS saml: SAML @@ -599,6 +612,8 @@ kab: account_status: Addad n umiḍan functional: Amiḍan-inek·inem yetteddu s lekmal-is. use_security_key: Seqdec tasarut n teɣlist + user_agreement_html: Ɣriɣ yerna qebleɣ " target="_blank">tiwtilin ne useqdec akked tsertit n tbaḍnit + user_privacy_agreement_html: Ɣriɣ yerna qebleɣ tasertit n tbaḍnit author_attribution: example_title: Amedya n weḍris more_from_html: Ugar s ɣur %{name} @@ -887,6 +902,8 @@ kab: one: "%{count} n tbidyutt" other: "%{count} n tbidyutin" edited_at_html: Tettwaẓreg ass n %{date} + pin_errors: + reblog: Azuzer ur yezmir ara ad yili d unṭiḍ quote_policies: followers: Imeḍfaṛen kan nobody: Nekki kan @@ -900,6 +917,7 @@ kab: unlisted: Azayez asusam statuses_cleanup: enabled: Tukksa n tsuffaɣ tiqburin s wudem awurman + keep_pinned: Eǧǧ tisuffaɣ tunṭiḍin min_age: '1209600': 2 n yimalasen '15778476': 6 n wayyuren diff --git a/config/locales/nan.yml b/config/locales/nan.yml index 21474c6d70dcfd..20e53b4a865b8b 100644 --- a/config/locales/nan.yml +++ b/config/locales/nan.yml @@ -213,7 +213,7 @@ nan: enable_user: 啟用口座 memorialize_account: 設做故人ê口座 promote_user: Kā用者升級 - publish_terms_of_service: 公佈服務ê使用規則 + publish_terms_of_service: 公佈服務規定 reject_appeal: 拒絕申訴 reject_user: 拒絕用者 remove_avatar_user: Thâi掉標頭 @@ -281,7 +281,7 @@ nan: enable_user_html: "%{name} kā 用者 %{target} 設做允准登入" memorialize_account_html: "%{name} kā %{target} 設做故人口座" promote_user_html: "%{name} kā 用者 %{target} 升級" - publish_terms_of_service_html: "%{name} 公佈服務規則ê更新" + publish_terms_of_service_html: "%{name} 公佈服務規定ê更新" reject_appeal_html: "%{name} 拒絕 %{target} 所寫ê tuì管理決定ê投訴" reject_user_html: "%{name} 拒絕 %{target} ê 註冊" remove_avatar_user_html: "%{name} thâi掉 %{target} ê標頭" @@ -787,7 +787,7 @@ nan: add_new: 加添規則 add_translation: 加添翻譯 delete: Thâi掉 - description_html: 雖bóng大部份ê lóng講有讀kap同意使用規則,m̄-koh攏無讀了,直到發生問題ê時。提供in列單ē當hōo tsi̍t kái看服侍器ê規則khah快。請試kā個別ê規則寫kah短koh簡單,m̄-kú m̄通kā in拆做tsē-tsē分開ê項目。 + description_html: 雖bóng大部份ê lóng講有讀kap同意服務規定,m̄-koh攏無讀了,直到發生問題ê時。提供in列單ē當hōo tsi̍t kái看服侍器ê規則khah快。請試kā個別ê規則寫kah短koh簡單,m̄-kú m̄通kā in拆做tsē-tsē分開ê項目。 edit: 編輯規則 empty: Iáu bē定義服侍器ê規則。 move_down: Suá khah落來 @@ -972,7 +972,36 @@ nan: search: Tshiau-tshuē title: Hashtag updated_msg: Hashtag設定更新成功ah + terms_of_service: + back: 轉去服務規定 + changelog: Siánn物有改 + create: 用lí家tī ê + current: 目前ê + draft: 草稿 + generate: 用枋模 + generates: + action: 生成 + chance_to_review_html: "所生成ê服務規定bē自動發布。Lí ē有機會來看結果。請添必要ê詳細來繼續。" + explanation_html: 提供ê服務規定kan-ta做參考用,bē當成做任何法律建議。請照lí ê情形kap有ê特別ê法律問題諮詢lí ê法律顧問。 + title: 設定服務規定 + going_live_on_html: 目前規定,tuì %{date} 施行 + history: 歷史 + live: 目前ê + no_history: Iáu無半項服務規定ê改變記錄。 + no_terms_of_service_html: Lí目前iáu無設定任何服務規定。服務規定是beh提供明確性,兼保護lí佇kap用者ê爭議中毋免承受可能ê責任。 + notified_on_html: 佇 %{date} 通知ê用者 + notify_users: 通知用者 trends: + preview_card_providers: + title: 發布者 + rejected: 拒絕ê + statuses: + allow: 允准PO文 + allow_account: 允准作者 + confirm_allow: Lí kám確定beh允准所揀ê狀態? + confirm_allow_account: Lí kám確定beh允准所揀ê口座? + confirm_disallow: Lí kám確定無愛允准所揀ê狀態? + confirm_disallow_account: Lí kám確定無愛允准所揀ê口座? tags: dashboard: tag_languages_dimension: Tsia̍p用ê語言 From bbb698937a55ad89bc24a4ae58cda2b5ab20200a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 29 Sep 2025 11:29:15 +0200 Subject: [PATCH 034/853] chore(deps): update dependency pino to v9.12.0 (#36287) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/yarn.lock b/yarn.lock index beca808c934c9f..17fbda96709202 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7436,13 +7436,6 @@ __metadata: languageName: node linkType: hard -"fast-redact@npm:^3.1.1": - version: 3.3.0 - resolution: "fast-redact@npm:3.3.0" - checksum: 10c0/d81562510681e9ba6404ee5d3838ff5257a44d2f80937f5024c099049ff805437d0fae0124458a7e87535cc9dcf4de305bb075cab8f08d6c720bbc3447861b4e - languageName: node - linkType: hard - "fast-safe-stringify@npm:^2.1.1": version: 2.1.1 resolution: "fast-safe-stringify@npm:2.1.1" @@ -10346,11 +10339,10 @@ __metadata: linkType: hard "pino@npm:^9.0.0": - version: 9.11.0 - resolution: "pino@npm:9.11.0" + version: 9.12.0 + resolution: "pino@npm:9.12.0" dependencies: atomic-sleep: "npm:^1.0.0" - fast-redact: "npm:^3.1.1" on-exit-leak-free: "npm:^2.1.0" pino-abstract-transport: "npm:^2.0.0" pino-std-serializers: "npm:^7.0.0" @@ -10358,11 +10350,12 @@ __metadata: quick-format-unescaped: "npm:^4.0.3" real-require: "npm:^0.2.0" safe-stable-stringify: "npm:^2.3.1" + slow-redact: "npm:^0.3.0" sonic-boom: "npm:^4.0.1" thread-stream: "npm:^3.0.0" bin: pino: bin.js - checksum: 10c0/ba908f95b61fa2c2d6c432e1f39a4394cc0dbf356c4f8837bd9c07538d749699b78204a5557e6050870f2988c25c3f0b6a88693d4bd185ebeef57d75a3b25e38 + checksum: 10c0/5cfe093e972a8471a90f7f380c01379eed3fd937038acb97d1de9180f097c044855ca89a2e70baa699aec3e8dcaec037d03e2c90dde235102a3e17b40f54cc1f languageName: node linkType: hard @@ -12287,6 +12280,13 @@ __metadata: languageName: node linkType: hard +"slow-redact@npm:^0.3.0": + version: 0.3.0 + resolution: "slow-redact@npm:0.3.0" + checksum: 10c0/bb2f77830f64fb01079849e0c6433c15e782b88cccb82d4b0d62ce216307cf514ea3f92e9b2c6ae1b1d613ac7743305d5f0324e94c9dc8e41908939456248f9a + languageName: node + linkType: hard + "smart-buffer@npm:^4.2.0": version: 4.2.0 resolution: "smart-buffer@npm:4.2.0" From 8779bbc4c1dd824b31b649fdafec9f76ea62742a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 29 Sep 2025 11:29:37 +0200 Subject: [PATCH 035/853] chore(deps): update rubocop (non-major) to v1.81.1 (#36277) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index db436c01bea4e2..1190cab586e2fd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -766,7 +766,7 @@ GEM rspec-mocks (~> 3.0) sidekiq (>= 5, < 9) rspec-support (3.13.4) - rubocop (1.81.0) + rubocop (1.81.1) json (~> 2.3) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.1.0) @@ -790,7 +790,7 @@ GEM lint_roller (~> 1.1) rubocop (>= 1.75.0, < 2.0) rubocop-ast (>= 1.44.0, < 2.0) - rubocop-rails (2.33.3) + rubocop-rails (2.33.4) activesupport (>= 4.2.0) lint_roller (~> 1.1) rack (>= 1.1) From adbd57e5a9de13ec8a335f4344116b8df6db0ac2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 29 Sep 2025 11:29:52 +0200 Subject: [PATCH 036/853] chore(deps): update dependency rubyzip to v3.1.1 (#36278) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 1190cab586e2fd..582d55840e91bc 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -812,7 +812,7 @@ GEM ruby-vips (2.2.5) ffi (~> 1.12) logger - rubyzip (3.1.0) + rubyzip (3.1.1) rufus-scheduler (3.9.2) fugit (~> 1.1, >= 1.11.1) safety_net_attestation (0.5.0) From 9f1a12b7492cad88aad8f7e1f49a5ee2c14ce3ce Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 29 Sep 2025 11:30:01 +0200 Subject: [PATCH 037/853] chore(deps): update dependency @vitejs/plugin-react to v5.0.4 (#36282) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/yarn.lock b/yarn.lock index 17fbda96709202..b6090455e43b2b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3329,10 +3329,10 @@ __metadata: languageName: node linkType: hard -"@rolldown/pluginutils@npm:1.0.0-beta.35": - version: 1.0.0-beta.35 - resolution: "@rolldown/pluginutils@npm:1.0.0-beta.35" - checksum: 10c0/feb6ab8f77ef2bde675099409c3ccd6a168f35a3c3e88482df3ca42494260fd42befe36e8e90ce358847a12aaab94cd8fe7069cf1e905edf91eb411d933906d9 +"@rolldown/pluginutils@npm:1.0.0-beta.38": + version: 1.0.0-beta.38 + resolution: "@rolldown/pluginutils@npm:1.0.0-beta.38" + checksum: 10c0/8353ec2528349f79e27d1a3193806725b85830da334e935cbb606d88c1177c58ea6519c578e4e93e5f677f5b22aecb8738894dbed14603e14b6bffe3facf1002 languageName: node linkType: hard @@ -4817,18 +4817,18 @@ __metadata: linkType: hard "@vitejs/plugin-react@npm:^5.0.0": - version: 5.0.3 - resolution: "@vitejs/plugin-react@npm:5.0.3" + version: 5.0.4 + resolution: "@vitejs/plugin-react@npm:5.0.4" dependencies: "@babel/core": "npm:^7.28.4" "@babel/plugin-transform-react-jsx-self": "npm:^7.27.1" "@babel/plugin-transform-react-jsx-source": "npm:^7.27.1" - "@rolldown/pluginutils": "npm:1.0.0-beta.35" + "@rolldown/pluginutils": "npm:1.0.0-beta.38" "@types/babel__core": "npm:^7.20.5" react-refresh: "npm:^0.17.0" peerDependencies: vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 - checksum: 10c0/3fc071455630a0584c170c544d20fc3edaccfb60a1e03ea14ca76f049f2657eb645aba9c216db016b8d70e4f894285a78fcd92ef63a2fcfa7864da378ac52761 + checksum: 10c0/bb9360a4b4c0abf064d22211756b999faf23889ac150de490590ca7bd029b0ef7f4cd8ba3a32b86682a62d46fb7bebd75b3fa9835c57c78123f4a646de2e0136 languageName: node linkType: hard From dc72719f4cf1b34f2293733e1d669f2bc844d3aa Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 29 Sep 2025 09:30:10 +0000 Subject: [PATCH 038/853] chore(deps): update dependency hiredis-client to v0.26.1 (#36286) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 582d55840e91bc..fa785d6876f029 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -300,8 +300,8 @@ GEM highline (3.1.2) reline hiredis (0.6.3) - hiredis-client (0.26.0) - redis-client (= 0.26.0) + hiredis-client (0.26.1) + redis-client (= 0.26.1) hkdf (0.3.0) htmlentities (4.3.4) http (5.3.1) @@ -720,7 +720,7 @@ GEM reline redcarpet (3.6.1) redis (4.8.1) - redis-client (0.26.0) + redis-client (0.26.1) connection_pool regexp_parser (2.11.3) reline (0.6.2) From 4d7c208da365ea51c458754946a3206351a21bdd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 29 Sep 2025 09:45:31 +0000 Subject: [PATCH 039/853] chore(deps): update node.js to 22.20 (#36252) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .nvmrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.nvmrc b/.nvmrc index 6e77d0a7496300..403f75d03823be 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -22.19 +22.20 From 150f0fcba5585782e2cac49d971904f02d5e6fbd Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 29 Sep 2025 14:05:48 +0200 Subject: [PATCH 040/853] Add support for numeric-based URIs for local accounts (#32724) --- app/controllers/accounts_controller.rb | 4 + .../activitypub/likes_controller.rb | 2 +- .../activitypub/outboxes_controller.rb | 4 +- .../activitypub/replies_controller.rb | 10 +- .../activitypub/shares_controller.rb | 2 +- .../concerns/account_owned_concern.rb | 6 +- .../follower_accounts_controller.rb | 6 +- .../following_accounts_controller.rb | 8 +- app/lib/activitypub/tag_manager.rb | 63 ++++-- app/models/account.rb | 2 + app/models/concerns/account/interactions.rb | 5 +- app/workers/activitypub/delivery_worker.rb | 2 +- config/routes.rb | 34 +++- ...0250924170259_add_id_scheme_to_accounts.rb | 7 + db/schema.rb | 3 +- spec/lib/activitypub/tag_manager_spec.rb | 179 +++++++++++++++++- .../concerns/account/interactions_spec.rb | 16 ++ spec/requests/accounts_spec.rb | 8 + .../synchronize_followers_service_spec.rb | 2 +- .../activitypub/delivery_worker_spec.rb | 13 +- 20 files changed, 324 insertions(+), 52 deletions(-) create mode 100644 db/migrate/20250924170259_add_id_scheme_to_accounts.rb diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index c3131edce939fd..efd0c92cef224d 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -71,6 +71,10 @@ def username_param params[:username] end + def account_id_param + params[:id] + end + def skip_temporary_suspension_response? request.format == :json end diff --git a/app/controllers/activitypub/likes_controller.rb b/app/controllers/activitypub/likes_controller.rb index 4aa6a4a771f156..e875517b021ec2 100644 --- a/app/controllers/activitypub/likes_controller.rb +++ b/app/controllers/activitypub/likes_controller.rb @@ -28,7 +28,7 @@ def set_status def likes_collection_presenter ActivityPub::CollectionPresenter.new( - id: account_status_likes_url(@account, @status), + id: ActivityPub::TagManager.instance.likes_uri_for(@status), type: :unordered, size: @status.favourites_count ) diff --git a/app/controllers/activitypub/outboxes_controller.rb b/app/controllers/activitypub/outboxes_controller.rb index a9476b806f54e1..928977768b9ed6 100644 --- a/app/controllers/activitypub/outboxes_controller.rb +++ b/app/controllers/activitypub/outboxes_controller.rb @@ -73,6 +73,8 @@ def page_params end def set_account - @account = params[:account_username].present? ? Account.find_local!(username_param) : Account.representative + return super if params[:account_username].present? || params[:account_id].present? + + @account = Account.representative end end diff --git a/app/controllers/activitypub/replies_controller.rb b/app/controllers/activitypub/replies_controller.rb index 0a19275d38e942..1959f50d676196 100644 --- a/app/controllers/activitypub/replies_controller.rb +++ b/app/controllers/activitypub/replies_controller.rb @@ -37,7 +37,7 @@ def set_replies def replies_collection_presenter page = ActivityPub::CollectionPresenter.new( - id: account_status_replies_url(@account, @status, page_params), + id: ActivityPub::TagManager.instance.replies_uri_for(@status, page_params), type: :unordered, part_of: account_status_replies_url(@account, @status), next: next_page, @@ -47,7 +47,7 @@ def replies_collection_presenter return page if page_requested? ActivityPub::CollectionPresenter.new( - id: account_status_replies_url(@account, @status), + id: ActivityPub::TagManager.instance.replies_uri_for(@status), type: :unordered, first: page ) @@ -66,8 +66,7 @@ def next_page # Only consider remote accounts return nil if @replies.size < DESCENDANTS_LIMIT - account_status_replies_url( - @account, + ActivityPub::TagManager.instance.replies_uri_for( @status, page: true, min_id: @replies&.last&.id, @@ -77,8 +76,7 @@ def next_page # For now, we're serving only self-replies, but next page might be other accounts next_only_other_accounts = @replies&.last&.account_id != @account.id || @replies.size < DESCENDANTS_LIMIT - account_status_replies_url( - @account, + ActivityPub::TagManager.instance.replies_uri_for( @status, page: true, min_id: next_only_other_accounts ? nil : @replies&.last&.id, diff --git a/app/controllers/activitypub/shares_controller.rb b/app/controllers/activitypub/shares_controller.rb index 65b4a5b3831326..2d1e389885a935 100644 --- a/app/controllers/activitypub/shares_controller.rb +++ b/app/controllers/activitypub/shares_controller.rb @@ -28,7 +28,7 @@ def set_status def shares_collection_presenter ActivityPub::CollectionPresenter.new( - id: account_status_shares_url(@account, @status), + id: ActivityPub::TagManager.instance.shares_uri_for(@status), type: :unordered, size: @status.reblogs_count ) diff --git a/app/controllers/concerns/account_owned_concern.rb b/app/controllers/concerns/account_owned_concern.rb index 2b132417f7cf33..7b3cd4d3ea607c 100644 --- a/app/controllers/concerns/account_owned_concern.rb +++ b/app/controllers/concerns/account_owned_concern.rb @@ -18,7 +18,11 @@ def account_required? end def set_account - @account = Account.find_local!(username_param) + @account = username_param.present? ? Account.find_local!(username_param) : Account.local.find(account_id_param) + end + + def account_id_param + params[:account_id] end def username_param diff --git a/app/controllers/follower_accounts_controller.rb b/app/controllers/follower_accounts_controller.rb index f4c7b37088a562..e9727b756a42fe 100644 --- a/app/controllers/follower_accounts_controller.rb +++ b/app/controllers/follower_accounts_controller.rb @@ -60,17 +60,17 @@ def prev_page_url def collection_presenter if page_requested? ActivityPub::CollectionPresenter.new( - id: account_followers_url(@account, page: params.fetch(:page, 1)), + id: page_url(params.fetch(:page, 1)), type: :ordered, size: @account.followers_count, items: follows.map { |follow| ActivityPub::TagManager.instance.uri_for(follow.account) }, - part_of: account_followers_url(@account), + part_of: ActivityPub::TagManager.instance.followers_uri_for(@account), next: next_page_url, prev: prev_page_url ) else ActivityPub::CollectionPresenter.new( - id: account_followers_url(@account), + id: ActivityPub::TagManager.instance.followers_uri_for(@account), type: :ordered, size: @account.followers_count, first: page_url(1) diff --git a/app/controllers/following_accounts_controller.rb b/app/controllers/following_accounts_controller.rb index 268fad96d09b68..803d6e342a9444 100644 --- a/app/controllers/following_accounts_controller.rb +++ b/app/controllers/following_accounts_controller.rb @@ -49,7 +49,7 @@ def page_requested? end def page_url(page) - account_following_index_url(@account, page: page) unless page.nil? + ActivityPub::TagManager.instance.following_uri_for(@account, page: page) unless page.nil? end def next_page_url @@ -63,17 +63,17 @@ def prev_page_url def collection_presenter if page_requested? ActivityPub::CollectionPresenter.new( - id: account_following_index_url(@account, page: params.fetch(:page, 1)), + id: page_url(params.fetch(:page, 1)), type: :ordered, size: @account.following_count, items: follows.map { |follow| ActivityPub::TagManager.instance.uri_for(follow.target_account) }, - part_of: account_following_index_url(@account), + part_of: ActivityPub::TagManager.instance.following_uri_for(@account), next: next_page_url, prev: prev_page_url ) else ActivityPub::CollectionPresenter.new( - id: account_following_index_url(@account), + id: ActivityPub::TagManager.instance.following_uri_for(@account), type: :ordered, size: @account.following_count, first: page_url(1) diff --git a/app/lib/activitypub/tag_manager.rb b/app/lib/activitypub/tag_manager.rb index 870cbea7e40613..43574d3657e49d 100644 --- a/app/lib/activitypub/tag_manager.rb +++ b/app/lib/activitypub/tag_manager.rb @@ -39,13 +39,25 @@ def uri_for(target) case target.object_type when :person - target.instance_actor? ? instance_actor_url : account_url(target) + if target.instance_actor? + instance_actor_url + elsif target.numeric_ap_id? + ap_account_url(target.id) + else + account_url(target) + end when :conversation context_url(target) unless target.parent_account_id.nil? || target.parent_status_id.nil? when :note, :comment, :activity - return activity_account_status_url(target.account, target) if target.reblog? + if target.account.numeric_ap_id? + return activity_ap_account_status_url(target.account, target) if target.reblog? + + ap_account_status_url(target.account.id, target) + else + return activity_account_status_url(target.account, target) if target.reblog? - account_status_url(target.account, target) + account_status_url(target.account, target) + end when :emoji emoji_url(target) when :flag @@ -57,7 +69,7 @@ def approval_uri_for(quote, check_approval: true) return quote.approval_uri unless quote.quoted_account&.local? return if check_approval && !quote.accepted? - account_quote_authorization_url(quote.quoted_account, quote) + quote.quoted_account.numeric_ap_id? ? ap_account_quote_authorization_url(quote.quoted_account_id, quote) : account_quote_authorization_url(quote.quoted_account, quote) end def key_uri_for(target) @@ -68,6 +80,10 @@ def uri_for_username(username) account_url(username: username) end + def uri_for_account_id(id) + ap_account_url(id: id) + end + def generate_uri_for(_target) URI.join(root_url, 'payloads', SecureRandom.uuid) end @@ -75,7 +91,7 @@ def generate_uri_for(_target) def activity_uri_for(target) raise ArgumentError, 'target must be a local activity' unless %i(note comment activity).include?(target.object_type) && target.local? - activity_account_status_url(target.account, target) + target.account.numeric_ap_id? ? activity_ap_account_status_url(target.account.id, target) : activity_account_status_url(target.account, target) end def context_uri_for(target, page_params = nil) @@ -87,49 +103,61 @@ def context_uri_for(target, page_params = nil) def replies_uri_for(target, page_params = nil) raise ArgumentError, 'target must be a local activity' unless %i(note comment activity).include?(target.object_type) && target.local? - account_status_replies_url(target.account, target, page_params) + target.account.numeric_ap_id? ? ap_account_status_replies_url(target.account.id, target, page_params) : account_status_replies_url(target.account, target, page_params) end def likes_uri_for(target) raise ArgumentError, 'target must be a local activity' unless %i(note comment activity).include?(target.object_type) && target.local? - account_status_likes_url(target.account, target) + target.account.numeric_ap_id? ? ap_account_status_likes_url(target.account.id, target) : account_status_likes_url(target.account, target) end def shares_uri_for(target) raise ArgumentError, 'target must be a local activity' unless %i(note comment activity).include?(target.object_type) && target.local? - account_status_shares_url(target.account, target) + target.account.numeric_ap_id? ? ap_account_status_shares_url(target.account.id, target) : account_status_shares_url(target.account, target) end def following_uri_for(target, ...) raise ArgumentError, 'target must be a local account' unless target.local? - account_following_index_url(target, ...) + target.numeric_ap_id? ? ap_account_following_index_url(target.id, ...) : account_following_index_url(target, ...) end def followers_uri_for(target, ...) return target.followers_url.presence unless target.local? - account_followers_url(target, ...) + target.numeric_ap_id? ? ap_account_followers_url(target.id, ...) : account_followers_url(target, ...) end def collection_uri_for(target, ...) - raise NotImplementedError unless target.local? + raise ArgumentError, 'target must be a local account' unless target.local? - account_collection_url(target, ...) + target.numeric_ap_id? ? ap_account_collection_url(target.id, ...) : account_collection_url(target, ...) end def inbox_uri_for(target) - raise NotImplementedError unless target.local? + raise ArgumentError, 'target must be a local account' unless target.local? - target.instance_actor? ? instance_actor_inbox_url : account_inbox_url(target) + if target.instance_actor? + instance_actor_inbox_url + elsif target.numeric_ap_id? + ap_account_inbox_url(target.id) + else + account_inbox_url(target) + end end def outbox_uri_for(target, ...) - raise NotImplementedError unless target.local? + raise ArgumentError, 'target must be a local account' unless target.local? - target.instance_actor? ? instance_actor_outbox_url(...) : account_outbox_url(target, ...) + if target.instance_actor? + instance_actor_outbox_url(...) + elsif target.numeric_ap_id? + ap_account_outbox_url(target.id, ...) + else + account_outbox_url(target, ...) + end end # Primary audience of a status @@ -262,10 +290,9 @@ def uri_to_local_account_params(uri) path_params = Rails.application.routes.recognize_path(uri) - # TODO: handle numeric IDs case path_params[:controller] when 'accounts' - [:username, path_params[:username]] + path_params.key?(:username) ? [:username, path_params[:username]] : [:id, path_params[:id]] when 'instance_actors' [:id, -99] end diff --git a/app/models/account.rb b/app/models/account.rb index 01644fdc92b557..79fba3472d8fa2 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -52,6 +52,7 @@ # requested_review_at :datetime # indexable :boolean default(FALSE), not null # attribution_domains :string default([]), is an Array +# id_scheme :integer default("username_ap_id") # class Account < ApplicationRecord @@ -105,6 +106,7 @@ class Account < ApplicationRecord enum :protocol, { ostatus: 0, activitypub: 1 } enum :suspension_origin, { local: 0, remote: 1 }, prefix: true + enum :id_scheme, { username_ap_id: 0, numeric_ap_id: 1 } validates :username, presence: true validates_with UniqueUsernameValidator, if: -> { will_save_change_to_username? } diff --git a/app/models/concerns/account/interactions.rb b/app/models/concerns/account/interactions.rb index 4eab55ca3e6b87..7f1d91a1602d8d 100644 --- a/app/models/concerns/account/interactions.rb +++ b/app/models/concerns/account/interactions.rb @@ -215,8 +215,9 @@ def remote_followers_hash(url) def local_followers_hash Rails.cache.fetch("followers_hash:#{id}:local") do digest = "\x00" * 32 - followers.where(domain: nil).pluck_each(:username) do |username| - Xorcist.xor!(digest, Digest::SHA256.digest(ActivityPub::TagManager.instance.uri_for_username(username))) + followers.where(domain: nil).pluck_each(:id_scheme, :id, :username) do |id_scheme, id, username| + uri = id_scheme == 'numeric_ap_id' ? ActivityPub::TagManager.instance.uri_for_account_id(id) : ActivityPub::TagManager.instance.uri_for_username(username) + Xorcist.xor!(digest, Digest::SHA256.digest(uri)) end digest.unpack1('H*') end diff --git a/app/workers/activitypub/delivery_worker.rb b/app/workers/activitypub/delivery_worker.rb index 40b5c42404fede..ade7175c9d52fc 100644 --- a/app/workers/activitypub/delivery_worker.rb +++ b/app/workers/activitypub/delivery_worker.rb @@ -55,7 +55,7 @@ def build_request(http_client) end def synchronization_header - "collectionId=\"#{account_followers_url(@source_account)}\", digest=\"#{@source_account.remote_followers_hash(@inbox_url)}\", url=\"#{account_followers_synchronization_url(@source_account)}\"" + "collectionId=\"#{ActivityPub::TagManager.instance.followers_uri_for(@source_account)}\", digest=\"#{@source_account.remote_followers_hash(@inbox_url)}\", url=\"#{account_followers_synchronization_url(@source_account)}\"" end def perform_request diff --git a/config/routes.rb b/config/routes.rb index 227b229a5bb276..0a6178399e0ab7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -95,7 +95,20 @@ def redirect_with_vary(path) get '/authorize_follow', to: redirect { |_, request| "/authorize_interaction?#{request.params.to_query}" } - resources :accounts, path: 'users', only: [:show], param: :username do + concern :account_resources do + resources :followers, only: [:index], controller: :follower_accounts + resources :following, only: [:index], controller: :following_accounts + + scope module: :activitypub do + resource :outbox, only: [:show] + resource :inbox, only: [:create] + resources :collections, only: [:show] + resource :followers_synchronization, only: [:show] + resources :quote_authorizations, only: [:show] + end + end + + resources :accounts, path: 'users', only: [:show], param: :username, concerns: :account_resources do resources :statuses, only: [:show] do member do get :activity @@ -106,16 +119,19 @@ def redirect_with_vary(path) resources :likes, only: [:index], module: :activitypub resources :shares, only: [:index], module: :activitypub end + end - resources :followers, only: [:index], controller: :follower_accounts - resources :following, only: [:index], controller: :following_accounts + scope path: 'ap', as: 'ap' do + resources :accounts, path: 'users', only: [:show], param: :id, concerns: :account_resources do + resources :statuses, module: :activitypub, only: [:show] do + member do + get :activity + end - scope module: :activitypub do - resource :outbox, only: [:show] - resource :inbox, only: [:create] - resources :collections, only: [:show] - resource :followers_synchronization, only: [:show] - resources :quote_authorizations, only: [:show] + resources :replies, only: [:index] + resources :likes, only: [:index] + resources :shares, only: [:index] + end end end diff --git a/db/migrate/20250924170259_add_id_scheme_to_accounts.rb b/db/migrate/20250924170259_add_id_scheme_to_accounts.rb new file mode 100644 index 00000000000000..7dd987dcc0e168 --- /dev/null +++ b/db/migrate/20250924170259_add_id_scheme_to_accounts.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class AddIdSchemeToAccounts < ActiveRecord::Migration[8.0] + def change + add_column :accounts, :id_scheme, :integer, default: 0 + end +end diff --git a/db/schema.rb b/db/schema.rb index 3b3c1bdfe5fe8f..78e75f787af53d 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[8.0].define(version: 2025_09_12_082651) do +ActiveRecord::Schema[8.0].define(version: 2025_09_24_170259) do # These are extensions that must be enabled in order to support this database enable_extension "pg_catalog.plpgsql" @@ -199,6 +199,7 @@ t.boolean "indexable", default: false, null: false t.string "attribution_domains", default: [], array: true t.string "following_url", default: "", null: false + t.integer "id_scheme", default: 0 t.index "(((setweight(to_tsvector('simple'::regconfig, (display_name)::text), 'A'::\"char\") || setweight(to_tsvector('simple'::regconfig, (username)::text), 'B'::\"char\")) || setweight(to_tsvector('simple'::regconfig, (COALESCE(domain, ''::character varying))::text), 'C'::\"char\")))", name: "search_index", using: :gin t.index "lower((username)::text), COALESCE(lower((domain)::text), ''::text)", name: "index_accounts_on_username_and_domain_lower", unique: true t.index ["domain", "id"], name: "index_accounts_on_domain_and_id" diff --git a/spec/lib/activitypub/tag_manager_spec.rb b/spec/lib/activitypub/tag_manager_spec.rb index e536883a557645..70e084a9c9264a 100644 --- a/spec/lib/activitypub/tag_manager_spec.rb +++ b/spec/lib/activitypub/tag_manager_spec.rb @@ -29,6 +29,15 @@ expect(subject.url_for(account)) .to eq("#{host_prefix}/@#{account.username}") end + + context 'when using a numeric ID based scheme' do + let(:account) { Fabricate(:account, id_scheme: :numeric_ap_id) } + + it 'returns a string starting with web domain and with the expected path' do + expect(subject.url_for(account)) + .to eq("#{host_prefix}/@#{account.username}") + end + end end context 'with a remote account' do @@ -46,6 +55,16 @@ expect(subject.url_for(status)) .to eq("#{host_prefix}/@#{status.account.username}/#{status.id}") end + + context 'when using a numeric ID based scheme' do + let(:account) { Fabricate(:account, id_scheme: :numeric_ap_id) } + let(:status) { Fabricate(:status, account: account) } + + it 'returns a string starting with web domain and with the expected path' do + expect(subject.url_for(status)) + .to eq("#{host_prefix}/@#{status.account.username}/#{status.id}") + end + end end context 'with a remote status' do @@ -73,6 +92,15 @@ expect(subject.uri_for(account)) .to eq("#{host_prefix}/users/#{account.username}") end + + context 'when using a numeric ID based scheme' do + let(:account) { Fabricate(:account, id_scheme: :numeric_ap_id) } + + it 'returns a string starting with web domain and with the expected path' do + expect(subject.uri_for(account)) + .to eq("#{host_prefix}/ap/users/#{account.id}") + end + end end context 'with a remote account' do @@ -90,6 +118,16 @@ expect(subject.uri_for(status)) .to eq("#{host_prefix}/users/#{status.account.username}/statuses/#{status.id}") end + + context 'when using a numeric ID based scheme' do + let(:account) { Fabricate(:account, id_scheme: :numeric_ap_id) } + let(:status) { Fabricate(:status, account: account) } + + it 'returns a string starting with web domain and with the expected path' do + expect(subject.uri_for(status)) + .to eq("#{host_prefix}/ap/users/#{status.account.id}/statuses/#{status.id}") + end + end end context 'with a remote status' do @@ -108,6 +146,16 @@ expect(subject.uri_for(status.conversation)) .to eq("#{host_prefix}/contexts/#{status.account.id}-#{status.id}") end + + context 'when using a numeric ID based scheme' do + let(:account) { Fabricate(:account, id_scheme: :numeric_ap_id) } + let(:status) { Fabricate(:status, account: account) } + + it 'returns a string starting with web domain and with the expected path' do + expect(subject.uri_for(status.conversation)) + .to eq("#{host_prefix}/contexts/#{status.account.id}-#{status.id}") + end + end end context 'with a remote conversation' do @@ -139,6 +187,15 @@ expect(subject.key_uri_for(account)) .to eq("#{host_prefix}/users/#{account.username}#main-key") end + + context 'when using a numeric ID based scheme' do + let(:account) { Fabricate(:account, id_scheme: :numeric_ap_id) } + + it 'returns a string starting with web domain and with the expected path' do + expect(subject.key_uri_for(account)) + .to eq("#{host_prefix}/ap/users/#{account.id}#main-key") + end + end end end @@ -167,6 +224,17 @@ expect(subject.approval_uri_for(quote)) .to eq("#{host_prefix}/users/#{quote.quoted_account.username}/quote_authorizations/#{quote.id}") end + + context 'when using a numeric ID based scheme' do + let(:quoted_account) { Fabricate(:account, id_scheme: :numeric_ap_id) } + let(:quoted_status) { Fabricate(:status, account: quoted_account) } + let(:quote) { Fabricate(:quote, state: :accepted, quoted_status: quoted_status) } + + it 'returns a string with the web domain and expected path' do + expect(subject.approval_uri_for(quote)) + .to eq("#{host_prefix}/ap/users/#{quote.quoted_account_id}/quote_authorizations/#{quote.id}") + end + end end context 'with an unapproved local quote' do @@ -176,6 +244,17 @@ expect(subject.approval_uri_for(quote)) .to be_nil end + + context 'when using a numeric ID based scheme' do + let(:quoted_account) { Fabricate(:account, id_scheme: :numeric_ap_id) } + let(:quoted_status) { Fabricate(:status, account: quoted_account) } + let(:quote) { Fabricate(:quote, state: :rejected, quoted_status: quoted_status) } + + it 'returns nil' do + expect(subject.approval_uri_for(quote)) + .to be_nil + end + end end context 'with a valid remote approval' do @@ -195,6 +274,17 @@ expect(subject.approval_uri_for(quote, check_approval: false)) .to eq("#{host_prefix}/users/#{quote.quoted_account.username}/quote_authorizations/#{quote.id}") end + + context 'when using a numeric ID based scheme' do + let(:quoted_account) { Fabricate(:account, id_scheme: :numeric_ap_id) } + let(:quoted_status) { Fabricate(:status, account: quoted_account) } + let(:quote) { Fabricate(:quote, state: :rejected, quoted_status: quoted_status) } + + it 'returns a string with the web domain and expected path' do + expect(subject.approval_uri_for(quote, check_approval: false)) + .to eq("#{host_prefix}/ap/users/#{quote.quoted_account_id}/quote_authorizations/#{quote.id}") + end + end end end @@ -206,6 +296,16 @@ expect(subject.replies_uri_for(status)) .to eq("#{host_prefix}/users/#{status.account.username}/statuses/#{status.id}/replies") end + + context 'when using a numeric ID based scheme' do + let(:account) { Fabricate(:account, id_scheme: :numeric_ap_id) } + let(:status) { Fabricate(:status, account: account) } + + it 'returns a string starting with web domain and with the expected path' do + expect(subject.replies_uri_for(status)) + .to eq("#{host_prefix}/ap/users/#{status.account.id}/statuses/#{status.id}/replies") + end + end end end @@ -217,6 +317,16 @@ expect(subject.likes_uri_for(status)) .to eq("#{host_prefix}/users/#{status.account.username}/statuses/#{status.id}/likes") end + + context 'when using a numeric ID based scheme' do + let(:account) { Fabricate(:account, id_scheme: :numeric_ap_id) } + let(:status) { Fabricate(:status, account: account) } + + it 'returns a string starting with web domain and with the expected path' do + expect(subject.likes_uri_for(status)) + .to eq("#{host_prefix}/ap/users/#{status.account.id}/statuses/#{status.id}/likes") + end + end end end @@ -228,6 +338,16 @@ expect(subject.shares_uri_for(status)) .to eq("#{host_prefix}/users/#{status.account.username}/statuses/#{status.id}/shares") end + + context 'when using a numeric ID based scheme' do + let(:account) { Fabricate(:account, id_scheme: :numeric_ap_id) } + let(:status) { Fabricate(:status, account: account) } + + it 'returns a string starting with web domain and with the expected path' do + expect(subject.shares_uri_for(status)) + .to eq("#{host_prefix}/ap/users/#{status.account.id}/statuses/#{status.id}/shares") + end + end end end @@ -239,6 +359,15 @@ expect(subject.following_uri_for(account)) .to eq("#{host_prefix}/users/#{account.username}/following") end + + context 'when using a numeric ID based scheme' do + let(:account) { Fabricate(:account, id_scheme: :numeric_ap_id) } + + it 'returns a string starting with web domain and with the expected path' do + expect(subject.following_uri_for(account)) + .to eq("#{host_prefix}/ap/users/#{account.id}/following") + end + end end end @@ -250,6 +379,15 @@ expect(subject.followers_uri_for(account)) .to eq("#{host_prefix}/users/#{account.username}/followers") end + + context 'when using a numeric ID based scheme' do + let(:account) { Fabricate(:account, id_scheme: :numeric_ap_id) } + + it 'returns a string starting with web domain and with the expected path' do + expect(subject.followers_uri_for(account)) + .to eq("#{host_prefix}/ap/users/#{account.id}/followers") + end + end end end @@ -268,6 +406,15 @@ expect(subject.inbox_uri_for(account)) .to eq("#{host_prefix}/users/#{account.username}/inbox") end + + context 'when using a numeric ID based scheme' do + let(:account) { Fabricate(:account, id_scheme: :numeric_ap_id) } + + it 'returns a string starting with web domain and with the expected path' do + expect(subject.inbox_uri_for(account)) + .to eq("#{host_prefix}/ap/users/#{account.id}/inbox") + end + end end end @@ -286,6 +433,15 @@ expect(subject.outbox_uri_for(account)) .to eq("#{host_prefix}/users/#{account.username}/outbox") end + + context 'when using a numeric ID based scheme' do + let(:account) { Fabricate(:account, id_scheme: :numeric_ap_id) } + + it 'returns a string starting with web domain and with the expected path' do + expect(subject.outbox_uri_for(account)) + .to eq("#{host_prefix}/ap/users/#{account.id}/outbox") + end + end end end @@ -300,16 +456,28 @@ expect(subject.to(status)).to eq [account_followers_url(status.account)] end + it 'returns followers collection for unlisted status when using a numeric ID based scheme' do + status = Fabricate(:status, visibility: :unlisted, account: Fabricate(:account, id_scheme: :numeric_ap_id)) + expect(subject.to(status)).to eq [ap_account_followers_url(status.account_id)] + end + it 'returns followers collection for private status' do status = Fabricate(:status, visibility: :private) expect(subject.to(status)).to eq [account_followers_url(status.account)] end + it 'returns followers collection for private status when using a numeric ID based scheme' do + status = Fabricate(:status, visibility: :private, account: Fabricate(:account, id_scheme: :numeric_ap_id)) + expect(subject.to(status)).to eq [ap_account_followers_url(status.account_id)] + end + it 'returns URIs of mentions for direct status' do status = Fabricate(:status, visibility: :direct) mentioned = Fabricate(:account) + mentioned_numeric = Fabricate(:account, id_scheme: :numeric_ap_id) status.mentions.create(account: mentioned) - expect(subject.to(status)).to eq [subject.uri_for(mentioned)] + status.mentions.create(account: mentioned_numeric) + expect(subject.to(status)).to eq [subject.uri_for(mentioned), subject.uri_for(mentioned_numeric)] end it "returns URIs of mentioned group's followers for direct statuses to groups" do @@ -350,6 +518,11 @@ expect(subject.cc(status)).to eq [account_followers_url(status.account)] end + it 'returns followers collection for public status when using a numeric ID based scheme' do + status = Fabricate(:status, visibility: :public, account: Fabricate(:account, id_scheme: :numeric_ap_id)) + expect(subject.cc(status)).to eq [ap_account_followers_url(status.account_id)] + end + it 'returns public collection for unlisted status' do status = Fabricate(:status, visibility: :unlisted) expect(subject.cc(status)).to eq ['https://www.w3.org/ns/activitystreams#Public'] @@ -368,8 +541,10 @@ it 'returns URIs of mentions for non-direct status' do status = Fabricate(:status, visibility: :public) mentioned = Fabricate(:account) + mentioned_numeric = Fabricate(:account, id_scheme: :numeric_ap_id) status.mentions.create(account: mentioned) - expect(subject.cc(status)).to include(subject.uri_for(mentioned)) + status.mentions.create(account: mentioned_numeric) + expect(subject.cc(status)).to include(subject.uri_for(mentioned), subject.uri_for(mentioned_numeric)) end context 'with followers and requested followers' do diff --git a/spec/models/concerns/account/interactions_spec.rb b/spec/models/concerns/account/interactions_spec.rb index e6e9076edb6cad..b683259c8c8de7 100644 --- a/spec/models/concerns/account/interactions_spec.rb +++ b/spec/models/concerns/account/interactions_spec.rb @@ -563,6 +563,22 @@ me.follow!(remote_alice) expect(remote_alice.local_followers_hash).to eq Digest::SHA256.hexdigest(ActivityPub::TagManager.instance.uri_for(me)) end + + context 'when using numeric ID based scheme' do + let(:me) { Fabricate(:account, username: 'Me', id_scheme: :numeric_ap_id) } + + it 'returns correct hash for local users' do + expect(remote_alice.local_followers_hash).to eq Digest::SHA256.hexdigest(ActivityPub::TagManager.instance.uri_for(me)) + end + + it 'invalidates cache as needed when removing or adding followers' do + expect(remote_alice.local_followers_hash).to eq Digest::SHA256.hexdigest(ActivityPub::TagManager.instance.uri_for(me)) + me.unfollow!(remote_alice) + expect(remote_alice.local_followers_hash).to eq '0000000000000000000000000000000000000000000000000000000000000000' + me.follow!(remote_alice) + expect(remote_alice.local_followers_hash).to eq Digest::SHA256.hexdigest(ActivityPub::TagManager.instance.uri_for(me)) + end + end end describe 'muting an account' do diff --git a/spec/requests/accounts_spec.rb b/spec/requests/accounts_spec.rb index 72913ebf22da07..cc2a5be7c5f5d8 100644 --- a/spec/requests/accounts_spec.rb +++ b/spec/requests/accounts_spec.rb @@ -5,6 +5,14 @@ RSpec.describe 'Accounts show response' do let(:account) { Fabricate(:account) } + context 'with numeric-based identifiers' do + it 'returns http success' do + get "/ap/users/#{account.id}" + + expect(response).to have_http_status(200) + end + end + context 'with an unapproved account' do before { account.user.update(approved: false) } diff --git a/spec/services/activitypub/synchronize_followers_service_spec.rb b/spec/services/activitypub/synchronize_followers_service_spec.rb index b0bd02dac887a2..813658d149b889 100644 --- a/spec/services/activitypub/synchronize_followers_service_spec.rb +++ b/spec/services/activitypub/synchronize_followers_service_spec.rb @@ -6,7 +6,7 @@ subject { described_class.new } let(:actor) { Fabricate(:account, domain: 'example.com', uri: 'http://example.com/account', inbox_url: 'http://example.com/inbox') } - let(:alice) { Fabricate(:account, username: 'alice') } + let(:alice) { Fabricate(:account, username: 'alice', id_scheme: :numeric_ap_id) } let(:bob) { Fabricate(:account, username: 'bob') } let(:eve) { Fabricate(:account, username: 'eve') } let(:mallory) { Fabricate(:account, username: 'mallory') } diff --git a/spec/workers/activitypub/delivery_worker_spec.rb b/spec/workers/activitypub/delivery_worker_spec.rb index 9e6805c68b4f06..a1eb7ebfa997a0 100644 --- a/spec/workers/activitypub/delivery_worker_spec.rb +++ b/spec/workers/activitypub/delivery_worker_spec.rb @@ -25,12 +25,23 @@ .to have_been_made.once end + context 'when using a numeric ID based scheme' do + let(:sender) { Fabricate(:account, id_scheme: :numeric_ap_id) } + + it 'performs a request to synchronize collection' do + subject.perform(payload, sender.id, url, { synchronize_followers: true }) + + expect(request_to_url) + .to have_been_made.once + end + end + def request_to_url a_request(:post, url) .with( headers: { 'Collection-Synchronization' => <<~VALUES.squish, - collectionId="#{account_followers_url(sender)}", digest="somehash", url="#{account_followers_synchronization_url(sender)}" + collectionId="#{ActivityPub::TagManager.instance.followers_uri_for(sender)}", digest="somehash", url="#{account_followers_synchronization_url(sender)}" VALUES } ) From c4cd2c955b440003aa4322663f7dd9ca9c70fea6 Mon Sep 17 00:00:00 2001 From: Brad Dunbar Date: Mon, 29 Sep 2025 05:10:27 -0400 Subject: [PATCH 041/853] [Glitch] Remove shallow prop from Wrapper Port aae9a5528a1677177a65891a058870f2e763e176 to glitch-soc Signed-off-by: Claire --- .../flavours/glitch/features/emoji/emoji_html.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/javascript/flavours/glitch/features/emoji/emoji_html.tsx b/app/javascript/flavours/glitch/features/emoji/emoji_html.tsx index 4fa671431cd8ce..b6d966c19502a8 100644 --- a/app/javascript/flavours/glitch/features/emoji/emoji_html.tsx +++ b/app/javascript/flavours/glitch/features/emoji/emoji_html.tsx @@ -51,7 +51,14 @@ export const EmojiHTML = ( if (isModernEmojiEnabled()) { return ; } - const { as: asElement, htmlString, extraEmojis, className, ...rest } = props; + const { + as: asElement, + htmlString, + extraEmojis, + className, + shallow: _, + ...rest + } = props; const Wrapper = asElement ?? 'div'; return ( Date: Tue, 30 Sep 2025 09:27:09 +0200 Subject: [PATCH 042/853] Add integration tests for mastodon-streaming (#36025) Co-authored-by: Claire Co-authored-by: David Roetzel --- Gemfile | 3 + Gemfile.lock | 1 + spec/rails_helper.rb | 3 +- spec/support/streaming_client.rb | 205 ++++++++++++++++++ spec/support/streaming_server_manager.rb | 11 +- .../streaming/channel_subscriptions_spec.rb | 62 ++++++ spec/system/streaming/streaming_spec.rb | 77 +++++++ 7 files changed, 358 insertions(+), 4 deletions(-) create mode 100644 spec/support/streaming_client.rb create mode 100644 spec/system/streaming/channel_subscriptions_spec.rb create mode 100644 spec/system/streaming/streaming_spec.rb diff --git a/Gemfile b/Gemfile index 126d73f9cab1e3..16be707bfbfccf 100644 --- a/Gemfile +++ b/Gemfile @@ -160,6 +160,9 @@ group :test do # Stub web requests for specs gem 'webmock', '~> 3.18' + + # Websocket driver for testing integration between rails/sidekiq and streaming + gem 'websocket-driver', '~> 0.8', require: false end group :development do diff --git a/Gemfile.lock b/Gemfile.lock index fa785d6876f029..5886fd6085b37c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1102,6 +1102,7 @@ DEPENDENCIES webauthn (~> 3.0) webmock (~> 3.18) webpush! + websocket-driver (~> 0.8) xorcist (~> 1.1) RUBY VERSION diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 3d3e556f353d3b..6be93ecb70ef99 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -30,7 +30,8 @@ # This needs to be defined before Rails is initialized STREAMING_PORT = ENV.fetch('TEST_STREAMING_PORT', '4020') -ENV['STREAMING_API_BASE_URL'] = "http://localhost:#{STREAMING_PORT}" +STREAMING_HOST = ENV.fetch('TEST_STREAMING_HOST', 'localhost') +ENV['STREAMING_API_BASE_URL'] = "http://#{STREAMING_HOST}:#{STREAMING_PORT}" require_relative '../config/environment' diff --git a/spec/support/streaming_client.rb b/spec/support/streaming_client.rb new file mode 100644 index 00000000000000..02186e781c7d3e --- /dev/null +++ b/spec/support/streaming_client.rb @@ -0,0 +1,205 @@ +# frozen_string_literal: true + +require 'websocket/driver' + +class StreamingClient + module AUTHENTICATION + SUBPROTOCOL = 1 + AUTHORIZATION_HEADER = 2 + QUERY_PARAMETER = 3 + end + + class Connection + attr_reader :url, :messages, :last_error + attr_accessor :logger, :protocols + + def initialize(url) + @uri = URI.parse(url) + @query_params = @uri.query.present? ? URI.decode_www_form(@uri.query).to_h : {} + @protocols = nil + @headers = {} + + @dead = false + + @events_queue = Thread::Queue.new + @messages = [] + @last_error = nil + end + + def set_header(key, value) + @headers[key] = value + end + + def set_query_param(key, value) + @query_params[key] = value + end + + def driver + return @driver if defined?(@driver) + + @uri.query = URI.encode_www_form(@query_params) + @url = @uri.to_s + @tcp = TCPSocket.new(@uri.host, @uri.port) + + @driver = WebSocket::Driver.client(self, { + protocols: @protocols, + }) + + @headers.each_pair do |key, value| + @driver.set_header(key, value) + end + + at_exit do + @driver.close + end + + @driver.on(:open) do + @events_queue.enq({ event: :opened }) + end + + @driver.on(:message) do |event| + @events_queue.enq({ event: :message, payload: event.data }) + @messages << event.data + end + + @driver.on(:error) do |event| + logger&.debug(event.message) + @events_queue.enq({ event: :error, payload: event }) + @last_error = event + end + + @driver.on(:close) do |event| + @events_queue.enq({ event: :closing, payload: event }) + finalize(event) + end + + @thread = Thread.new do + @driver.parse(@tcp.read(1)) until @dead || @tcp.closed? + rescue Errno::ECONNRESET + # Create a synthetic close event: + close_event = WebSocket::Driver::CloseEvent.new( + WebSocket::Driver::Hybi::ERRORS[:unexpected_condition], + 'Connection reset' + ) + + finalize(close_event) + end + + @driver + end + + def wait_for_event(expected_event, timeout: 10) + Timeout.timeout(timeout) do + loop do + event = dequeue_event + + return nil if event.nil? && @events_queue.closed? + return event[:payload] unless event.nil? || event[:event] != expected_event + end + end + end + + def write(data) + @tcp.write(data) + rescue Errno::EPIPE => e + logger&.debug("EPIPE: #{e}") + end + + def finalize(event) + @dead = true + @events_queue.enq({ event: :closed, payload: event }) + @events_queue.close + @thread.kill + end + + def dequeue_event + event = @events_queue.pop + logger&.debug(event) unless event.nil? + event + end + end + + def initialize + @logger = Logger.new($stdout) + @logger.level = 'info' + + @connection = Connection.new("ws://#{STREAMING_HOST}:#{STREAMING_PORT}/api/v1/streaming") + @connection.logger = @logger + end + + def debug! + @logger.debug! + end + + def authenticate(access_token, authentication_method = StreamingClient::AUTHENTICATION::SUBPROTOCOL) + raise 'Invalid access_token passed to StreamingClient, expected a string' unless access_token.is_a?(String) + + case authentication_method + when AUTHENTICATION::QUERY_PARAMETER + @connection.set_query_param('access_token', access_token) + when AUTHENTICATION::SUBPROTOCOL + @connection.protocols = access_token + when AUTHENTICATION::AUTHORIZATION_HEADER + @connection.set_header('Authorization', "Bearer #{access_token}") + else + raise 'Invalid authentication method' + end + end + + def connect + @connection.driver.start + @connection.wait_for_event(:opened) + end + + def subscribe(channel, **params) + send(Oj.dump({ type: 'subscribe', stream: channel }.merge(params))) + end + + def wait_for(event = nil) + @connection.wait_for_event(event) + end + + def wait_for_message + message = @connection.wait_for_event(:message) + event = Oj.load(message) + event['payload'] = Oj.load(event['payload']) if event['payload'] + + event.deep_symbolize_keys + end + + delegate :status, :state, to: :'@connection.driver' + delegate :messages, to: :@connection + + def open? + state == :open + end + + def closing? + state == :closing + end + + def closed? + state == :closed + end + + def send(message) + @connection.driver.text(message) if open? + end + + def close + return if closed? + + @connection.driver.close unless closing? + @connection.wait_for_event(:closed) + end +end + +module StreamingClientHelper + def streaming_client + @streaming_client ||= StreamingClient.new + end +end + +RSpec.configure do |config| + config.include StreamingClientHelper, :streaming +end diff --git a/spec/support/streaming_server_manager.rb b/spec/support/streaming_server_manager.rb index d98f7dd960735e..b565ed79a88d56 100644 --- a/spec/support/streaming_server_manager.rb +++ b/spec/support/streaming_server_manager.rb @@ -12,6 +12,11 @@ def start(port: 4020) queue = Queue.new + if ENV['DEBUG_STREAMING_SERVER'].present? + logger = Logger.new($stdout) + logger.level = 'debug' + end + @queue = queue @running_thread = Thread.new do @@ -31,7 +36,7 @@ def start(port: 4020) # Spawn a thread to listen on streaming server output output_thread = Thread.new do stdout_err.each_line do |line| - Rails.logger.info "Streaming server: #{line}" + logger&.info "Streaming server: #{line}" if status == :starting && line.match('Streaming API now listening on') status = :started @@ -115,12 +120,12 @@ def stop self.use_transactional_tests = true end - private - def streaming_server_manager @streaming_server_manager ||= StreamingServerManager.new end + private + def streaming_examples_present? RSpec.world.filtered_examples.values.flatten.any? { |example| example.metadata[:streaming] == true } end diff --git a/spec/system/streaming/channel_subscriptions_spec.rb b/spec/system/streaming/channel_subscriptions_spec.rb new file mode 100644 index 00000000000000..54e125c293dfa0 --- /dev/null +++ b/spec/system/streaming/channel_subscriptions_spec.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +require 'rails_helper' +require 'debug' + +RSpec.describe 'Channel Subscriptions', :inline_jobs, :streaming do + let(:application) { Fabricate(:application, confidential: false) } + let(:scopes) { nil } + let(:access_token) { Fabricate(:accessible_access_token, resource_owner_id: user_account.user.id, application: application, scopes: scopes) } + + let(:user_account) { Fabricate(:account, username: 'alice', domain: nil) } + let(:bob_account) { Fabricate(:account, username: 'bob') } + + after do + streaming_client.close + end + + context 'when the access token has read scope' do + let(:scopes) { 'read' } + + it 'can subscribing to the public:local channel' do + streaming_client.authenticate(access_token.token) + + streaming_client.connect + streaming_client.subscribe('public:local') + + # We need to publish a status as there is no positive acknowledgement of + # subscriptions: + status = PostStatusService.new.call(bob_account, text: 'Hello @alice') + + # And then we want to receive that status: + message = streaming_client.wait_for_message + + expect(message).to include( + stream: be_an(Array).and(contain_exactly('public:local')), + event: 'update', + payload: include( + id: status.id.to_s + ) + ) + end + end + + context 'when the access token cannot read notifications' do + let(:scopes) { 'read:statuses' } + + it 'cannot subscribing to the user:notifications channel' do + streaming_client.authenticate(access_token.token) + + streaming_client.connect + streaming_client.subscribe('user:notification') + + # We should receive an error back immediately: + message = streaming_client.wait_for_message + + expect(message).to include( + error: 'Access token does not have the required scopes', + status: 401 + ) + end + end +end diff --git a/spec/system/streaming/streaming_spec.rb b/spec/system/streaming/streaming_spec.rb new file mode 100644 index 00000000000000..c12bd1b18fed77 --- /dev/null +++ b/spec/system/streaming/streaming_spec.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +require 'rails_helper' +RSpec.describe 'Streaming', :inline_jobs, :streaming do + let(:authentication_method) { StreamingClient::AUTHENTICATION::SUBPROTOCOL } + let(:user) { Fabricate(:user) } + let(:scopes) { '' } + let(:application) { Fabricate(:application, confidential: false) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, application: application, scopes: scopes) } + let(:access_token) { token.token } + + before do + streaming_client.authenticate(access_token, authentication_method) + end + + after do + streaming_client.close + end + + context 'when authenticating via subprotocol' do + it 'is able to connect' do + streaming_client.connect + + expect(streaming_client.status).to eq(101) + expect(streaming_client.open?).to be(true) + end + end + + context 'when authenticating via authorization header' do + let(:authentication_method) { StreamingClient::AUTHENTICATION::AUTHORIZATION_HEADER } + + it 'is able to connect successfully' do + streaming_client.connect + + expect(streaming_client.status).to eq(101) + expect(streaming_client.open?).to be(true) + end + end + + context 'when authenticating via query parameter' do + let(:authentication_method) { StreamingClient::AUTHENTICATION::QUERY_PARAMETER } + + it 'is able to connect successfully' do + streaming_client.connect + + expect(streaming_client.status).to eq(101) + expect(streaming_client.open?).to be(true) + end + end + + context 'with a revoked access token' do + before do + token.revoke + end + + it 'receives an 401 unauthorized error' do + streaming_client.connect + + expect(streaming_client.status).to eq(401) + expect(streaming_client.open?).to be(false) + end + end + + context 'when revoking an access token after connection' do + it 'disconnects the client' do + streaming_client.connect + + expect(streaming_client.status).to eq(101) + expect(streaming_client.open?).to be(true) + + token.revoke + + expect(streaming_client.wait_for(:closed).code).to be(1000) + expect(streaming_client.open?).to be(false) + end + end +end From a6236148d8f3e42a960eb4509d4d83bcfa683578 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 Sep 2025 10:44:15 +0200 Subject: [PATCH 043/853] chore(deps): update dependency haml-rails to v3 (#36288) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 16be707bfbfccf..0d9ab342715c46 100644 --- a/Gemfile +++ b/Gemfile @@ -9,7 +9,7 @@ gem 'rails', '~> 8.0' gem 'thor', '~> 1.2' gem 'dotenv' -gem 'haml-rails', '~>2.0' +gem 'haml-rails', '~>3.0' gem 'pg', '~> 1.5' gem 'pghero' diff --git a/Gemfile.lock b/Gemfile.lock index 5886fd6085b37c..cd96d60e1d5539 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -282,7 +282,7 @@ GEM temple (>= 0.8.2) thor tilt - haml-rails (2.1.0) + haml-rails (3.0.0) actionpack (>= 5.1) activesupport (>= 5.1) haml (>= 4.0.6) @@ -990,7 +990,7 @@ DEPENDENCIES flatware-rspec fog-core (<= 2.6.0) fog-openstack (~> 1.0) - haml-rails (~> 2.0) + haml-rails (~> 3.0) haml_lint hcaptcha (~> 7.1) hiredis (~> 0.6) From 45219dbf64805746a472e50bb7c9bcb52972ab2a Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 30 Sep 2025 11:40:58 +0200 Subject: [PATCH 044/853] Fix spurious notification of local boosters and quoters when updating quote policy (#36299) --- .../api/v1/statuses/interaction_policies_controller.rb | 2 +- spec/requests/api/v1/statuses/interaction_policies_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/api/v1/statuses/interaction_policies_controller.rb b/app/controllers/api/v1/statuses/interaction_policies_controller.rb index 6e2745806d8d1b..5cfb2d0e8fd185 100644 --- a/app/controllers/api/v1/statuses/interaction_policies_controller.rb +++ b/app/controllers/api/v1/statuses/interaction_policies_controller.rb @@ -22,7 +22,7 @@ def status_params end def broadcast_updates! - DistributionWorker.perform_async(@status.id, { 'update' => true }) + DistributionWorker.perform_async(@status.id, { 'update' => true, 'skip_notifications' => true }) ActivityPub::StatusUpdateDistributionWorker.perform_async(@status.id, { 'updated_at' => Time.now.utc.iso8601 }) end end diff --git a/spec/requests/api/v1/statuses/interaction_policies_spec.rb b/spec/requests/api/v1/statuses/interaction_policies_spec.rb index aa447de17fa19d..321a68cd2519a0 100644 --- a/spec/requests/api/v1/statuses/interaction_policies_spec.rb +++ b/spec/requests/api/v1/statuses/interaction_policies_spec.rb @@ -60,7 +60,7 @@ ) expect(DistributionWorker) - .to have_enqueued_sidekiq_job(status.id, { 'update' => true }) + .to have_enqueued_sidekiq_job(status.id, { 'update' => true, 'skip_notifications' => true }) expect(ActivityPub::StatusUpdateDistributionWorker) .to have_enqueued_sidekiq_job(status.id, { 'updated_at' => anything }) end From 589af7a1cca643199907fbaaaf795314f9a09d3e Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 30 Sep 2025 11:56:03 +0200 Subject: [PATCH 045/853] Change `GET /api/v1/statuses/:id/quotes` to allow listing quotes to other people's posts (#36291) --- .../api/v1/statuses/quotes_controller.rb | 34 ++++++++++--------- app/policies/status_policy.rb | 4 --- spec/requests/api/v1/statuses/quotes_spec.rb | 27 ++++++++++++--- 3 files changed, 40 insertions(+), 25 deletions(-) diff --git a/app/controllers/api/v1/statuses/quotes_controller.rb b/app/controllers/api/v1/statuses/quotes_controller.rb index 962855884ec87c..be3a4edc83d87a 100644 --- a/app/controllers/api/v1/statuses/quotes_controller.rb +++ b/app/controllers/api/v1/statuses/quotes_controller.rb @@ -4,13 +4,13 @@ class Api::V1::Statuses::QuotesController < Api::V1::Statuses::BaseController before_action -> { doorkeeper_authorize! :read, :'read:statuses' }, only: :index before_action -> { doorkeeper_authorize! :write, :'write:statuses' }, only: :revoke - before_action :check_owner! + before_action :set_statuses, only: :index + before_action :set_quote, only: :revoke after_action :insert_pagination_headers, only: :index def index cache_if_unauthenticated! - @statuses = load_statuses render json: @statuses, each_serializer: REST::StatusSerializer end @@ -24,18 +24,26 @@ def revoke private - def check_owner! - authorize @status, :list_quotes? - end - def set_quote @quote = @status.quotes.find_by!(status_id: params[:id]) end - def load_statuses + def set_statuses scope = default_statuses scope = scope.not_excluded_by_account(current_account) unless current_account.nil? - scope.merge(paginated_quotes).to_a + @statuses = scope.merge(paginated_quotes).to_a + + # Store next page info before filtering + @records_continue = @statuses.size == limit_param(DEFAULT_STATUSES_LIMIT) + @pagination_since_id = @statuses.first.quote.id unless @statuses.empty? + @pagination_max_id = @statuses.last.quote.id if @records_continue + + if current_account&.id != @status.account_id + domains = @statuses.filter_map(&:account_domain).uniq + account_ids = @statuses.map(&:account_id).uniq + relations = current_account&.relations_map(account_ids, domains) || {} + @statuses.reject! { |status| StatusFilter.new(status, current_account, relations).filtered? } + end end def default_statuses @@ -58,15 +66,9 @@ def prev_path api_v1_status_quotes_url pagination_params(since_id: pagination_since_id) unless @statuses.empty? end - def pagination_max_id - @statuses.last.quote.id - end - - def pagination_since_id - @statuses.first.quote.id - end + attr_reader :pagination_max_id, :pagination_since_id def records_continue? - @statuses.size == limit_param(DEFAULT_STATUSES_LIMIT) + @records_continue end end diff --git a/app/policies/status_policy.rb b/app/policies/status_policy.rb index b7463869959ccb..03ceae718e5493 100644 --- a/app/policies/status_policy.rb +++ b/app/policies/status_policy.rb @@ -36,10 +36,6 @@ def destroy? owned? end - def list_quotes? - owned? - end - alias unreblog? destroy? def update? diff --git a/spec/requests/api/v1/statuses/quotes_spec.rb b/spec/requests/api/v1/statuses/quotes_spec.rb index 9456556ce99fad..01e9e17b07785f 100644 --- a/spec/requests/api/v1/statuses/quotes_spec.rb +++ b/spec/requests/api/v1/statuses/quotes_spec.rb @@ -17,7 +17,7 @@ let!(:accepted_quote) { Fabricate(:quote, quoted_status: status, state: :accepted) } let!(:rejected_quote) { Fabricate(:quote, quoted_status: status, state: :rejected) } let!(:pending_quote) { Fabricate(:quote, quoted_status: status, state: :pending) } - let!(:another_accepted_quote) { Fabricate(:quote, quoted_status: status, state: :accepted) } + let!(:accepted_private_quote) { Fabricate(:quote, status: Fabricate(:status, visibility: :private), quoted_status: status, state: :accepted) } context 'with an OAuth token' do let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } @@ -30,7 +30,7 @@ expect(response) .to have_http_status(200) .and include_pagination_headers( - prev: api_v1_status_quotes_url(limit: 2, since_id: another_accepted_quote.id), + prev: api_v1_status_quotes_url(limit: 2, since_id: accepted_private_quote.id), next: api_v1_status_quotes_url(limit: 2, max_id: accepted_quote.id) ) expect(response.content_type) @@ -39,7 +39,7 @@ expect(response.parsed_body) .to contain_exactly( include(id: accepted_quote.status.id.to_s), - include(id: another_accepted_quote.status.id.to_s) + include(id: accepted_private_quote.status.id.to_s) ) expect(response.parsed_body) @@ -52,12 +52,29 @@ context 'with a different user than the post owner' do let(:status) { Fabricate(:status) } - it 'returns http forbidden' do + it 'returns http success and statuses but not private ones' do subject - expect(response).to have_http_status(403) + expect(response) + .to have_http_status(200) + .and include_pagination_headers( + prev: api_v1_status_quotes_url(limit: 2, since_id: accepted_private_quote.id), + next: api_v1_status_quotes_url(limit: 2, max_id: accepted_quote.id) + ) expect(response.content_type) .to start_with('application/json') + + expect(response.parsed_body) + .to contain_exactly( + include(id: accepted_quote.status.id.to_s) + ) + + expect(response.parsed_body) + .to_not include( + include(id: rejected_quote.status.id.to_s), + include(id: pending_quote.status.id.to_s), + include(id: accepted_private_quote.id.to_s) + ) end end end From ac50e5eebc4300dacb6bef6b76e63e6569f12adc Mon Sep 17 00:00:00 2001 From: Brad Dunbar Date: Tue, 30 Sep 2025 07:14:58 -0400 Subject: [PATCH 046/853] Convert mastodon/initial_state to TypeScript (#36274) --- .../mastodon/containers/compose_container.jsx | 2 +- .../mastodon/containers/mastodon.jsx | 2 +- .../mastodon/features/emoji/index.ts | 2 +- .../features/standalone/status/index.tsx | 2 +- app/javascript/mastodon/features/ui/index.jsx | 2 +- .../mastodon/features/ui/util/focusUtils.ts | 2 +- app/javascript/mastodon/initial_state.js | 145 ------------------ app/javascript/mastodon/initial_state.ts | 141 +++++++++++++++++ app/javascript/mastodon/utils/environment.ts | 2 +- 9 files changed, 148 insertions(+), 152 deletions(-) delete mode 100644 app/javascript/mastodon/initial_state.js create mode 100644 app/javascript/mastodon/initial_state.ts diff --git a/app/javascript/mastodon/containers/compose_container.jsx b/app/javascript/mastodon/containers/compose_container.jsx index a2513cc552da1d..3e6d20c74c4ebd 100644 --- a/app/javascript/mastodon/containers/compose_container.jsx +++ b/app/javascript/mastodon/containers/compose_container.jsx @@ -5,7 +5,7 @@ import { fetchServer } from 'mastodon/actions/server'; import { hydrateStore } from 'mastodon/actions/store'; import { Router } from 'mastodon/components/router'; import Compose from 'mastodon/features/standalone/compose'; -import initialState from 'mastodon/initial_state'; +import { initialState } from 'mastodon/initial_state'; import { IntlProvider } from 'mastodon/locales'; import { store } from 'mastodon/store'; diff --git a/app/javascript/mastodon/containers/mastodon.jsx b/app/javascript/mastodon/containers/mastodon.jsx index 086a7681c403d9..ee861366a50f6a 100644 --- a/app/javascript/mastodon/containers/mastodon.jsx +++ b/app/javascript/mastodon/containers/mastodon.jsx @@ -13,7 +13,7 @@ import ErrorBoundary from 'mastodon/components/error_boundary'; import { Router } from 'mastodon/components/router'; import UI from 'mastodon/features/ui'; import { IdentityContext, createIdentityContext } from 'mastodon/identity_context'; -import initialState, { title as siteTitle } from 'mastodon/initial_state'; +import { initialState, title as siteTitle } from 'mastodon/initial_state'; import { IntlProvider } from 'mastodon/locales'; import { store } from 'mastodon/store'; import { isProduction } from 'mastodon/utils/environment'; diff --git a/app/javascript/mastodon/features/emoji/index.ts b/app/javascript/mastodon/features/emoji/index.ts index 99c16fe361c7fe..d128da6b5362a1 100644 --- a/app/javascript/mastodon/features/emoji/index.ts +++ b/app/javascript/mastodon/features/emoji/index.ts @@ -1,4 +1,4 @@ -import initialState from '@/mastodon/initial_state'; +import { initialState } from '@/mastodon/initial_state'; import { loadWorker } from '@/mastodon/utils/workers'; import { toSupportedLocale } from './locale'; diff --git a/app/javascript/mastodon/features/standalone/status/index.tsx b/app/javascript/mastodon/features/standalone/status/index.tsx index a7850eae1cc112..a53d6e6b237a01 100644 --- a/app/javascript/mastodon/features/standalone/status/index.tsx +++ b/app/javascript/mastodon/features/standalone/status/index.tsx @@ -11,7 +11,7 @@ import { hydrateStore } from 'mastodon/actions/store'; import { Router } from 'mastodon/components/router'; import { DetailedStatus } from 'mastodon/features/status/components/detailed_status'; import { useRenderSignal } from 'mastodon/hooks/useRenderSignal'; -import initialState from 'mastodon/initial_state'; +import { initialState } from 'mastodon/initial_state'; import { IntlProvider } from 'mastodon/locales'; import { makeGetStatus, makeGetPictureInPicture } from 'mastodon/selectors'; import { store, useAppSelector, useAppDispatch } from 'mastodon/store'; diff --git a/app/javascript/mastodon/features/ui/index.jsx b/app/javascript/mastodon/features/ui/index.jsx index efec38caf4b6cc..04c7f33dfd526d 100644 --- a/app/javascript/mastodon/features/ui/index.jsx +++ b/app/javascript/mastodon/features/ui/index.jsx @@ -27,7 +27,7 @@ import { uploadCompose, resetCompose, changeComposeSpoilerness } from '../../act import { clearHeight } from '../../actions/height_cache'; import { fetchServer, fetchServerTranslationLanguages } from '../../actions/server'; import { expandHomeTimeline } from '../../actions/timelines'; -import initialState, { me, owner, singleUserMode, trendsEnabled, trendsAsLanding, disableHoverCards, autoPlayGif } from '../../initial_state'; +import { initialState, me, owner, singleUserMode, trendsEnabled, trendsAsLanding, disableHoverCards, autoPlayGif } from '../../initial_state'; import BundleColumnError from './components/bundle_column_error'; import { NavigationBar } from './components/navigation_bar'; diff --git a/app/javascript/mastodon/features/ui/util/focusUtils.ts b/app/javascript/mastodon/features/ui/util/focusUtils.ts index 9bcd3f894397be..e46ede3553f8c4 100644 --- a/app/javascript/mastodon/features/ui/util/focusUtils.ts +++ b/app/javascript/mastodon/features/ui/util/focusUtils.ts @@ -1,4 +1,4 @@ -import initialState from '@/mastodon/initial_state'; +import { initialState } from '@/mastodon/initial_state'; interface FocusColumnOptions { index?: number; diff --git a/app/javascript/mastodon/initial_state.js b/app/javascript/mastodon/initial_state.js deleted file mode 100644 index 4a078b86f5b0c3..00000000000000 --- a/app/javascript/mastodon/initial_state.js +++ /dev/null @@ -1,145 +0,0 @@ -// @ts-check - -/** - * @typedef {[code: string, name: string, localName: string]} InitialStateLanguage - */ - -/** - * @typedef InitialStateMeta - * @property {string} access_token - * @property {boolean=} advanced_layout - * @property {boolean} auto_play_gif - * @property {boolean} activity_api_enabled - * @property {string} admin - * @property {boolean=} boost_modal - * @property {boolean=} delete_modal - * @property {boolean=} missing_alt_text_modal - * @property {boolean=} disable_swiping - * @property {boolean=} disable_hover_cards - * @property {string=} disabled_account_id - * @property {string} display_media - * @property {string} domain - * @property {boolean=} expand_spoilers - * @property {boolean} limited_federation_mode - * @property {string} locale - * @property {string | null} mascot - * @property {string=} me - * @property {string=} moved_to_account_id - * @property {string=} owner - * @property {boolean} profile_directory - * @property {boolean} registrations_open - * @property {boolean} reduce_motion - * @property {string} repository - * @property {boolean} search_enabled - * @property {boolean} trends_enabled - * @property {boolean} single_user_mode - * @property {string} source_url - * @property {string} streaming_api_base_url - * @property {boolean} timeline_preview - * @property {string} title - * @property {boolean} show_trends - * @property {boolean} trends_as_landing_page - * @property {boolean} use_blurhash - * @property {boolean=} use_pending_items - * @property {string} version - * @property {string} sso_redirect - * @property {string} status_page_url - * @property {boolean} terms_of_service_enabled - * @property {string?} emoji_style - */ - -/** - * @typedef Role - * @property {string} id - * @property {string} name - * @property {string} permissions - * @property {string} color - * @property {boolean} highlighted - */ - -/** - * @typedef InitialState - * @property {Record} accounts - * @property {InitialStateLanguage[]} languages - * @property {boolean=} critical_updates_pending - * @property {InitialStateMeta} meta - * @property {Role?} role - * @property {string[]} features - */ - -const element = document.getElementById('initial-state'); -/** @type {InitialState | undefined} */ -const initialState = element?.textContent && JSON.parse(element.textContent); - -/** @type {string} */ -const initialPath = document.querySelector("head meta[name=initialPath]")?.getAttribute("content") ?? ''; -/** @type {boolean} */ -export const hasMultiColumnPath = initialPath === '/' - || initialPath === '/getting-started' - || initialPath === '/home' - || initialPath.startsWith('/deck'); - -/** - * @template {keyof InitialStateMeta} K - * @param {K} prop - * @returns {InitialStateMeta[K] | undefined} - */ -const getMeta = (prop) => initialState?.meta && initialState.meta[prop]; - -export const activityApiEnabled = getMeta('activity_api_enabled'); -export const autoPlayGif = getMeta('auto_play_gif'); -export const boostModal = getMeta('boost_modal'); -export const deleteModal = getMeta('delete_modal'); -export const missingAltTextModal = getMeta('missing_alt_text_modal'); -export const disableSwiping = getMeta('disable_swiping'); -export const disableHoverCards = getMeta('disable_hover_cards'); -export const disabledAccountId = getMeta('disabled_account_id'); -export const displayMedia = getMeta('display_media'); -export const domain = getMeta('domain'); -export const emojiStyle = getMeta('emoji_style') || 'auto'; -export const expandSpoilers = getMeta('expand_spoilers'); -export const forceSingleColumn = !getMeta('advanced_layout'); -export const limitedFederationMode = getMeta('limited_federation_mode'); -export const mascot = getMeta('mascot'); -export const me = getMeta('me'); -export const movedToAccountId = getMeta('moved_to_account_id'); -export const owner = getMeta('owner'); -export const profile_directory = getMeta('profile_directory'); -export const reduceMotion = getMeta('reduce_motion'); -export const registrationsOpen = getMeta('registrations_open'); -export const repository = getMeta('repository'); -export const searchEnabled = getMeta('search_enabled'); -export const trendsEnabled = getMeta('trends_enabled'); -export const showTrends = getMeta('show_trends'); -export const singleUserMode = getMeta('single_user_mode'); -export const source_url = getMeta('source_url'); -export const timelinePreview = getMeta('timeline_preview'); -export const title = getMeta('title'); -export const trendsAsLanding = getMeta('trends_as_landing_page'); -export const useBlurhash = getMeta('use_blurhash'); -export const usePendingItems = getMeta('use_pending_items'); -export const version = getMeta('version'); -export const criticalUpdatesPending = initialState?.critical_updates_pending; -export const statusPageUrl = getMeta('status_page_url'); -export const sso_redirect = getMeta('sso_redirect'); -export const termsOfServiceEnabled = getMeta('terms_of_service_enabled'); - -const displayNames = Intl.DisplayNames && new Intl.DisplayNames(getMeta('locale'), { - type: 'language', - fallback: 'none', - languageDisplay: 'standard', -}); - -export const languages = initialState?.languages?.map(lang => { - // zh-YUE is not a valid CLDR unicode_language_id - return [lang[0], displayNames?.of(lang[0].replace('zh-YUE', 'yue')) || lang[1], lang[2]]; -}); - -/** - * @returns {string | undefined} - */ -export function getAccessToken() { - return getMeta('access_token'); -} - -export default initialState; diff --git a/app/javascript/mastodon/initial_state.ts b/app/javascript/mastodon/initial_state.ts new file mode 100644 index 00000000000000..b6d7d55483f336 --- /dev/null +++ b/app/javascript/mastodon/initial_state.ts @@ -0,0 +1,141 @@ +import type { ApiAccountJSON } from './api_types/accounts'; + +type InitialStateLanguage = [code: string, name: string, localName: string]; + +interface InitialStateMeta { + access_token: string; + advanced_layout?: boolean; + auto_play_gif: boolean; + activity_api_enabled: boolean; + admin: string; + boost_modal?: boolean; + delete_modal?: boolean; + missing_alt_text_modal?: boolean; + disable_swiping?: boolean; + disable_hover_cards?: boolean; + disabled_account_id?: string; + display_media: string; + domain: string; + expand_spoilers?: boolean; + limited_federation_mode: boolean; + locale: string; + mascot: string | null; + me?: string; + moved_to_account_id?: string; + owner?: string; + profile_directory: boolean; + registrations_open: boolean; + reduce_motion: boolean; + repository: string; + search_enabled: boolean; + trends_enabled: boolean; + single_user_mode: boolean; + source_url: string; + streaming_api_base_url: string; + timeline_preview: boolean; + title: string; + show_trends: boolean; + trends_as_landing_page: boolean; + use_blurhash: boolean; + use_pending_items?: boolean; + version: string; + sso_redirect: string; + status_page_url: string; + terms_of_service_enabled: boolean; + emoji_style?: string; +} + +interface Role { + id: string; + name: string; + permissions: string; + color: string; + highlighted: boolean; +} + +export interface InitialState { + accounts: Record; + languages: InitialStateLanguage[]; + critical_updates_pending?: boolean; + meta: InitialStateMeta; + role?: Role; + features: string[]; +} + +const element = document.getElementById('initial-state'); +export const initialState: InitialState | undefined = element?.textContent + ? (JSON.parse(element.textContent) as InitialState) + : undefined; + +const initialPath: string = + document + .querySelector('head meta[name=initialPath]') + ?.getAttribute('content') ?? ''; +export const hasMultiColumnPath: boolean = + initialPath === '/' || + initialPath === '/getting-started' || + initialPath === '/home' || + initialPath.startsWith('/deck'); + +function getMeta( + prop: K, +): InitialStateMeta[K] | undefined { + return initialState?.meta[prop]; +} + +export const activityApiEnabled = getMeta('activity_api_enabled'); +export const autoPlayGif = getMeta('auto_play_gif'); +export const boostModal = getMeta('boost_modal'); +export const deleteModal = getMeta('delete_modal'); +export const missingAltTextModal = getMeta('missing_alt_text_modal'); +export const disableSwiping = getMeta('disable_swiping'); +export const disableHoverCards = getMeta('disable_hover_cards'); +export const disabledAccountId = getMeta('disabled_account_id'); +export const displayMedia = getMeta('display_media'); +export const domain = getMeta('domain'); +export const emojiStyle = getMeta('emoji_style') ?? 'auto'; +export const expandSpoilers = getMeta('expand_spoilers'); +export const forceSingleColumn = !getMeta('advanced_layout'); +export const limitedFederationMode = getMeta('limited_federation_mode'); +export const mascot = getMeta('mascot'); +export const me = getMeta('me'); +export const movedToAccountId = getMeta('moved_to_account_id'); +export const owner = getMeta('owner'); +export const profile_directory = getMeta('profile_directory'); +export const reduceMotion = getMeta('reduce_motion'); +export const registrationsOpen = getMeta('registrations_open'); +export const repository = getMeta('repository'); +export const searchEnabled = getMeta('search_enabled'); +export const trendsEnabled = getMeta('trends_enabled'); +export const showTrends = getMeta('show_trends'); +export const singleUserMode = getMeta('single_user_mode'); +export const source_url = getMeta('source_url'); +export const timelinePreview = getMeta('timeline_preview'); +export const title = getMeta('title'); +export const trendsAsLanding = getMeta('trends_as_landing_page'); +export const useBlurhash = getMeta('use_blurhash'); +export const usePendingItems = getMeta('use_pending_items'); +export const version = getMeta('version'); +export const criticalUpdatesPending = initialState?.critical_updates_pending; +export const statusPageUrl = getMeta('status_page_url'); +export const sso_redirect = getMeta('sso_redirect'); +export const termsOfServiceEnabled = getMeta('terms_of_service_enabled'); + +const displayNames = new Intl.DisplayNames(getMeta('locale'), { + type: 'language', + fallback: 'none', + languageDisplay: 'standard', +}); + +export const languages = initialState?.languages.map((lang) => { + // zh-YUE is not a valid CLDR unicode_language_id + return [ + lang[0], + displayNames.of(lang[0].replace('zh-YUE', 'yue')) ?? lang[1], + lang[2], + ]; +}); + +export function getAccessToken(): string | undefined { + return getMeta('access_token'); +} diff --git a/app/javascript/mastodon/utils/environment.ts b/app/javascript/mastodon/utils/environment.ts index 2d544417e3d65e..c666e2c94d7866 100644 --- a/app/javascript/mastodon/utils/environment.ts +++ b/app/javascript/mastodon/utils/environment.ts @@ -1,4 +1,4 @@ -import initialState from '../initial_state'; +import { initialState } from '../initial_state'; export function isDevelopment() { if (typeof process !== 'undefined') From c12b8f51c132baeb81652b61f178b7de7b41e424 Mon Sep 17 00:00:00 2001 From: Echo Date: Tue, 30 Sep 2025 15:06:02 +0200 Subject: [PATCH 047/853] Emoji Component (#36293) --- .../mastodon/components/account_bio.tsx | 12 +- .../components/display_name/no-domain.tsx | 12 +- .../components/display_name/simple.tsx | 18 +- .../mastodon/components/emoji/context.tsx | 108 ++++++++++++ .../mastodon/components/emoji/html.tsx | 61 +++++++ .../mastodon/components/emoji/index.tsx | 99 +++++++++++ .../mastodon/components/status_content.jsx | 6 +- .../components/account_header.tsx | 7 +- .../components/conversation.jsx | 5 +- .../mastodon/features/emoji/constants.ts | 2 - .../mastodon/features/emoji/database.ts | 9 +- .../mastodon/features/emoji/emoji_html.tsx | 70 -------- .../mastodon/features/emoji/loader.ts | 6 +- .../mastodon/features/emoji/normalize.test.ts | 23 --- .../mastodon/features/emoji/normalize.ts | 28 ++- .../mastodon/features/emoji/render.test.ts | 101 +---------- .../mastodon/features/emoji/render.ts | 166 +++++++++++++----- .../mastodon/features/emoji/types.ts | 40 ++--- .../mastodon/features/emoji/utils.ts | 12 ++ .../components/embedded_status.tsx | 7 +- app/javascript/types/polymorphic.ts | 75 ++++++++ 21 files changed, 566 insertions(+), 301 deletions(-) create mode 100644 app/javascript/mastodon/components/emoji/context.tsx create mode 100644 app/javascript/mastodon/components/emoji/html.tsx create mode 100644 app/javascript/mastodon/components/emoji/index.tsx delete mode 100644 app/javascript/mastodon/features/emoji/emoji_html.tsx create mode 100644 app/javascript/types/polymorphic.ts diff --git a/app/javascript/mastodon/components/account_bio.tsx b/app/javascript/mastodon/components/account_bio.tsx index b720b4746d0eba..b5ff686f864ead 100644 --- a/app/javascript/mastodon/components/account_bio.tsx +++ b/app/javascript/mastodon/components/account_bio.tsx @@ -1,11 +1,15 @@ import { useCallback } from 'react'; +import classNames from 'classnames'; + import { useLinks } from 'mastodon/hooks/useLinks'; -import { EmojiHTML } from '../features/emoji/emoji_html'; import { useAppSelector } from '../store'; import { isModernEmojiEnabled } from '../utils/environment'; +import { AnimateEmojiProvider } from './emoji/context'; +import { EmojiHTML } from './emoji/html'; + interface AccountBioProps { className: string; accountId: string; @@ -44,13 +48,13 @@ export const AccountBio: React.FC = ({ } return ( -
-
+ ); }; diff --git a/app/javascript/mastodon/components/display_name/no-domain.tsx b/app/javascript/mastodon/components/display_name/no-domain.tsx index 3a66fe5042cd46..bb5a0936593bdc 100644 --- a/app/javascript/mastodon/components/display_name/no-domain.tsx +++ b/app/javascript/mastodon/components/display_name/no-domain.tsx @@ -2,9 +2,10 @@ import type { ComponentPropsWithoutRef, FC } from 'react'; import classNames from 'classnames'; -import { EmojiHTML } from '@/mastodon/features/emoji/emoji_html'; import { isModernEmojiEnabled } from '@/mastodon/utils/environment'; +import { AnimateEmojiProvider } from '../emoji/context'; +import { EmojiHTML } from '../emoji/html'; import { Skeleton } from '../skeleton'; import type { DisplayNameProps } from './index'; @@ -14,9 +15,10 @@ export const DisplayNameWithoutDomain: FC< ComponentPropsWithoutRef<'span'> > = ({ account, className, children, ...props }) => { return ( - {account ? ( @@ -27,8 +29,8 @@ export const DisplayNameWithoutDomain: FC< ? account.get('display_name') : account.get('display_name_html') } - shallow as='strong' + extraEmojis={account.get('emojis')} /> ) : ( @@ -37,6 +39,6 @@ export const DisplayNameWithoutDomain: FC< )} {children} - + ); }; diff --git a/app/javascript/mastodon/components/display_name/simple.tsx b/app/javascript/mastodon/components/display_name/simple.tsx index 3190c4384b2dcc..375f4932b2e2cb 100644 --- a/app/javascript/mastodon/components/display_name/simple.tsx +++ b/app/javascript/mastodon/components/display_name/simple.tsx @@ -1,8 +1,9 @@ import type { ComponentPropsWithoutRef, FC } from 'react'; -import { EmojiHTML } from '@/mastodon/features/emoji/emoji_html'; import { isModernEmojiEnabled } from '@/mastodon/utils/environment'; +import { EmojiHTML } from '../emoji/html'; + import type { DisplayNameProps } from './index'; export const DisplayNameSimple: FC< @@ -12,12 +13,19 @@ export const DisplayNameSimple: FC< if (!account) { return null; } - const accountName = isModernEmojiEnabled() - ? account.get('display_name') - : account.get('display_name_html'); + return ( - + ); }; diff --git a/app/javascript/mastodon/components/emoji/context.tsx b/app/javascript/mastodon/components/emoji/context.tsx new file mode 100644 index 00000000000000..9fda5714d97d4c --- /dev/null +++ b/app/javascript/mastodon/components/emoji/context.tsx @@ -0,0 +1,108 @@ +import type { MouseEventHandler, PropsWithChildren } from 'react'; +import { + createContext, + useCallback, + useContext, + useMemo, + useState, +} from 'react'; + +import classNames from 'classnames'; + +import { cleanExtraEmojis } from '@/mastodon/features/emoji/normalize'; +import { autoPlayGif } from '@/mastodon/initial_state'; +import { polymorphicForwardRef } from '@/types/polymorphic'; +import type { + CustomEmojiMapArg, + ExtraCustomEmojiMap, +} from 'mastodon/features/emoji/types'; + +// Animation context +export const AnimateEmojiContext = createContext(null); + +// Polymorphic provider component +type AnimateEmojiProviderProps = Required & { + className?: string; +}; + +export const AnimateEmojiProvider = polymorphicForwardRef< + 'div', + AnimateEmojiProviderProps +>( + ( + { + children, + as: Wrapper = 'div', + className, + onMouseEnter, + onMouseLeave, + ...props + }, + ref, + ) => { + const [animate, setAnimate] = useState(autoPlayGif ?? false); + + const handleEnter: MouseEventHandler = useCallback( + (event) => { + onMouseEnter?.(event); + if (!autoPlayGif) { + setAnimate(true); + } + }, + [onMouseEnter], + ); + const handleLeave: MouseEventHandler = useCallback( + (event) => { + onMouseLeave?.(event); + if (!autoPlayGif) { + setAnimate(false); + } + }, + [onMouseLeave], + ); + + // If there's a parent context or GIFs autoplay, we don't need handlers. + const parentContext = useContext(AnimateEmojiContext); + if (parentContext !== null || autoPlayGif === true) { + return ( + + {children} + + ); + } + + return ( + + + {children} + + + ); + }, +); +AnimateEmojiProvider.displayName = 'AnimateEmojiProvider'; + +// Handle custom emoji +export const CustomEmojiContext = createContext({}); + +export const CustomEmojiProvider = ({ + children, + emojis: rawEmojis, +}: PropsWithChildren<{ emojis?: CustomEmojiMapArg }>) => { + const emojis = useMemo(() => cleanExtraEmojis(rawEmojis) ?? {}, [rawEmojis]); + return ( + + {children} + + ); +}; diff --git a/app/javascript/mastodon/components/emoji/html.tsx b/app/javascript/mastodon/components/emoji/html.tsx new file mode 100644 index 00000000000000..a6ecc869c1d8e2 --- /dev/null +++ b/app/javascript/mastodon/components/emoji/html.tsx @@ -0,0 +1,61 @@ +import { useMemo } from 'react'; +import type { ComponentPropsWithoutRef, ElementType } from 'react'; + +import classNames from 'classnames'; + +import type { CustomEmojiMapArg } from '@/mastodon/features/emoji/types'; +import { isModernEmojiEnabled } from '@/mastodon/utils/environment'; +import { htmlStringToComponents } from '@/mastodon/utils/html'; + +import { AnimateEmojiProvider, CustomEmojiProvider } from './context'; +import { textToEmojis } from './index'; + +type EmojiHTMLProps = Omit< + ComponentPropsWithoutRef, + 'dangerouslySetInnerHTML' | 'className' +> & { + htmlString: string; + extraEmojis?: CustomEmojiMapArg; + as?: Element; + className?: string; +}; + +export const ModernEmojiHTML = ({ + extraEmojis, + htmlString, + as: asProp = 'div', // Rename for syntax highlighting + shallow, + className = '', + ...props +}: EmojiHTMLProps) => { + const contents = useMemo( + () => htmlStringToComponents(htmlString, { onText: textToEmojis }), + [htmlString], + ); + + return ( + + + {contents} + + + ); +}; + +export const LegacyEmojiHTML = ( + props: EmojiHTMLProps, +) => { + const { as: asElement, htmlString, extraEmojis, className, ...rest } = props; + const Wrapper = asElement ?? 'div'; + return ( + + ); +}; + +export const EmojiHTML = isModernEmojiEnabled() + ? ModernEmojiHTML + : LegacyEmojiHTML; diff --git a/app/javascript/mastodon/components/emoji/index.tsx b/app/javascript/mastodon/components/emoji/index.tsx new file mode 100644 index 00000000000000..e070eb30dd800e --- /dev/null +++ b/app/javascript/mastodon/components/emoji/index.tsx @@ -0,0 +1,99 @@ +import type { FC } from 'react'; +import { useContext, useEffect, useState } from 'react'; + +import { EMOJI_TYPE_CUSTOM } from '@/mastodon/features/emoji/constants'; +import { useEmojiAppState } from '@/mastodon/features/emoji/hooks'; +import { unicodeHexToUrl } from '@/mastodon/features/emoji/normalize'; +import { + isStateLoaded, + loadEmojiDataToState, + shouldRenderImage, + stringToEmojiState, + tokenizeText, +} from '@/mastodon/features/emoji/render'; + +import { AnimateEmojiContext, CustomEmojiContext } from './context'; + +interface EmojiProps { + code: string; + showFallback?: boolean; + showLoading?: boolean; +} + +export const Emoji: FC = ({ + code, + showFallback = true, + showLoading = true, +}) => { + const customEmoji = useContext(CustomEmojiContext); + + // First, set the emoji state based on the input code. + const [state, setState] = useState(() => + stringToEmojiState(code, customEmoji), + ); + + // If we don't have data, then load emoji data asynchronously. + const appState = useEmojiAppState(); + useEffect(() => { + if (state !== null) { + void loadEmojiDataToState(state, appState.currentLocale).then(setState); + } + }, [appState.currentLocale, state]); + + const animate = useContext(AnimateEmojiContext); + const fallback = showFallback ? code : null; + + // If the code is invalid or we otherwise know it's not valid, show the fallback. + if (!state) { + return fallback; + } + + if (!shouldRenderImage(state, appState.mode)) { + return code; + } + + if (!isStateLoaded(state)) { + if (showLoading) { + return ; + } + return fallback; + } + + if (state.type === EMOJI_TYPE_CUSTOM) { + const shortcode = `:${state.code}:`; + return ( + {shortcode} + ); + } + + const src = unicodeHexToUrl(state.code, appState.darkTheme); + + return ( + {state.data.unicode} + ); +}; + +/** + * Takes a text string and converts it to an array of React nodes. + * @param text The text to be tokenized and converted. + */ +export function textToEmojis(text: string) { + return tokenizeText(text).map((token, index) => { + if (typeof token === 'string') { + return token; + } + return ; + }); +} diff --git a/app/javascript/mastodon/components/status_content.jsx b/app/javascript/mastodon/components/status_content.jsx index af0059c7d62850..d766793d87c129 100644 --- a/app/javascript/mastodon/components/status_content.jsx +++ b/app/javascript/mastodon/components/status_content.jsx @@ -13,10 +13,12 @@ import ChevronRightIcon from '@/material-icons/400-24px/chevron_right.svg?react' import { Icon } from 'mastodon/components/icon'; import { Poll } from 'mastodon/components/poll'; import { identityContextPropShape, withIdentity } from 'mastodon/identity_context'; -import { autoPlayGif, languages as preloadedLanguages } from 'mastodon/initial_state'; -import { EmojiHTML } from '../features/emoji/emoji_html'; +import { languages as preloadedLanguages } from 'mastodon/initial_state'; + import { isModernEmojiEnabled } from '../utils/environment'; +import { EmojiHTML } from './emoji/html'; + const MAX_HEIGHT = 706; // 22px * 32 (+ 2px padding at the top) /** diff --git a/app/javascript/mastodon/features/account_timeline/components/account_header.tsx b/app/javascript/mastodon/features/account_timeline/components/account_header.tsx index f58f1f4a8c4c14..2be026c8f92381 100644 --- a/app/javascript/mastodon/features/account_timeline/components/account_header.tsx +++ b/app/javascript/mastodon/features/account_timeline/components/account_header.tsx @@ -8,6 +8,7 @@ import { NavLink } from 'react-router-dom'; import { AccountBio } from '@/mastodon/components/account_bio'; import { DisplayName } from '@/mastodon/components/display_name'; +import { AnimateEmojiProvider } from '@/mastodon/components/emoji/context'; import CheckIcon from '@/material-icons/400-24px/check.svg?react'; import LockIcon from '@/material-icons/400-24px/lock.svg?react'; import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react'; @@ -777,8 +778,8 @@ export const AccountHeader: React.FC<{ )} -
@@ -967,7 +968,7 @@ export const AccountHeader: React.FC<{
)} - + {!(hideTabs || hidden) && (
diff --git a/app/javascript/mastodon/features/direct_timeline/components/conversation.jsx b/app/javascript/mastodon/features/direct_timeline/components/conversation.jsx index bb0815087b080f..fbe37f58a29888 100644 --- a/app/javascript/mastodon/features/direct_timeline/components/conversation.jsx +++ b/app/javascript/mastodon/features/direct_timeline/components/conversation.jsx @@ -25,6 +25,7 @@ import StatusContent from 'mastodon/components/status_content'; import { Dropdown } from 'mastodon/components/dropdown_menu'; import { makeGetStatus } from 'mastodon/selectors'; import { LinkedDisplayName } from '@/mastodon/components/display_name'; +import { AnimateEmojiProvider } from '@/mastodon/components/emoji/context'; const messages = defineMessages({ more: { id: 'status.more', defaultMessage: 'More' }, @@ -136,9 +137,9 @@ export const Conversation = ({ conversation, scrollKey }) => { {unread && }
-
+ {names} }} /> -
+ { if (loadedLocales.has(locale)) { return true; diff --git a/app/javascript/mastodon/features/emoji/emoji_html.tsx b/app/javascript/mastodon/features/emoji/emoji_html.tsx deleted file mode 100644 index b4c352073cec33..00000000000000 --- a/app/javascript/mastodon/features/emoji/emoji_html.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import type { ComponentPropsWithoutRef, ElementType } from 'react'; - -import classNames from 'classnames'; - -import { isModernEmojiEnabled } from '@/mastodon/utils/environment'; - -import { useEmojify } from './hooks'; -import type { CustomEmojiMapArg } from './types'; - -type EmojiHTMLProps = Omit< - ComponentPropsWithoutRef, - 'dangerouslySetInnerHTML' | 'className' -> & { - htmlString: string; - extraEmojis?: CustomEmojiMapArg; - as?: Element; - shallow?: boolean; - className?: string; -}; - -export const ModernEmojiHTML = ({ - extraEmojis, - htmlString, - as: Wrapper = 'div', // Rename for syntax highlighting - shallow, - className = '', - ...props -}: EmojiHTMLProps) => { - const emojifiedHtml = useEmojify({ - text: htmlString, - extraEmojis, - deep: !shallow, - }); - - if (emojifiedHtml === null) { - return null; - } - - return ( - - ); -}; - -export const EmojiHTML = ( - props: EmojiHTMLProps, -) => { - if (isModernEmojiEnabled()) { - return ; - } - const { - as: asElement, - htmlString, - extraEmojis, - className, - shallow: _, - ...rest - } = props; - const Wrapper = asElement ?? 'div'; - return ( - - ); -}; diff --git a/app/javascript/mastodon/features/emoji/loader.ts b/app/javascript/mastodon/features/emoji/loader.ts index 72f57b6f6c0f1f..3196b28b9c6d69 100644 --- a/app/javascript/mastodon/features/emoji/loader.ts +++ b/app/javascript/mastodon/features/emoji/loader.ts @@ -1,8 +1,6 @@ import { flattenEmojiData } from 'emojibase'; import type { CompactEmoji, FlatCompactEmoji } from 'emojibase'; -import type { ApiCustomEmojiJSON } from '@/mastodon/api_types/custom_emoji'; - import { putEmojiData, putCustomEmojiData, @@ -10,7 +8,7 @@ import { putLatestEtag, } from './database'; import { toSupportedLocale, toSupportedLocaleOrCustom } from './locale'; -import type { LocaleOrCustom } from './types'; +import type { CustomEmojiData, LocaleOrCustom } from './types'; import { emojiLogger } from './utils'; const log = emojiLogger('loader'); @@ -27,7 +25,7 @@ export async function importEmojiData(localeString: string) { } export async function importCustomEmojiData() { - const emojis = await fetchAndCheckEtag('custom'); + const emojis = await fetchAndCheckEtag('custom'); if (!emojis) { return; } diff --git a/app/javascript/mastodon/features/emoji/normalize.test.ts b/app/javascript/mastodon/features/emoji/normalize.test.ts index f0ea140590b068..b4c766996112c3 100644 --- a/app/javascript/mastodon/features/emoji/normalize.test.ts +++ b/app/javascript/mastodon/features/emoji/normalize.test.ts @@ -5,11 +5,8 @@ import { flattenEmojiData } from 'emojibase'; import unicodeRawEmojis from 'emojibase-data/en/data.json'; import { - twemojiHasBorder, twemojiToUnicodeInfo, unicodeToTwemojiHex, - CODES_WITH_DARK_BORDER, - CODES_WITH_LIGHT_BORDER, emojiToUnicodeHex, } from './normalize'; @@ -57,26 +54,6 @@ describe('unicodeToTwemojiHex', () => { }); }); -describe('twemojiHasBorder', () => { - test.concurrent.for( - svgFileNames - .filter((file) => file.endsWith('_border')) - .map((file) => { - const hexCode = file.replace('_border', ''); - return [ - hexCode, - CODES_WITH_LIGHT_BORDER.includes(hexCode.toUpperCase()), - CODES_WITH_DARK_BORDER.includes(hexCode.toUpperCase()), - ] as const; - }), - )('twemojiHasBorder for %s', ([hexCode, isLight, isDark], { expect }) => { - const result = twemojiHasBorder(hexCode); - expect(result).toHaveProperty('hexCode', hexCode); - expect(result).toHaveProperty('hasLightBorder', isLight); - expect(result).toHaveProperty('hasDarkBorder', isDark); - }); -}); - describe('twemojiToUnicodeInfo', () => { const unicodeCodeSet = new Set(unicodeEmojis.map((emoji) => emoji.hexcode)); diff --git a/app/javascript/mastodon/features/emoji/normalize.ts b/app/javascript/mastodon/features/emoji/normalize.ts index 959732f9856d19..65667dfe6dd8cd 100644 --- a/app/javascript/mastodon/features/emoji/normalize.ts +++ b/app/javascript/mastodon/features/emoji/normalize.ts @@ -1,5 +1,7 @@ import { isList } from 'immutable'; +import { assetHost } from '@/mastodon/utils/config'; + import { VARIATION_SELECTOR_CODE, KEYCAP_CODE, @@ -9,11 +11,7 @@ import { EMOJIS_WITH_DARK_BORDER, EMOJIS_WITH_LIGHT_BORDER, } from './constants'; -import type { - CustomEmojiMapArg, - ExtraCustomEmojiMap, - TwemojiBorderInfo, -} from './types'; +import type { CustomEmojiMapArg, ExtraCustomEmojiMap } from './types'; // Misc codes that have special handling const SKIER_CODE = 0x26f7; @@ -67,21 +65,17 @@ export const CODES_WITH_DARK_BORDER = export const CODES_WITH_LIGHT_BORDER = EMOJIS_WITH_LIGHT_BORDER.map(emojiToUnicodeHex); -export function twemojiHasBorder(twemojiHex: string): TwemojiBorderInfo { - const normalizedHex = twemojiHex.toUpperCase(); - let hasLightBorder = false; - let hasDarkBorder = false; - if (CODES_WITH_LIGHT_BORDER.includes(normalizedHex)) { - hasLightBorder = true; +export function unicodeHexToUrl(unicodeHex: string, darkMode: boolean): string { + const normalizedHex = unicodeToTwemojiHex(unicodeHex); + let url = `${assetHost}/emoji/${normalizedHex}`; + if (darkMode && CODES_WITH_LIGHT_BORDER.includes(normalizedHex)) { + url += '_border'; } if (CODES_WITH_DARK_BORDER.includes(normalizedHex)) { - hasDarkBorder = true; + url += '_border'; } - return { - hexCode: twemojiHex, - hasLightBorder, - hasDarkBorder, - }; + url += '.svg'; + return url; } interface TwemojiSpecificEmoji { diff --git a/app/javascript/mastodon/features/emoji/render.test.ts b/app/javascript/mastodon/features/emoji/render.test.ts index e9609e15dc5060..108cf747504048 100644 --- a/app/javascript/mastodon/features/emoji/render.test.ts +++ b/app/javascript/mastodon/features/emoji/render.test.ts @@ -1,10 +1,6 @@ import { customEmojiFactory, unicodeEmojiFactory } from '@/testing/factories'; -import { - EMOJI_MODE_NATIVE, - EMOJI_MODE_NATIVE_WITH_FLAGS, - EMOJI_MODE_TWEMOJI, -} from './constants'; +import { EMOJI_MODE_TWEMOJI } from './constants'; import * as db from './database'; import { emojifyElement, @@ -12,7 +8,7 @@ import { testCacheClear, tokenizeText, } from './render'; -import type { EmojiAppState, ExtraCustomEmojiMap } from './types'; +import type { EmojiAppState } from './types'; function mockDatabase() { return { @@ -40,18 +36,6 @@ const expectedSmileImage = '😊'; const expectedFlagImage = '🇪🇺'; -const expectedCustomEmojiImage = - ':custom:'; -const expectedRemoteCustomEmojiImage = - ':remote:'; - -const mockExtraCustom: ExtraCustomEmojiMap = { - remote: { - shortcode: 'remote', - static_url: 'remote.social/static', - url: 'remote.social/custom', - }, -}; function testAppState(state: Partial = {}) { return { @@ -86,64 +70,10 @@ describe('emojifyElement', () => { 'en', ); expect(searchCustomEmojisByShortcodes).toHaveBeenCalledExactlyOnceWith([ - 'custom', + ':custom:', ]); }); - test('emojifies custom emoji in native mode', async () => { - const { searchEmojisByHexcodes } = mockDatabase(); - const actual = await emojifyElement( - testElement(), - testAppState({ mode: EMOJI_MODE_NATIVE }), - ); - assert(actual); - expect(actual.innerHTML).toBe( - `

Hello 😊🇪🇺!

${expectedCustomEmojiImage}

`, - ); - expect(searchEmojisByHexcodes).not.toHaveBeenCalled(); - }); - - test('emojifies flag emoji in native-with-flags mode', async () => { - const { searchEmojisByHexcodes } = mockDatabase(); - const actual = await emojifyElement( - testElement(), - testAppState({ mode: EMOJI_MODE_NATIVE_WITH_FLAGS }), - ); - assert(actual); - expect(actual.innerHTML).toBe( - `

Hello 😊${expectedFlagImage}!

${expectedCustomEmojiImage}

`, - ); - expect(searchEmojisByHexcodes).toHaveBeenCalledOnce(); - }); - - test('emojifies everything in twemoji mode', async () => { - const { searchCustomEmojisByShortcodes, searchEmojisByHexcodes } = - mockDatabase(); - const actual = await emojifyElement(testElement(), testAppState()); - assert(actual); - expect(actual.innerHTML).toBe( - `

Hello ${expectedSmileImage}${expectedFlagImage}!

${expectedCustomEmojiImage}

`, - ); - expect(searchEmojisByHexcodes).toHaveBeenCalledOnce(); - expect(searchCustomEmojisByShortcodes).toHaveBeenCalledOnce(); - }); - - test('emojifies with provided custom emoji', async () => { - const { searchCustomEmojisByShortcodes, searchEmojisByHexcodes } = - mockDatabase(); - const actual = await emojifyElement( - testElement('

hi :remote:

'), - testAppState(), - mockExtraCustom, - ); - assert(actual); - expect(actual.innerHTML).toBe( - `

hi ${expectedRemoteCustomEmojiImage}

`, - ); - expect(searchEmojisByHexcodes).not.toHaveBeenCalled(); - expect(searchCustomEmojisByShortcodes).not.toHaveBeenCalled(); - }); - test('returns null when no emoji are found', async () => { mockDatabase(); const actual = await emojifyElement( @@ -165,28 +95,9 @@ describe('emojifyText', () => { const actual = await emojifyText('Hello 😊🇪🇺!', testAppState()); expect(actual).toBe(`Hello ${expectedSmileImage}${expectedFlagImage}!`); }); - - test('renders custom emojis', async () => { - mockDatabase(); - const actual = await emojifyText('Hello :custom:!', testAppState()); - expect(actual).toBe(`Hello ${expectedCustomEmojiImage}!`); - }); - - test('renders provided extra emojis', async () => { - const actual = await emojifyText( - 'remote emoji :remote:', - testAppState(), - mockExtraCustom, - ); - expect(actual).toBe(`remote emoji ${expectedRemoteCustomEmojiImage}`); - }); }); describe('tokenizeText', () => { - test('returns empty array for string with only whitespace', () => { - expect(tokenizeText(' \n')).toEqual([]); - }); - test('returns an array of text to be a single token', () => { expect(tokenizeText('Hello')).toEqual(['Hello']); }); @@ -212,7 +123,7 @@ describe('tokenizeText', () => { 'Hello ', { type: 'custom', - code: 'smile', + code: ':smile:', }, '!!', ]); @@ -223,7 +134,7 @@ describe('tokenizeText', () => { 'Hello ', { type: 'custom', - code: 'smile_123', + code: ':smile_123:', }, '!!', ]); @@ -239,7 +150,7 @@ describe('tokenizeText', () => { ' ', { type: 'custom', - code: 'smile', + code: ':smile:', }, '!!', ]); diff --git a/app/javascript/mastodon/features/emoji/render.ts b/app/javascript/mastodon/features/emoji/render.ts index 8d2299fd89e682..e0c8fd8dce51e0 100644 --- a/app/javascript/mastodon/features/emoji/render.ts +++ b/app/javascript/mastodon/features/emoji/render.ts @@ -1,6 +1,5 @@ import { autoPlayGif } from '@/mastodon/initial_state'; import { createLimitedCache } from '@/mastodon/utils/cache'; -import { assetHost } from '@/mastodon/utils/config'; import * as perf from '@/mastodon/utils/performance'; import { @@ -8,38 +7,130 @@ import { EMOJI_MODE_NATIVE_WITH_FLAGS, EMOJI_TYPE_UNICODE, EMOJI_TYPE_CUSTOM, - EMOJI_STATE_MISSING, } from './constants'; import { + loadCustomEmojiByShortcode, + loadEmojiByHexcode, + LocaleNotLoadedError, searchCustomEmojisByShortcodes, searchEmojisByHexcodes, } from './database'; -import { - emojiToUnicodeHex, - twemojiHasBorder, - unicodeToTwemojiHex, -} from './normalize'; +import { importEmojiData } from './loader'; +import { emojiToUnicodeHex, unicodeHexToUrl } from './normalize'; import type { - CustomEmojiToken, EmojiAppState, EmojiLoadedState, EmojiMode, EmojiState, + EmojiStateCustom, EmojiStateMap, - EmojiToken, + EmojiStateUnicode, ExtraCustomEmojiMap, LocaleOrCustom, - UnicodeEmojiToken, } from './types'; import { anyEmojiRegex, emojiLogger, + isCustomEmoji, + isUnicodeEmoji, stringHasAnyEmoji, stringHasUnicodeFlags, } from './utils'; const log = emojiLogger('render'); +/** + * Parses emoji string to extract emoji state. + * @param code Hex code or custom shortcode. + * @param customEmoji Extra custom emojis. + */ +export function stringToEmojiState( + code: string, + customEmoji: ExtraCustomEmojiMap = {}, +): EmojiState | null { + if (isUnicodeEmoji(code)) { + return { + type: EMOJI_TYPE_UNICODE, + code: emojiToUnicodeHex(code), + }; + } + + if (isCustomEmoji(code)) { + const shortCode = code.slice(1, -1); + return { + type: EMOJI_TYPE_CUSTOM, + code: shortCode, + data: customEmoji[shortCode], + }; + } + + return null; +} + +/** + * Loads emoji data into the given state if not already loaded. + * @param state Emoji state to load data for. + * @param locale Locale to load data for. Only for Unicode emoji. + * @param retry Internal. Whether this is a retry after loading the locale. + */ +export async function loadEmojiDataToState( + state: EmojiState, + locale: string, + retry = false, +): Promise { + if (isStateLoaded(state)) { + return state; + } + + // First, try to load the data from IndexedDB. + try { + // This is duplicative, but that's because TS can't distinguish the state type easily. + if (state.type === EMOJI_TYPE_UNICODE) { + const data = await loadEmojiByHexcode(state.code, locale); + if (data) { + return { + ...state, + data, + }; + } + } else { + const data = await loadCustomEmojiByShortcode(state.code); + if (data) { + return { + ...state, + data, + }; + } + } + // If not found, assume it's not an emoji and return null. + log( + 'Could not find emoji %s of type %s for locale %s', + state.code, + state.type, + locale, + ); + return null; + } catch (err: unknown) { + // If the locale is not loaded, load it and retry once. + if (!retry && err instanceof LocaleNotLoadedError) { + log( + 'Error loading emoji %s for locale %s, loading locale and retrying.', + state.code, + locale, + ); + await importEmojiData(locale); // Use this from the loader file as it can be awaited. + return loadEmojiDataToState(state, locale, true); + } + + console.warn('Error loading emoji data, not retrying:', state, locale, err); + return null; + } +} + +export function isStateLoaded(state: EmojiState): state is EmojiLoadedState { + return !!state.data; +} + /** * Emojifies an element. This modifies the element in place, replacing text nodes with emojified versions. */ @@ -177,7 +268,11 @@ async function textToElementArray( if (token.type === EMOJI_TYPE_CUSTOM) { const extraEmojiData = extraEmojis[token.code]; if (extraEmojiData) { - state = { type: EMOJI_TYPE_CUSTOM, data: extraEmojiData }; + state = { + type: EMOJI_TYPE_CUSTOM, + data: extraEmojiData, + code: token.code, + }; } else { state = emojiForLocale(token.code, EMOJI_TYPE_CUSTOM); } @@ -189,7 +284,7 @@ async function textToElementArray( } // If the state is valid, create an image element. Otherwise, just append as text. - if (state && typeof state !== 'string') { + if (state && typeof state !== 'string' && isStateLoaded(state)) { const image = stateToImage(state, appState); renderedFragments.push(image); continue; @@ -202,11 +297,11 @@ async function textToElementArray( return renderedFragments; } -type TokenizedText = (string | EmojiToken)[]; +type TokenizedText = (string | EmojiState)[]; export function tokenizeText(text: string): TokenizedText { if (!text.trim()) { - return []; + return [text]; } const tokens = []; @@ -222,14 +317,14 @@ export function tokenizeText(text: string): TokenizedText { // Custom emoji tokens.push({ type: EMOJI_TYPE_CUSTOM, - code: code.slice(1, -1), // Remove the colons - } satisfies CustomEmojiToken); + code, + } satisfies EmojiStateCustom); } else { // Unicode emoji tokens.push({ type: EMOJI_TYPE_UNICODE, code: code, - } satisfies UnicodeEmojiToken); + } satisfies EmojiStateUnicode); } lastIndex = match.index + code.length; } @@ -304,13 +399,11 @@ async function loadMissingEmojiIntoCache( const emojis = await searchEmojisByHexcodes(missingEmojis, currentLocale); const cache = cacheForLocale(currentLocale); for (const emoji of emojis) { - cache.set(emoji.hexcode, { type: EMOJI_TYPE_UNICODE, data: emoji }); - } - const notFoundEmojis = missingEmojis.filter((code) => - emojis.every((emoji) => emoji.hexcode !== code), - ); - for (const code of notFoundEmojis) { - cache.set(code, EMOJI_STATE_MISSING); // Mark as missing if not found, as it's probably not a valid emoji. + cache.set(emoji.hexcode, { + type: EMOJI_TYPE_UNICODE, + data: emoji, + code: emoji.hexcode, + }); } localeCacheMap.set(currentLocale, cache); } @@ -320,19 +413,17 @@ async function loadMissingEmojiIntoCache( const emojis = await searchCustomEmojisByShortcodes(missingEmojis); const cache = cacheForLocale(EMOJI_TYPE_CUSTOM); for (const emoji of emojis) { - cache.set(emoji.shortcode, { type: EMOJI_TYPE_CUSTOM, data: emoji }); - } - const notFoundEmojis = missingEmojis.filter((code) => - emojis.every((emoji) => emoji.shortcode !== code), - ); - for (const code of notFoundEmojis) { - cache.set(code, EMOJI_STATE_MISSING); // Mark as missing if not found, as it's probably not a valid emoji. + cache.set(emoji.shortcode, { + type: EMOJI_TYPE_CUSTOM, + data: emoji, + code: emoji.shortcode, + }); } localeCacheMap.set(EMOJI_TYPE_CUSTOM, cache); } } -function shouldRenderImage(token: EmojiToken, mode: EmojiMode): boolean { +export function shouldRenderImage(token: EmojiState, mode: EmojiMode): boolean { if (token.type === EMOJI_TYPE_UNICODE) { // If the mode is native or native with flags for non-flag emoji // we can just append the text node directly. @@ -354,18 +445,9 @@ function stateToImage(state: EmojiLoadedState, appState: EmojiAppState) { image.classList.add('emojione'); if (state.type === EMOJI_TYPE_UNICODE) { - const emojiInfo = twemojiHasBorder(unicodeToTwemojiHex(state.data.hexcode)); - let fileName = emojiInfo.hexCode; - if ( - (appState.darkTheme && emojiInfo.hasDarkBorder) || - (!appState.darkTheme && emojiInfo.hasLightBorder) - ) { - fileName = `${emojiInfo.hexCode}_border`; - } - image.alt = state.data.unicode; image.title = state.data.label; - image.src = `${assetHost}/emoji/${fileName}.svg`; + image.src = unicodeHexToUrl(state.data.hexcode, appState.darkTheme); } else { // Custom emoji const shortCode = `:${state.data.shortcode}:`; diff --git a/app/javascript/mastodon/features/emoji/types.ts b/app/javascript/mastodon/features/emoji/types.ts index 85bbe6d1a56a8f..043b21361bbf3c 100644 --- a/app/javascript/mastodon/features/emoji/types.ts +++ b/app/javascript/mastodon/features/emoji/types.ts @@ -10,7 +10,6 @@ import type { EMOJI_MODE_NATIVE, EMOJI_MODE_NATIVE_WITH_FLAGS, EMOJI_MODE_TWEMOJI, - EMOJI_STATE_MISSING, EMOJI_TYPE_CUSTOM, EMOJI_TYPE_UNICODE, } from './constants'; @@ -29,45 +28,40 @@ export interface EmojiAppState { darkTheme: boolean; } -export interface UnicodeEmojiToken { - type: typeof EMOJI_TYPE_UNICODE; - code: string; -} -export interface CustomEmojiToken { - type: typeof EMOJI_TYPE_CUSTOM; - code: string; -} -export type EmojiToken = UnicodeEmojiToken | CustomEmojiToken; - export type CustomEmojiData = ApiCustomEmojiJSON; export type UnicodeEmojiData = FlatCompactEmoji; export type AnyEmojiData = CustomEmojiData | UnicodeEmojiData; -export type EmojiStateMissing = typeof EMOJI_STATE_MISSING; +type CustomEmojiRenderFields = Pick< + CustomEmojiData, + 'shortcode' | 'static_url' | 'url' +>; + export interface EmojiStateUnicode { type: typeof EMOJI_TYPE_UNICODE; - data: UnicodeEmojiData; + code: string; + data?: UnicodeEmojiData; } export interface EmojiStateCustom { type: typeof EMOJI_TYPE_CUSTOM; - data: CustomEmojiRenderFields; + code: string; + data?: CustomEmojiRenderFields; } -export type EmojiState = - | EmojiStateMissing - | EmojiStateUnicode - | EmojiStateCustom; -export type EmojiLoadedState = EmojiStateUnicode | EmojiStateCustom; +export type EmojiState = EmojiStateUnicode | EmojiStateCustom; +export type EmojiLoadedState = + | Required + | Required; export type EmojiStateMap = LimitedCache; export type CustomEmojiMapArg = | ExtraCustomEmojiMap | ImmutableList; -export type CustomEmojiRenderFields = Pick< - CustomEmojiData, - 'shortcode' | 'static_url' | 'url' + +export type ExtraCustomEmojiMap = Record< + string, + Pick >; -export type ExtraCustomEmojiMap = Record; export interface TwemojiBorderInfo { hexCode: string; diff --git a/app/javascript/mastodon/features/emoji/utils.ts b/app/javascript/mastodon/features/emoji/utils.ts index ce3591992967d8..e811565c2717f1 100644 --- a/app/javascript/mastodon/features/emoji/utils.ts +++ b/app/javascript/mastodon/features/emoji/utils.ts @@ -10,6 +10,13 @@ export function stringHasUnicodeEmoji(input: string): boolean { return new RegExp(EMOJI_REGEX, supportedFlags()).test(input); } +export function isUnicodeEmoji(input: string): boolean { + return ( + input.length > 0 && + new RegExp(`^(${EMOJI_REGEX})+$`, supportedFlags()).test(input) + ); +} + export function stringHasUnicodeFlags(input: string): boolean { if (supportsRegExpSets()) { return new RegExp( @@ -27,6 +34,11 @@ export function stringHasUnicodeFlags(input: string): boolean { // Constant as this is supported by all browsers. const CUSTOM_EMOJI_REGEX = /:([a-z0-9_]+):/i; + +export function isCustomEmoji(input: string): boolean { + return new RegExp(`^${CUSTOM_EMOJI_REGEX.source}$`, 'i').test(input); +} + export function stringHasCustomEmoji(input: string) { return CUSTOM_EMOJI_REGEX.test(input); } diff --git a/app/javascript/mastodon/features/notifications_v2/components/embedded_status.tsx b/app/javascript/mastodon/features/notifications_v2/components/embedded_status.tsx index a17425169b857c..8e5e72b6aa9713 100644 --- a/app/javascript/mastodon/features/notifications_v2/components/embedded_status.tsx +++ b/app/javascript/mastodon/features/notifications_v2/components/embedded_status.tsx @@ -6,6 +6,7 @@ import { useHistory } from 'react-router-dom'; import type { List as ImmutableList, RecordOf } from 'immutable'; +import { AnimateEmojiProvider } from '@/mastodon/components/emoji/context'; import BarChart4BarsIcon from '@/material-icons/400-24px/bar_chart_4_bars.svg?react'; import PhotoLibraryIcon from '@/material-icons/400-24px/photo_library.svg?react'; import { toggleStatusSpoilers } from 'mastodon/actions/statuses'; @@ -96,8 +97,8 @@ export const EmbeddedStatus: React.FC<{ statusId: string }> = ({ ).size; return ( -
= ({ )}
)} - + ); }; diff --git a/app/javascript/types/polymorphic.ts b/app/javascript/types/polymorphic.ts new file mode 100644 index 00000000000000..e58aa7b75eec4a --- /dev/null +++ b/app/javascript/types/polymorphic.ts @@ -0,0 +1,75 @@ +import { forwardRef } from 'react'; +import type { + ElementType, + ComponentPropsWithRef, + ForwardRefRenderFunction, + ReactElement, + Ref, + ForwardRefExoticComponent, +} from 'react'; + +// This complicated type file is based on the following posts: +// - https://www.tsteele.dev/posts/react-polymorphic-forwardref +// - https://www.kripod.dev/blog/behind-the-as-prop-polymorphism-done-well/ +// - https://github.com/radix-ui/primitives/blob/7101e7d6efb2bff13cc6761023ab85aeec73539e/packages/react/polymorphic/src/forwardRefWithAs.ts +// Whenever we upgrade to React 19 or later, we can remove all this because ref is a prop there. + +// Utils +interface AsProp { + as?: As; +} +type PropsOf = ComponentPropsWithRef; + +/** + * Extract the element instance type (e.g. HTMLButtonElement) from ComponentPropsWithRef: + * - For intrinsic elements, look up in JSX.IntrinsicElements + * - For components, infer from `ComponentPropsWithRef` + */ +type ElementRef = + As extends keyof React.JSX.IntrinsicElements + ? React.JSX.IntrinsicElements[As] extends { ref?: Ref } + ? Inst + : never + : ComponentPropsWithRef extends { ref?: Ref } + ? Inst + : never; + +/** + * Merge additional props with intrinsic/element props for `as`. + * Additional props win on conflicts. + */ +type PolymorphicProps< + As extends ElementType, + AdditionalProps extends object = object, +> = AdditionalProps & + AsProp & + Omit, keyof AdditionalProps | 'ref'>; + +/** + * Signature of a component created with `polymorphicForwardRef`. + */ +type PolymorphicWithRef< + DefaultAs extends ElementType, + AdditionalProps extends object = object, +> = ( + props: PolymorphicProps & { ref?: Ref> }, +) => ReactElement | null; + +/** + * The type of `polymorphicForwardRef`. + */ +type PolyRefFunction = < + DefaultAs extends ElementType, + AdditionalProps extends object = object, +>( + render: ForwardRefRenderFunction< + ElementRef, + PolymorphicProps + >, +) => PolymorphicWithRef & + ForwardRefExoticComponent>; + +/** + * Polymorphic `forwardRef` function. + */ +export const polymorphicForwardRef = forwardRef as PolyRefFunction; From 473bd84c24ac2197ed16c7e4a7f8271653511f8f Mon Sep 17 00:00:00 2001 From: diondiondion Date: Tue, 30 Sep 2025 16:55:25 +0200 Subject: [PATCH 048/853] Update confirmation dialogs for follow button actions "unfollow", "unblock", and "withdraw request" (#36289) --- .../mastodon/components/follow_button.tsx | 25 ++-- .../components/account_header.tsx | 50 ++++---- .../confirmation_modal.tsx | 4 +- .../components/confirmation_modals/index.ts | 2 + .../confirmation_modals/unblock.tsx | 45 ++++++++ .../confirmation_modals/unfollow.tsx | 13 +-- .../withdraw_follow_request.tsx | 45 ++++++++ .../features/ui/components/modal_root.jsx | 4 + app/javascript/mastodon/locales/en.json | 7 +- .../styles/mastodon/components.scss | 109 +++++++++++------- 10 files changed, 218 insertions(+), 86 deletions(-) create mode 100644 app/javascript/mastodon/features/ui/components/confirmation_modals/unblock.tsx create mode 100644 app/javascript/mastodon/features/ui/components/confirmation_modals/withdraw_follow_request.tsx diff --git a/app/javascript/mastodon/components/follow_button.tsx b/app/javascript/mastodon/components/follow_button.tsx index 15a9046848f5ab..97aaecd1aac902 100644 --- a/app/javascript/mastodon/components/follow_button.tsx +++ b/app/javascript/mastodon/components/follow_button.tsx @@ -8,7 +8,6 @@ import { useIdentity } from '@/mastodon/identity_context'; import { fetchRelationships, followAccount, - unblockAccount, unmuteAccount, } from 'mastodon/actions/accounts'; import { openModal } from 'mastodon/actions/modal'; @@ -59,7 +58,8 @@ export const FollowButton: React.FC<{ accountId?: string; compact?: boolean; labelLength?: 'auto' | 'short' | 'long'; -}> = ({ accountId, compact, labelLength = 'auto' }) => { + className?: string; +}> = ({ accountId, compact, labelLength = 'auto', className }) => { const intl = useIntl(); const dispatch = useAppDispatch(); const { signedIn } = useIdentity(); @@ -96,12 +96,24 @@ export const FollowButton: React.FC<{ return; } else if (relationship.muting) { dispatch(unmuteAccount(accountId)); - } else if (account && (relationship.following || relationship.requested)) { + } else if (account && relationship.following) { dispatch( openModal({ modalType: 'CONFIRM_UNFOLLOW', modalProps: { account } }), ); + } else if (account && relationship.requested) { + dispatch( + openModal({ + modalType: 'CONFIRM_WITHDRAW_REQUEST', + modalProps: { account }, + }), + ); } else if (relationship.blocking) { - dispatch(unblockAccount(accountId)); + dispatch( + openModal({ + modalType: 'CONFIRM_UNBLOCK', + modalProps: { account }, + }), + ); } else { dispatch(followAccount(accountId)); } @@ -144,7 +156,7 @@ export const FollowButton: React.FC<{ href='/settings/profile' target='_blank' rel='noopener' - className={classNames('button button-secondary', { + className={classNames(className, 'button button-secondary', { 'button--compact': compact, })} > @@ -158,13 +170,12 @@ export const FollowButton: React.FC<{ onClick={handleClick} disabled={ relationship?.blocked_by || - relationship?.blocking || (!(relationship?.following || relationship?.requested) && (account?.suspended || !!account?.moved)) } secondary={following} compact={compact} - className={following ? 'button--destructive' : undefined} + className={classNames(className, { 'button--destructive': following })} > {label} diff --git a/app/javascript/mastodon/features/account_timeline/components/account_header.tsx b/app/javascript/mastodon/features/account_timeline/components/account_header.tsx index 2be026c8f92381..776157ccf5118e 100644 --- a/app/javascript/mastodon/features/account_timeline/components/account_header.tsx +++ b/app/javascript/mastodon/features/account_timeline/components/account_header.tsx @@ -34,7 +34,6 @@ import { initMuteModal } from 'mastodon/actions/mutes'; import { initReport } from 'mastodon/actions/reports'; import { Avatar } from 'mastodon/components/avatar'; import { Badge, AutomatedBadge, GroupBadge } from 'mastodon/components/badge'; -import { Button } from 'mastodon/components/button'; import { CopyIconButton } from 'mastodon/components/copy_icon_button'; import { FollowersCounter, @@ -384,7 +383,7 @@ export const AccountHeader: React.FC<{ const isRemote = account?.acct !== account?.username; const remoteDomain = isRemote ? account?.acct.split('@')[1] : null; - const menu = useMemo(() => { + const menuItems = useMemo(() => { const arr: MenuItem[] = []; if (!account) { @@ -606,6 +605,15 @@ export const AccountHeader: React.FC<{ handleUnblockDomain, ]); + const menu = accountId !== me && ( + + ); + if (!account) { return null; } @@ -719,21 +727,16 @@ export const AccountHeader: React.FC<{ ); } - if (relationship?.blocking) { + const isMovedAndUnfollowedAccount = account.moved && !relationship?.following; + + if (!isMovedAndUnfollowedAccount) { actionBtn = ( -
diff --git a/app/javascript/flavours/glitch/features/account_timeline/components/account_header.tsx b/app/javascript/flavours/glitch/features/account_timeline/components/account_header.tsx index 06396030eb6b38..fe42d6486fc870 100644 --- a/app/javascript/flavours/glitch/features/account_timeline/components/account_header.tsx +++ b/app/javascript/flavours/glitch/features/account_timeline/components/account_header.tsx @@ -38,7 +38,6 @@ import { AutomatedBadge, GroupBadge, } from 'flavours/glitch/components/badge'; -import { Button } from 'flavours/glitch/components/button'; import { CopyIconButton } from 'flavours/glitch/components/copy_icon_button'; import { Dropdown } from 'flavours/glitch/components/dropdown_menu'; import { FollowButton } from 'flavours/glitch/components/follow_button'; @@ -388,7 +387,7 @@ export const AccountHeader: React.FC<{ const isRemote = account?.acct !== account?.username; const remoteDomain = isRemote ? account?.acct.split('@')[1] : null; - const menu = useMemo(() => { + const menuItems = useMemo(() => { const arr: MenuItem[] = []; if (!account) { @@ -610,6 +609,15 @@ export const AccountHeader: React.FC<{ handleUnblockDomain, ]); + const menu = accountId !== me && ( + + ); + if (!account) { return null; } @@ -723,21 +731,16 @@ export const AccountHeader: React.FC<{ ); } - if (relationship?.blocking) { + const isMovedAndUnfollowedAccount = account.moved && !relationship?.following; + + if (!isMovedAndUnfollowedAccount) { actionBtn = ( - - + ); }; diff --git a/app/javascript/mastodon/features/compose/components/edit_indicator.jsx b/app/javascript/mastodon/features/compose/components/edit_indicator.jsx index 106ff7bdaa41f6..3fa37bb8c8b061 100644 --- a/app/javascript/mastodon/features/compose/components/edit_indicator.jsx +++ b/app/javascript/mastodon/features/compose/components/edit_indicator.jsx @@ -50,9 +50,7 @@ export const EditIndicator = () => { {(status.get('poll') || status.get('media_attachments').size > 0) && ( diff --git a/app/javascript/mastodon/features/compose/components/reply_indicator.jsx b/app/javascript/mastodon/features/compose/components/reply_indicator.jsx index 35733ac23b662c..e746fe6a6d22cb 100644 --- a/app/javascript/mastodon/features/compose/components/reply_indicator.jsx +++ b/app/javascript/mastodon/features/compose/components/reply_indicator.jsx @@ -35,9 +35,7 @@ export const ReplyIndicator = () => { {(status.get('poll') || status.get('media_attachments').size > 0) && ( diff --git a/app/javascript/mastodon/features/directory/components/account_card.tsx b/app/javascript/mastodon/features/directory/components/account_card.tsx index 6dc70532ab0b03..562a72b4e8b854 100644 --- a/app/javascript/mastodon/features/directory/components/account_card.tsx +++ b/app/javascript/mastodon/features/directory/components/account_card.tsx @@ -2,6 +2,7 @@ import { FormattedMessage } from 'react-intl'; import { Link } from 'react-router-dom'; +import { EmojiHTML } from '@/mastodon/components/emoji/html'; import { Avatar } from 'mastodon/components/avatar'; import { DisplayName } from 'mastodon/components/display_name'; import { FollowButton } from 'mastodon/components/follow_button'; @@ -39,9 +40,10 @@ export const AccountCard: React.FC<{ accountId: string }> = ({ accountId }) => { {account.get('note').length > 0 && ( -
)} diff --git a/app/javascript/mastodon/features/emoji/normalize.ts b/app/javascript/mastodon/features/emoji/normalize.ts index 65667dfe6dd8cd..7c4252017b5bed 100644 --- a/app/javascript/mastodon/features/emoji/normalize.ts +++ b/app/javascript/mastodon/features/emoji/normalize.ts @@ -154,6 +154,12 @@ export function cleanExtraEmojis(extraEmojis?: CustomEmojiMapArg) { if (!extraEmojis) { return null; } + if (Array.isArray(extraEmojis)) { + return extraEmojis.reduce( + (acc, emoji) => ({ ...acc, [emoji.shortcode]: emoji }), + {}, + ); + } if (!isList(extraEmojis)) { return extraEmojis; } diff --git a/app/javascript/mastodon/features/emoji/types.ts b/app/javascript/mastodon/features/emoji/types.ts index 043b21361bbf3c..a98d931ea5cfb9 100644 --- a/app/javascript/mastodon/features/emoji/types.ts +++ b/app/javascript/mastodon/features/emoji/types.ts @@ -56,7 +56,8 @@ export type EmojiStateMap = LimitedCache; export type CustomEmojiMapArg = | ExtraCustomEmojiMap - | ImmutableList; + | ImmutableList + | CustomEmoji[]; export type ExtraCustomEmojiMap = Record< string, diff --git a/app/javascript/mastodon/features/follow_requests/components/account_authorize.jsx b/app/javascript/mastodon/features/follow_requests/components/account_authorize.jsx index dd308c87cb1fc3..e865b606fe38e8 100644 --- a/app/javascript/mastodon/features/follow_requests/components/account_authorize.jsx +++ b/app/javascript/mastodon/features/follow_requests/components/account_authorize.jsx @@ -10,9 +10,10 @@ import ImmutablePureComponent from 'react-immutable-pure-component'; import CheckIcon from '@/material-icons/400-24px/check.svg?react'; import CloseIcon from '@/material-icons/400-24px/close.svg?react'; -import { Avatar } from '../../../components/avatar'; -import { DisplayName } from '../../../components/display_name'; -import { IconButton } from '../../../components/icon_button'; +import { Avatar } from '@/mastodon/components/avatar'; +import { DisplayName } from '@/mastodon/components/display_name'; +import { IconButton } from '@/mastodon/components/icon_button'; +import { EmojiHTML } from '@/mastodon/components/emoji/html'; const messages = defineMessages({ authorize: { id: 'follow_request.authorize', defaultMessage: 'Authorize' }, @@ -30,7 +31,6 @@ class AccountAuthorize extends ImmutablePureComponent { render () { const { intl, account, onAuthorize, onReject } = this.props; - const content = { __html: account.get('note_emojified') }; return (
@@ -40,7 +40,11 @@ class AccountAuthorize extends ImmutablePureComponent { -
+
diff --git a/app/javascript/mastodon/features/notifications_v2/components/embedded_status.tsx b/app/javascript/mastodon/features/notifications_v2/components/embedded_status.tsx index 8e5e72b6aa9713..49bf364f05526f 100644 --- a/app/javascript/mastodon/features/notifications_v2/components/embedded_status.tsx +++ b/app/javascript/mastodon/features/notifications_v2/components/embedded_status.tsx @@ -6,6 +6,7 @@ import { useHistory } from 'react-router-dom'; import type { List as ImmutableList, RecordOf } from 'immutable'; +import type { ApiMentionJSON } from '@/mastodon/api_types/statuses'; import { AnimateEmojiProvider } from '@/mastodon/components/emoji/context'; import BarChart4BarsIcon from '@/material-icons/400-24px/bar_chart_4_bars.svg?react'; import PhotoLibraryIcon from '@/material-icons/400-24px/photo_library.svg?react'; @@ -18,7 +19,7 @@ import { useAppSelector, useAppDispatch } from 'mastodon/store'; import { EmbeddedStatusContent } from './embedded_status_content'; -export type Mention = RecordOf<{ url: string; acct: string }>; +export type Mention = RecordOf; export const EmbeddedStatus: React.FC<{ statusId: string }> = ({ statusId, @@ -86,12 +87,9 @@ export const EmbeddedStatus: React.FC<{ statusId: string }> = ({ } // Assign status attributes to variables with a forced type, as status is not yet properly typed - const contentHtml = status.get('contentHtml') as string; - const contentWarning = status.get('spoilerHtml') as string; + const hasContentWarning = !!status.get('spoiler_text'); const poll = status.get('poll'); - const language = status.get('language') as string; - const mentions = status.get('mentions') as ImmutableList; - const expanded = !status.get('hidden') || !contentWarning; + const expanded = !status.get('hidden') || !hasContentWarning; const mediaAttachmentsSize = ( status.get('media_attachments') as ImmutableList ).size; @@ -109,20 +107,16 @@ export const EmbeddedStatus: React.FC<{ statusId: string }> = ({
- {contentWarning && ( - - )} + - {(!contentWarning || expanded) && ( + {(!hasContentWarning || expanded) && ( )} diff --git a/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx b/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx index 855e160fac657d..91c3abde38da31 100644 --- a/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx +++ b/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx @@ -1,4 +1,4 @@ -import { useCallback } from 'react'; +import { useCallback, useMemo } from 'react'; import { useHistory } from 'react-router-dom'; @@ -6,16 +6,22 @@ import type { List } from 'immutable'; import type { History } from 'history'; +import type { ApiMentionJSON } from '@/mastodon/api_types/statuses'; +import { EmojiHTML } from '@/mastodon/components/emoji/html'; +import { useElementHandledLink } from '@/mastodon/components/status/handled_link'; +import type { Status } from '@/mastodon/models/status'; +import { isModernEmojiEnabled } from '@/mastodon/utils/environment'; + import type { Mention } from './embedded_status'; const handleMentionClick = ( history: History, - mention: Mention, + mention: ApiMentionJSON, e: MouseEvent, ) => { if (e.button === 0 && !(e.ctrlKey || e.metaKey)) { e.preventDefault(); - history.push(`/@${mention.get('acct')}`); + history.push(`/@${mention.acct}`); } }; @@ -31,16 +37,26 @@ const handleHashtagClick = ( }; export const EmbeddedStatusContent: React.FC<{ - content: string; - mentions: List; - language: string; + status: Status; className?: string; -}> = ({ content, mentions, language, className }) => { +}> = ({ status, className }) => { const history = useHistory(); + const mentions = useMemo( + () => (status.get('mentions') as List).toJS(), + [status], + ); + const htmlHandlers = useElementHandledLink({ + hashtagAccountId: status.get('account') as string | undefined, + hrefToMentionAccountId(href) { + const mention = mentions.find((item) => item.url === href); + return mention?.id; + }, + }); + const handleContentRef = useCallback( (node: HTMLDivElement | null) => { - if (!node) { + if (!node || isModernEmojiEnabled()) { return; } @@ -53,7 +69,7 @@ export const EmbeddedStatusContent: React.FC<{ link.classList.add('status-link'); - const mention = mentions.find((item) => link.href === item.get('url')); + const mention = mentions.find((item) => link.href === item.url); if (mention) { link.addEventListener( @@ -61,8 +77,8 @@ export const EmbeddedStatusContent: React.FC<{ handleMentionClick.bind(null, history, mention), false, ); - link.setAttribute('title', `@${mention.get('acct')}`); - link.setAttribute('href', `/@${mention.get('acct')}`); + link.setAttribute('title', `@${mention.acct}`); + link.setAttribute('href', `/@${mention.acct}`); } else if ( link.textContent.startsWith('#') || link.previousSibling?.textContent?.endsWith('#') @@ -83,11 +99,12 @@ export const EmbeddedStatusContent: React.FC<{ ); return ( -
); }; diff --git a/app/javascript/mastodon/features/status/components/detailed_status.tsx b/app/javascript/mastodon/features/status/components/detailed_status.tsx index b09e109afb2f64..9b525b616c7caa 100644 --- a/app/javascript/mastodon/features/status/components/detailed_status.tsx +++ b/app/javascript/mastodon/features/status/components/detailed_status.tsx @@ -394,17 +394,13 @@ export const DetailedStatus: React.FC<{ /> )} - {status.get('spoiler_text').length > 0 && - (!matchedFilters || showDespiteFilter) && ( - - )} + {(!matchedFilters || showDespiteFilter) && ( + + )} {expanded && ( <> From 5c92312d4d3b96c076fd384d01e7ff9c0958e3dc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 8 Oct 2025 16:19:27 +0200 Subject: [PATCH 108/853] Update dependency cross-env to v10.1.0 (#36297) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 6dc3809d4b5905..20d256424aa9ca 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6173,15 +6173,15 @@ __metadata: linkType: hard "cross-env@npm:^10.0.0": - version: 10.0.0 - resolution: "cross-env@npm:10.0.0" + version: 10.1.0 + resolution: "cross-env@npm:10.1.0" dependencies: "@epic-web/invariant": "npm:^1.0.0" cross-spawn: "npm:^7.0.6" bin: cross-env: dist/bin/cross-env.js cross-env-shell: dist/bin/cross-env-shell.js - checksum: 10c0/d16ffc3734106577d57b6253d81ab50294623bd59f96e161033eaf99c1c308ffbaba8463c23a6c0f72e841eff467cb7007a0a551f27554fcf2bbf6598cd828f9 + checksum: 10c0/834a862db456ba1fedf6c6da43436b123ae38f514fa286d6f0937c14fa83f13469f77f70f2812db041ae2d84f82bac627040b8686030aca27fbdf113dfa38b63 languageName: node linkType: hard From babb7b2b9d13d6c9041edfe3ab6fe9fba708709c Mon Sep 17 00:00:00 2001 From: Echo Date: Wed, 8 Oct 2025 17:07:01 +0200 Subject: [PATCH 109/853] Emoji: Announcements (#36397) Co-authored-by: diondiondion --- .../mastodon/api_types/announcements.ts | 28 +++++ .../mastodon/features/emoji/normalize.ts | 16 +-- .../mastodon/features/emoji/types.ts | 3 +- .../components/announcements/announcement.tsx | 119 ++++++++++++++++++ .../components/announcements/index.tsx | 118 +++++++++++++++++ .../components/announcements/reactions.tsx | 108 ++++++++++++++++ .../mastodon/features/home_timeline/index.jsx | 4 +- 7 files changed, 385 insertions(+), 11 deletions(-) create mode 100644 app/javascript/mastodon/api_types/announcements.ts create mode 100644 app/javascript/mastodon/features/home_timeline/components/announcements/announcement.tsx create mode 100644 app/javascript/mastodon/features/home_timeline/components/announcements/index.tsx create mode 100644 app/javascript/mastodon/features/home_timeline/components/announcements/reactions.tsx diff --git a/app/javascript/mastodon/api_types/announcements.ts b/app/javascript/mastodon/api_types/announcements.ts new file mode 100644 index 00000000000000..03e8922d8f189f --- /dev/null +++ b/app/javascript/mastodon/api_types/announcements.ts @@ -0,0 +1,28 @@ +// See app/serializers/rest/announcement_serializer.rb + +import type { ApiCustomEmojiJSON } from './custom_emoji'; +import type { ApiMentionJSON, ApiStatusJSON, ApiTagJSON } from './statuses'; + +export interface ApiAnnouncementJSON { + id: string; + content: string; + starts_at: null | string; + ends_at: null | string; + all_day: boolean; + published_at: string; + updated_at: null | string; + read: boolean; + mentions: ApiMentionJSON[]; + statuses: ApiStatusJSON[]; + tags: ApiTagJSON[]; + emojis: ApiCustomEmojiJSON[]; + reactions: ApiAnnouncementReactionJSON[]; +} + +export interface ApiAnnouncementReactionJSON { + name: string; + count: number; + me: boolean; + url?: string; + static_url?: string; +} diff --git a/app/javascript/mastodon/features/emoji/normalize.ts b/app/javascript/mastodon/features/emoji/normalize.ts index 7c4252017b5bed..a09505e97fc545 100644 --- a/app/javascript/mastodon/features/emoji/normalize.ts +++ b/app/javascript/mastodon/features/emoji/normalize.ts @@ -160,15 +160,15 @@ export function cleanExtraEmojis(extraEmojis?: CustomEmojiMapArg) { {}, ); } - if (!isList(extraEmojis)) { - return extraEmojis; + if (isList(extraEmojis)) { + return extraEmojis + .toJS() + .reduce( + (acc, emoji) => ({ ...acc, [emoji.shortcode]: emoji }), + {}, + ); } - return extraEmojis - .toJSON() - .reduce( - (acc, emoji) => ({ ...acc, [emoji.shortcode]: emoji }), - {}, - ); + return extraEmojis; } function hexStringToNumbers(hexString: string): number[] { diff --git a/app/javascript/mastodon/features/emoji/types.ts b/app/javascript/mastodon/features/emoji/types.ts index a98d931ea5cfb9..b55cefb0a5e218 100644 --- a/app/javascript/mastodon/features/emoji/types.ts +++ b/app/javascript/mastodon/features/emoji/types.ts @@ -57,7 +57,8 @@ export type EmojiStateMap = LimitedCache; export type CustomEmojiMapArg = | ExtraCustomEmojiMap | ImmutableList - | CustomEmoji[]; + | CustomEmoji[] + | ApiCustomEmojiJSON[]; export type ExtraCustomEmojiMap = Record< string, diff --git a/app/javascript/mastodon/features/home_timeline/components/announcements/announcement.tsx b/app/javascript/mastodon/features/home_timeline/components/announcements/announcement.tsx new file mode 100644 index 00000000000000..8513e6169bd5e8 --- /dev/null +++ b/app/javascript/mastodon/features/home_timeline/components/announcements/announcement.tsx @@ -0,0 +1,119 @@ +import { useEffect, useState } from 'react'; +import type { FC } from 'react'; + +import { FormattedDate, FormattedMessage } from 'react-intl'; + +import type { ApiAnnouncementJSON } from '@/mastodon/api_types/announcements'; +import { AnimateEmojiProvider } from '@/mastodon/components/emoji/context'; +import { EmojiHTML } from '@/mastodon/components/emoji/html'; + +import { ReactionsBar } from './reactions'; + +export interface IAnnouncement extends ApiAnnouncementJSON { + contentHtml: string; +} + +interface AnnouncementProps { + announcement: IAnnouncement; + selected: boolean; +} + +export const Announcement: FC = ({ + announcement, + selected, +}) => { + const [unread, setUnread] = useState(!announcement.read); + useEffect(() => { + // Only update `unread` marker once the announcement is out of view + if (!selected && unread !== !announcement.read) { + setUnread(!announcement.read); + } + }, [announcement.read, selected, unread]); + + return ( + + + + + {' · '} + + + + + + + + + {unread && } + + ); +}; + +const Timestamp: FC> = ({ + announcement, +}) => { + const startsAt = announcement.starts_at && new Date(announcement.starts_at); + const endsAt = announcement.ends_at && new Date(announcement.ends_at); + const now = new Date(); + const hasTimeRange = startsAt && endsAt; + const skipTime = announcement.all_day; + + if (hasTimeRange) { + const skipYear = + startsAt.getFullYear() === endsAt.getFullYear() && + endsAt.getFullYear() === now.getFullYear(); + const skipEndDate = + startsAt.getDate() === endsAt.getDate() && + startsAt.getMonth() === endsAt.getMonth() && + startsAt.getFullYear() === endsAt.getFullYear(); + return ( + <> + {' '} + -{' '} + + + ); + } + const publishedAt = new Date(announcement.published_at); + return ( + + ); +}; diff --git a/app/javascript/mastodon/features/home_timeline/components/announcements/index.tsx b/app/javascript/mastodon/features/home_timeline/components/announcements/index.tsx new file mode 100644 index 00000000000000..8c7c704849dfdc --- /dev/null +++ b/app/javascript/mastodon/features/home_timeline/components/announcements/index.tsx @@ -0,0 +1,118 @@ +import { useCallback, useState } from 'react'; +import type { FC } from 'react'; + +import { defineMessages, useIntl } from 'react-intl'; + +import type { Map, List } from 'immutable'; + +import ReactSwipeableViews from 'react-swipeable-views'; + +import elephantUIPlane from '@/images/elephant_ui_plane.svg'; +import { CustomEmojiProvider } from '@/mastodon/components/emoji/context'; +import { IconButton } from '@/mastodon/components/icon_button'; +import LegacyAnnouncements from '@/mastodon/features/getting_started/containers/announcements_container'; +import { mascot, reduceMotion } from '@/mastodon/initial_state'; +import { createAppSelector, useAppSelector } from '@/mastodon/store'; +import { isModernEmojiEnabled } from '@/mastodon/utils/environment'; +import ChevronLeftIcon from '@/material-icons/400-24px/chevron_left.svg?react'; +import ChevronRightIcon from '@/material-icons/400-24px/chevron_right.svg?react'; + +import type { IAnnouncement } from './announcement'; +import { Announcement } from './announcement'; + +const messages = defineMessages({ + close: { id: 'lightbox.close', defaultMessage: 'Close' }, + previous: { id: 'lightbox.previous', defaultMessage: 'Previous' }, + next: { id: 'lightbox.next', defaultMessage: 'Next' }, +}); + +const announcementSelector = createAppSelector( + [(state) => state.announcements as Map>>], + (announcements) => + (announcements.get('items')?.toJS() as IAnnouncement[] | undefined) ?? [], +); + +export const ModernAnnouncements: FC = () => { + const intl = useIntl(); + + const announcements = useAppSelector(announcementSelector); + const emojis = useAppSelector((state) => state.custom_emojis); + + const [index, setIndex] = useState(0); + const handleChangeIndex = useCallback( + (idx: number) => { + setIndex(idx % announcements.length); + }, + [announcements.length], + ); + const handleNextIndex = useCallback(() => { + setIndex((prevIndex) => (prevIndex + 1) % announcements.length); + }, [announcements.length]); + const handlePrevIndex = useCallback(() => { + setIndex((prevIndex) => + prevIndex === 0 ? announcements.length - 1 : prevIndex - 1, + ); + }, [announcements.length]); + + if (announcements.length === 0) { + return null; + } + + return ( +
+ + +
+ + + {announcements + .map((announcement, idx) => ( + + )) + .reverse()} + + + + {announcements.length > 1 && ( +
+ + + {index + 1} / {announcements.length} + + +
+ )} +
+
+ ); +}; + +export const Announcements = isModernEmojiEnabled() + ? ModernAnnouncements + : LegacyAnnouncements; diff --git a/app/javascript/mastodon/features/home_timeline/components/announcements/reactions.tsx b/app/javascript/mastodon/features/home_timeline/components/announcements/reactions.tsx new file mode 100644 index 00000000000000..481e87f190bcf9 --- /dev/null +++ b/app/javascript/mastodon/features/home_timeline/components/announcements/reactions.tsx @@ -0,0 +1,108 @@ +import { useCallback, useMemo } from 'react'; +import type { FC, HTMLAttributes } from 'react'; + +import classNames from 'classnames'; + +import type { AnimatedProps } from '@react-spring/web'; +import { animated, useTransition } from '@react-spring/web'; + +import { addReaction, removeReaction } from '@/mastodon/actions/announcements'; +import type { ApiAnnouncementReactionJSON } from '@/mastodon/api_types/announcements'; +import { AnimatedNumber } from '@/mastodon/components/animated_number'; +import { Emoji } from '@/mastodon/components/emoji'; +import { Icon } from '@/mastodon/components/icon'; +import EmojiPickerDropdown from '@/mastodon/features/compose/containers/emoji_picker_dropdown_container'; +import { isUnicodeEmoji } from '@/mastodon/features/emoji/utils'; +import { useAppDispatch } from '@/mastodon/store'; +import AddIcon from '@/material-icons/400-24px/add.svg?react'; + +export const ReactionsBar: FC<{ + reactions: ApiAnnouncementReactionJSON[]; + id: string; +}> = ({ reactions, id }) => { + const visibleReactions = useMemo( + () => reactions.filter((x) => x.count > 0), + [reactions], + ); + + const dispatch = useAppDispatch(); + const handleEmojiPick = useCallback( + (emoji: { native: string }) => { + dispatch(addReaction(id, emoji.native.replaceAll(/:/g, ''))); + }, + [dispatch, id], + ); + + const transitions = useTransition(visibleReactions, { + from: { + scale: 0, + }, + enter: { + scale: 1, + }, + leave: { + scale: 0, + }, + keys: visibleReactions.map((x) => x.name), + }); + + return ( +
+ {transitions(({ scale }, reaction) => ( + `scale(${s})`) }} + id={id} + /> + ))} + + {visibleReactions.length < 8 && ( + } + /> + )} +
+ ); +}; + +const Reaction: FC<{ + reaction: ApiAnnouncementReactionJSON; + id: string; + style: AnimatedProps>['style']; +}> = ({ id, reaction, style }) => { + const dispatch = useAppDispatch(); + const handleClick = useCallback(() => { + if (reaction.me) { + dispatch(removeReaction(id, reaction.name)); + } else { + dispatch(addReaction(id, reaction.name)); + } + }, [dispatch, id, reaction.me, reaction.name]); + + const code = isUnicodeEmoji(reaction.name) + ? reaction.name + : `:${reaction.name}:`; + + return ( + + + + + + + + + ); +}; diff --git a/app/javascript/mastodon/features/home_timeline/index.jsx b/app/javascript/mastodon/features/home_timeline/index.jsx index 39a8355b8993d0..8c5555fd49e01b 100644 --- a/app/javascript/mastodon/features/home_timeline/index.jsx +++ b/app/javascript/mastodon/features/home_timeline/index.jsx @@ -14,7 +14,6 @@ import { SymbolLogo } from 'mastodon/components/logo'; import { fetchAnnouncements, toggleShowAnnouncements } from 'mastodon/actions/announcements'; import { IconWithBadge } from 'mastodon/components/icon_with_badge'; import { NotSignedInIndicator } from 'mastodon/components/not_signed_in_indicator'; -import AnnouncementsContainer from 'mastodon/features/getting_started/containers/announcements_container'; import { identityContextPropShape, withIdentity } from 'mastodon/identity_context'; import { criticalUpdatesPending } from 'mastodon/initial_state'; import { withBreakpoint } from 'mastodon/features/ui/hooks/useBreakpoint'; @@ -27,6 +26,7 @@ import StatusListContainer from '../ui/containers/status_list_container'; import { ColumnSettings } from './components/column_settings'; import { CriticalUpdateBanner } from './components/critical_update_banner'; +import { Announcements } from './components/announcements'; const messages = defineMessages({ title: { id: 'column.home', defaultMessage: 'Home' }, @@ -162,7 +162,7 @@ class HomeTimeline extends PureComponent { pinned={pinned} multiColumn={multiColumn} extraButton={announcementsButton} - appendContent={hasAnnouncements && showAnnouncements && } + appendContent={hasAnnouncements && showAnnouncements && } > From b8444d9bb7885d75112a3cae74b6a5c711c7d547 Mon Sep 17 00:00:00 2001 From: Renaud Chaput Date: Wed, 8 Oct 2025 17:51:53 +0200 Subject: [PATCH 110/853] Do not automatically run Prettier on the streaming server code. (#36400) --- streaming/lint-staged.config.mjs | 1 - 1 file changed, 1 deletion(-) diff --git a/streaming/lint-staged.config.mjs b/streaming/lint-staged.config.mjs index 430a999b9ab144..5f9230acbd55d7 100644 --- a/streaming/lint-staged.config.mjs +++ b/streaming/lint-staged.config.mjs @@ -1,5 +1,4 @@ const config = { - '*': 'prettier --ignore-unknown --write', '*.{js,ts}': 'eslint --fix', '**/*.ts': () => 'tsc -p tsconfig.json --noEmit', }; From 0281768cfdda5a92b1eee2706b13faa22f642c05 Mon Sep 17 00:00:00 2001 From: Echo Date: Mon, 6 Oct 2025 11:31:10 +0200 Subject: [PATCH 111/853] [Glitch] Emoji: Link Replacement Port ffac4cb05f5c5a8f91074c846b74fc1dd0c5faf3 to glitch-soc Signed-off-by: Claire --- .../glitch/components/account_bio.tsx | 40 ++++-- .../flavours/glitch/components/emoji/html.tsx | 105 +++++++++------- .../status/handled_link.stories.tsx | 65 ++++++++++ .../glitch/components/status/handled_link.tsx | 79 ++++++++++++ .../glitch/components/status_content.jsx | 49 ++++++-- app/javascript/flavours/glitch/utils/html.ts | 116 ++++++++++-------- 6 files changed, 338 insertions(+), 116 deletions(-) create mode 100644 app/javascript/flavours/glitch/components/status/handled_link.stories.tsx create mode 100644 app/javascript/flavours/glitch/components/status/handled_link.tsx diff --git a/app/javascript/flavours/glitch/components/account_bio.tsx b/app/javascript/flavours/glitch/components/account_bio.tsx index 97717f47b873f1..8c221239efea58 100644 --- a/app/javascript/flavours/glitch/components/account_bio.tsx +++ b/app/javascript/flavours/glitch/components/account_bio.tsx @@ -6,9 +6,10 @@ import { useLinks } from 'flavours/glitch/hooks/useLinks'; import { useAppSelector } from '../store'; import { isModernEmojiEnabled } from '../utils/environment'; +import type { OnElementHandler } from '../utils/html'; -import { AnimateEmojiProvider } from './emoji/context'; import { EmojiHTML } from './emoji/html'; +import { HandledLink } from './status/handled_link'; interface AccountBioProps { className: string; @@ -24,13 +25,37 @@ export const AccountBio: React.FC = ({ const handleClick = useLinks(showDropdown); const handleNodeChange = useCallback( (node: HTMLDivElement | null) => { - if (!showDropdown || !node || node.childNodes.length === 0) { + if ( + !showDropdown || + !node || + node.childNodes.length === 0 || + isModernEmojiEnabled() + ) { return; } addDropdownToHashtags(node, accountId); }, [showDropdown, accountId], ); + + const handleLink = useCallback( + (element, { key, ...props }) => { + if (element instanceof HTMLAnchorElement) { + return ( + + ); + } + return undefined; + }, + [accountId], + ); + const note = useAppSelector((state) => { const account = state.accounts.get(accountId); if (!account) { @@ -48,13 +73,14 @@ export const AccountBio: React.FC = ({ } return ( - - - + onElement={handleLink} + /> ); }; diff --git a/app/javascript/flavours/glitch/components/emoji/html.tsx b/app/javascript/flavours/glitch/components/emoji/html.tsx index 569b4730a58cb1..dea389426511bc 100644 --- a/app/javascript/flavours/glitch/components/emoji/html.tsx +++ b/app/javascript/flavours/glitch/components/emoji/html.tsx @@ -1,60 +1,79 @@ import { useMemo } from 'react'; -import type { ComponentPropsWithoutRef, ElementType } from 'react'; import classNames from 'classnames'; import type { CustomEmojiMapArg } from '@/flavours/glitch/features/emoji/types'; import { isModernEmojiEnabled } from '@/flavours/glitch/utils/environment'; +import type { OnElementHandler } from '@/flavours/glitch/utils/html'; import { htmlStringToComponents } from '@/flavours/glitch/utils/html'; +import { polymorphicForwardRef } from '@/types/polymorphic'; import { AnimateEmojiProvider, CustomEmojiProvider } from './context'; import { textToEmojis } from './index'; -type EmojiHTMLProps = Omit< - ComponentPropsWithoutRef, - 'dangerouslySetInnerHTML' | 'className' -> & { +interface EmojiHTMLProps { htmlString: string; extraEmojis?: CustomEmojiMapArg; - as?: Element; className?: string; -}; - -export const ModernEmojiHTML = ({ - extraEmojis, - htmlString, - as: asProp = 'div', // Rename for syntax highlighting - shallow, - className = '', - ...props -}: EmojiHTMLProps) => { - const contents = useMemo( - () => htmlStringToComponents(htmlString, { onText: textToEmojis }), - [htmlString], - ); - - return ( - - - {contents} - - - ); -}; - -export const LegacyEmojiHTML = ( - props: EmojiHTMLProps, -) => { - const { as: asElement, htmlString, extraEmojis, className, ...rest } = props; - const Wrapper = asElement ?? 'div'; - return ( - - ); -}; + onElement?: OnElementHandler; +} + +export const ModernEmojiHTML = polymorphicForwardRef<'div', EmojiHTMLProps>( + ( + { + extraEmojis, + htmlString, + as: asProp = 'div', // Rename for syntax highlighting + className = '', + onElement, + ...props + }, + ref, + ) => { + const contents = useMemo( + () => + htmlStringToComponents(htmlString, { onText: textToEmojis, onElement }), + [htmlString, onElement], + ); + + return ( + + + {contents} + + + ); + }, +); +ModernEmojiHTML.displayName = 'ModernEmojiHTML'; + +export const LegacyEmojiHTML = polymorphicForwardRef<'div', EmojiHTMLProps>( + (props, ref) => { + const { + as: asElement, + htmlString, + extraEmojis, + className, + onElement, + ...rest + } = props; + const Wrapper = asElement ?? 'div'; + return ( + + ); + }, +); +LegacyEmojiHTML.displayName = 'LegacyEmojiHTML'; export const EmojiHTML = isModernEmojiEnabled() ? ModernEmojiHTML diff --git a/app/javascript/flavours/glitch/components/status/handled_link.stories.tsx b/app/javascript/flavours/glitch/components/status/handled_link.stories.tsx new file mode 100644 index 00000000000000..abc2aa6cefa2f4 --- /dev/null +++ b/app/javascript/flavours/glitch/components/status/handled_link.stories.tsx @@ -0,0 +1,65 @@ +import type { Meta, StoryObj } from '@storybook/react-vite'; + +import { HashtagMenuController } from '@/flavours/glitch/features/ui/components/hashtag_menu_controller'; +import { accountFactoryState } from '@/testing/factories'; + +import { HoverCardController } from '../hover_card_controller'; + +import type { HandledLinkProps } from './handled_link'; +import { HandledLink } from './handled_link'; + +const meta = { + title: 'Components/Status/HandledLink', + render(args) { + return ( + <> + + + + + ); + }, + args: { + href: 'https://example.com/path/subpath?query=1#hash', + text: 'https://example.com', + }, + parameters: { + state: { + accounts: { + '1': accountFactoryState(), + }, + }, + }, +} satisfies Meta>; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = {}; + +export const Hashtag: Story = { + args: { + text: '#example', + }, +}; + +export const Mention: Story = { + args: { + text: '@user', + }, +}; + +export const InternalLink: Story = { + args: { + href: '/about', + text: 'About', + }, +}; + +export const InvalidURL: Story = { + args: { + href: 'ht!tp://invalid-url', + text: 'ht!tp://invalid-url -- invalid!', + }, +}; diff --git a/app/javascript/flavours/glitch/components/status/handled_link.tsx b/app/javascript/flavours/glitch/components/status/handled_link.tsx new file mode 100644 index 00000000000000..ee41321283b22d --- /dev/null +++ b/app/javascript/flavours/glitch/components/status/handled_link.tsx @@ -0,0 +1,79 @@ +import type { ComponentProps, FC } from 'react'; + +import { Link } from 'react-router-dom'; + +export interface HandledLinkProps { + href: string; + text: string; + hashtagAccountId?: string; + mentionAccountId?: string; +} + +export const HandledLink: FC> = ({ + href, + text, + hashtagAccountId, + mentionAccountId, + ...props +}) => { + // Handle hashtags + if (text.startsWith('#')) { + const hashtag = text.slice(1).trim(); + return ( + + #{hashtag} + + ); + } else if (text.startsWith('@')) { + // Handle mentions + const mention = text.slice(1).trim(); + return ( + + @{mention} + + ); + } + + // Non-absolute paths treated as internal links. + if (href.startsWith('/')) { + return ( + + {text} + + ); + } + + try { + const url = new URL(href); + const [first, ...rest] = url.pathname.split('/').slice(1); // Start at 1 to skip the leading slash. + return ( + + {url.protocol + '//'} + {`${url.hostname}/${first ?? ''}`} + {'/' + rest.join('/')} + + ); + } catch { + return text; + } +}; diff --git a/app/javascript/flavours/glitch/components/status_content.jsx b/app/javascript/flavours/glitch/components/status_content.jsx index 2de11f00032ccf..8b0ec56c823d1e 100644 --- a/app/javascript/flavours/glitch/components/status_content.jsx +++ b/app/javascript/flavours/glitch/components/status_content.jsx @@ -19,6 +19,7 @@ import { decode as decodeIDNA } from 'flavours/glitch/utils/idna'; import { isModernEmojiEnabled } from '../utils/environment'; import { EmojiHTML } from './emoji/html'; +import { HandledLink } from './status/handled_link'; const MAX_HEIGHT = 706; // 22px * 32 (+ 2px padding at the top) @@ -163,6 +164,23 @@ class StatusContent extends PureComponent { } const { status, onCollapsedToggle } = this.props; + if (status.get('collapsed', null) === null && onCollapsedToggle) { + const { collapsible, onClick } = this.props; + + const collapsed = + collapsible + && onClick + && node.clientHeight > MAX_HEIGHT + && status.get('spoiler_text').length === 0; + + onCollapsedToggle(collapsed); + } + + // Exit if modern emoji is enabled, as it handles links using the HandledLink component. + if (isModernEmojiEnabled()) { + return; + } + const links = node.querySelectorAll('a'); let link, mention; @@ -225,18 +243,6 @@ class StatusContent extends PureComponent { } } } - - if (status.get('collapsed', null) === null && onCollapsedToggle) { - const { collapsible, onClick } = this.props; - - const collapsed = - collapsible - && onClick - && node.clientHeight > MAX_HEIGHT - && status.get('spoiler_text').length === 0; - - onCollapsedToggle(collapsed); - } } componentDidMount () { @@ -298,6 +304,23 @@ class StatusContent extends PureComponent { this.node = c; }; + handleElement = (element, {key, ...props}) => { + if (element instanceof HTMLAnchorElement) { + const mention = this.props.status.get('mentions').find(item => element.href === item.get('url')); + return ( + + ); + } + return undefined; + } + render () { const { status, intl, statusContent } = this.props; @@ -342,6 +365,7 @@ class StatusContent extends PureComponent { lang={language} htmlString={content} extraEmojis={status.get('emojis')} + onElement={this.handleElement.bind(this)} /> {poll} @@ -359,6 +383,7 @@ class StatusContent extends PureComponent { lang={language} htmlString={content} extraEmojis={status.get('emojis')} + onElement={this.handleElement.bind(this)} /> {poll} diff --git a/app/javascript/flavours/glitch/utils/html.ts b/app/javascript/flavours/glitch/utils/html.ts index 52b0fb7b7e7dcd..bbda1b7be37192 100644 --- a/app/javascript/flavours/glitch/utils/html.ts +++ b/app/javascript/flavours/glitch/utils/html.ts @@ -32,14 +32,21 @@ interface QueueItem { depth: number; } -export interface HTMLToStringOptions> { +export type OnElementHandler< + Arg extends Record = Record, +> = ( + element: HTMLElement, + props: Record, + children: React.ReactNode[], + extra: Arg, +) => React.ReactNode; + +export interface HTMLToStringOptions< + Arg extends Record = Record, +> { maxDepth?: number; onText?: (text: string, extra: Arg) => React.ReactNode; - onElement?: ( - element: HTMLElement, - children: React.ReactNode[], - extra: Arg, - ) => React.ReactNode; + onElement?: OnElementHandler; onAttribute?: ( name: string, value: string, @@ -125,9 +132,57 @@ export function htmlStringToComponents>( const children: React.ReactNode[] = []; let element: React.ReactNode = undefined; + // Generate props from attributes. + const key = `html-${uniqueIdCounter++}`; // Get the current key and then increment it. + const props: Record = { key }; + for (const attr of node.attributes) { + let name = attr.name.toLowerCase(); + + // Custom attribute handler. + if (onAttribute) { + const result = onAttribute( + name, + attr.value, + node.tagName.toLowerCase(), + extraArgs, + ); + if (result) { + const [cbName, value] = result; + props[cbName] = value; + } + } else { + // Check global attributes first, then tag-specific ones. + const globalAttr = globalAttributes[name]; + const tagAttr = tagInfo.attributes?.[name]; + + // Exit if neither global nor tag-specific attribute is allowed. + if (!globalAttr && !tagAttr) { + continue; + } + + // Rename if needed. + if (typeof tagAttr === 'string') { + name = tagAttr; + } else if (typeof globalAttr === 'string') { + name = globalAttr; + } + + let value: string | boolean | number = attr.value; + + // Handle boolean attributes. + if (value === 'true') { + value = true; + } else if (value === 'false') { + value = false; + } + + props[name] = value; + } + } + // If onElement is provided, use it to create the element. if (onElement) { - const component = onElement(node, children, extraArgs); + const component = onElement(node, props, children, extraArgs); // Check for undefined to allow returning null. if (component !== undefined) { @@ -137,53 +192,6 @@ export function htmlStringToComponents>( // If the element wasn't created, use the default conversion. if (element === undefined) { - const props: Record = {}; - props.key = `html-${uniqueIdCounter++}`; // Get the current key and then increment it. - for (const attr of node.attributes) { - let name = attr.name.toLowerCase(); - - // Custom attribute handler. - if (onAttribute) { - const result = onAttribute( - name, - attr.value, - node.tagName.toLowerCase(), - extraArgs, - ); - if (result) { - const [cbName, value] = result; - props[cbName] = value; - } - } else { - // Check global attributes first, then tag-specific ones. - const globalAttr = globalAttributes[name]; - const tagAttr = tagInfo.attributes?.[name]; - - // Exit if neither global nor tag-specific attribute is allowed. - if (!globalAttr && !tagAttr) { - continue; - } - - // Rename if needed. - if (typeof tagAttr === 'string') { - name = tagAttr; - } else if (typeof globalAttr === 'string') { - name = globalAttr; - } - - let value: string | boolean | number = attr.value; - - // Handle boolean attributes. - if (value === 'true') { - value = true; - } else if (value === 'false') { - value = false; - } - - props[name] = value; - } - } - element = React.createElement( tagName, props, From d5ce785267a544c076fa5daed53ee027b4c741ab Mon Sep 17 00:00:00 2001 From: Echo Date: Mon, 6 Oct 2025 15:34:51 +0200 Subject: [PATCH 112/853] [Glitch] Allow modern_emojis to be enabled purely server-side Port 68a36d5a57269e34c76305b49628a36a87c21b74 to glitch-soc Signed-off-by: Claire --- app/javascript/flavours/glitch/utils/environment.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/app/javascript/flavours/glitch/utils/environment.ts b/app/javascript/flavours/glitch/utils/environment.ts index c666e2c94d7866..c2b6b1cf86a0d3 100644 --- a/app/javascript/flavours/glitch/utils/environment.ts +++ b/app/javascript/flavours/glitch/utils/environment.ts @@ -20,10 +20,7 @@ export function isFeatureEnabled(feature: Features) { export function isModernEmojiEnabled() { try { - return ( - isFeatureEnabled('modern_emojis') && - localStorage.getItem('experiments')?.split(',').includes('modern_emojis') - ); + return isFeatureEnabled('modern_emojis'); } catch { return false; } From d34b4f3fd00657a329fd1f1fc82268b12082763b Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 6 Oct 2025 15:43:20 +0200 Subject: [PATCH 113/853] [Glitch] Add feature to automatically attach quote on eligible link past in Web UI composer Port cda07686dfbbc0b3f8dfbb38a54efa3d126f2c44 to glitch-soc Signed-off-by: Claire --- .../flavours/glitch/actions/compose_typed.ts | 37 +++++++++++++++++++ .../components/autosuggest_textarea.jsx | 5 +-- .../containers/compose_form_container.js | 20 +++++++++- 3 files changed, 56 insertions(+), 6 deletions(-) diff --git a/app/javascript/flavours/glitch/actions/compose_typed.ts b/app/javascript/flavours/glitch/actions/compose_typed.ts index f0219f7da7949b..ec929df8481856 100644 --- a/app/javascript/flavours/glitch/actions/compose_typed.ts +++ b/app/javascript/flavours/glitch/actions/compose_typed.ts @@ -4,6 +4,7 @@ import { createAction } from '@reduxjs/toolkit'; import type { List as ImmutableList, Map as ImmutableMap } from 'immutable'; import { apiUpdateMedia } from 'flavours/glitch/api/compose'; +import { apiGetSearch } from 'flavours/glitch/api/search'; import type { ApiMediaAttachmentJSON } from 'flavours/glitch/api_types/media_attachments'; import type { MediaAttachment } from 'flavours/glitch/models/media_attachment'; import { @@ -16,6 +17,7 @@ import type { Status } from '../models/status'; import { showAlert } from './alerts'; import { focusCompose } from './compose'; +import { importFetchedStatuses } from './importer'; import { openModal } from './modal'; const messages = defineMessages({ @@ -165,6 +167,41 @@ export const quoteComposeById = createAppThunk( }, ); +export const pasteLinkCompose = createDataLoadingThunk( + 'compose/pasteLink', + async ({ url }: { url: string }) => { + return await apiGetSearch({ + q: url, + type: 'statuses', + resolve: true, + limit: 2, + }); + }, + (data, { dispatch, getState }) => { + const composeState = getState().compose; + + if ( + composeState.get('quoted_status_id') || + composeState.get('is_submitting') || + composeState.get('poll') || + composeState.get('is_uploading') + ) + return; + + dispatch(importFetchedStatuses(data.statuses)); + + if ( + data.statuses.length === 1 && + data.statuses[0] && + ['automatic', 'manual'].includes( + data.statuses[0].quote_approval?.current_user ?? 'denied', + ) + ) { + dispatch(quoteComposeById(data.statuses[0].id)); + } + }, +); + export const quoteComposeCancel = createAction('compose/quoteComposeCancel'); export const setComposeQuotePolicy = createAction( diff --git a/app/javascript/flavours/glitch/components/autosuggest_textarea.jsx b/app/javascript/flavours/glitch/components/autosuggest_textarea.jsx index de5accc4b287df..68cf9e17fc92f5 100644 --- a/app/javascript/flavours/glitch/components/autosuggest_textarea.jsx +++ b/app/javascript/flavours/glitch/components/autosuggest_textarea.jsx @@ -150,10 +150,7 @@ const AutosuggestTextarea = forwardRef(({ }, [suggestions, onSuggestionSelected, textareaRef]); const handlePaste = useCallback((e) => { - if (e.clipboardData && e.clipboardData.files.length === 1) { - onPaste(e.clipboardData.files); - e.preventDefault(); - } + onPaste(e); }, [onPaste]); // Show the suggestions again whenever they change and the textarea is focused diff --git a/app/javascript/flavours/glitch/features/compose/containers/compose_form_container.js b/app/javascript/flavours/glitch/features/compose/containers/compose_form_container.js index 239f2f8a3d0a5b..fd7186d71a7a6a 100644 --- a/app/javascript/flavours/glitch/features/compose/containers/compose_form_container.js +++ b/app/javascript/flavours/glitch/features/compose/containers/compose_form_container.js @@ -10,11 +10,14 @@ import { insertEmojiCompose, uploadCompose, } from 'flavours/glitch/actions/compose'; +import { pasteLinkCompose } from 'flavours/glitch/actions/compose_typed'; import { openModal } from 'flavours/glitch/actions/modal'; import { privacyPreference } from 'flavours/glitch/utils/privacy_preference'; import ComposeForm from '../components/compose_form'; +const urlLikeRegex = /^https?:\/\/[^\s]+\/[^\s]+$/i; + const sideArmPrivacy = state => { const inReplyTo = state.getIn(['compose', 'in_reply_to']); const replyPrivacy = inReplyTo ? state.getIn(['statuses', inReplyTo, 'visibility']) : null; @@ -93,8 +96,21 @@ const mapDispatchToProps = (dispatch, props) => ({ dispatch(changeComposeSpoilerText(checked)); }, - onPaste (files) { - dispatch(uploadCompose(files)); + onPaste (e) { + if (e.clipboardData && e.clipboardData.files.length === 1) { + dispatch(uploadCompose(e.clipboardData.files)); + e.preventDefault(); + } else if (e.clipboardData && e.clipboardData.files.length === 0) { + const data = e.clipboardData.getData('text/plain'); + if (!data.match(urlLikeRegex)) return; + + try { + const url = new URL(data); + dispatch(pasteLinkCompose({ url })); + } catch { + return; + } + } }, onPickEmoji (position, data, needsSpace) { From da99ec0eea22209b9d06185f65c3d94fd1448155 Mon Sep 17 00:00:00 2001 From: diondiondion Date: Mon, 6 Oct 2025 16:13:24 +0200 Subject: [PATCH 114/853] [Glitch] Fetch all replies: Only display "More replies found" prompt when there really are new replies Port 474fbb2770a4bff97e25d07897a21acfda373262 to glitch-soc Signed-off-by: Claire --- .../flavours/glitch/actions/statuses_typed.ts | 14 ++- .../status/components/refresh_controller.tsx | 118 +++++++++--------- .../flavours/glitch/reducers/contexts.ts | 109 ++++++++++++---- 3 files changed, 154 insertions(+), 87 deletions(-) diff --git a/app/javascript/flavours/glitch/actions/statuses_typed.ts b/app/javascript/flavours/glitch/actions/statuses_typed.ts index 4472cbad2540bc..039fbf3ac5110a 100644 --- a/app/javascript/flavours/glitch/actions/statuses_typed.ts +++ b/app/javascript/flavours/glitch/actions/statuses_typed.ts @@ -9,8 +9,9 @@ import { importFetchedStatuses } from './importer'; export const fetchContext = createDataLoadingThunk( 'status/context', - ({ statusId }: { statusId: string }) => apiGetContext(statusId), - ({ context, refresh }, { dispatch }) => { + ({ statusId }: { statusId: string; prefetchOnly?: boolean }) => + apiGetContext(statusId), + ({ context, refresh }, { dispatch, actionArg: { prefetchOnly = false } }) => { const statuses = context.ancestors.concat(context.descendants); dispatch(importFetchedStatuses(statuses)); @@ -18,6 +19,7 @@ export const fetchContext = createDataLoadingThunk( return { context, refresh, + prefetchOnly, }; }, ); @@ -26,6 +28,14 @@ export const completeContextRefresh = createAction<{ statusId: string }>( 'status/context/complete', ); +export const showPendingReplies = createAction<{ statusId: string }>( + 'status/context/showPendingReplies', +); + +export const clearPendingReplies = createAction<{ statusId: string }>( + 'status/context/clearPendingReplies', +); + export const setStatusQuotePolicy = createDataLoadingThunk( 'status/setQuotePolicy', ({ statusId, policy }: { statusId: string; policy: ApiQuotePolicy }) => { diff --git a/app/javascript/flavours/glitch/features/status/components/refresh_controller.tsx b/app/javascript/flavours/glitch/features/status/components/refresh_controller.tsx index 1bf5b5b3ef0e5d..d97a211d95dc08 100644 --- a/app/javascript/flavours/glitch/features/status/components/refresh_controller.tsx +++ b/app/javascript/flavours/glitch/features/status/components/refresh_controller.tsx @@ -5,6 +5,8 @@ import { useIntl, defineMessages } from 'react-intl'; import { fetchContext, completeContextRefresh, + showPendingReplies, + clearPendingReplies, } from 'flavours/glitch/actions/statuses'; import type { AsyncRefreshHeader } from 'flavours/glitch/api'; import { apiGetAsyncRefresh } from 'flavours/glitch/api/async_refreshes'; @@ -34,10 +36,6 @@ const messages = defineMessages({ id: 'status.context.loading', defaultMessage: 'Loading', }, - loadingMore: { - id: 'status.context.loading_more', - defaultMessage: 'Loading more replies', - }, success: { id: 'status.context.loading_success', defaultMessage: 'All replies loaded', @@ -52,36 +50,33 @@ const messages = defineMessages({ }, }); -type LoadingState = - | 'idle' - | 'more-available' - | 'loading-initial' - | 'loading-more' - | 'success' - | 'error'; +type LoadingState = 'idle' | 'more-available' | 'loading' | 'success' | 'error'; export const RefreshController: React.FC<{ statusId: string; }> = ({ statusId }) => { - const refresh = useAppSelector( - (state) => state.contexts.refreshing[statusId], - ); - const currentReplyCount = useAppSelector( - (state) => state.contexts.replies[statusId]?.length ?? 0, - ); - const autoRefresh = !currentReplyCount; const dispatch = useAppDispatch(); const intl = useIntl(); - const [loadingState, setLoadingState] = useState( - refresh && autoRefresh ? 'loading-initial' : 'idle', + const refreshHeader = useAppSelector( + (state) => state.contexts.refreshing[statusId], + ); + const hasPendingReplies = useAppSelector( + (state) => !!state.contexts.pendingReplies[statusId]?.length, ); + const [partialLoadingState, setLoadingState] = useState( + refreshHeader ? 'loading' : 'idle', + ); + const loadingState = hasPendingReplies + ? 'more-available' + : partialLoadingState; const [wasDismissed, setWasDismissed] = useState(false); const dismissPrompt = useCallback(() => { setWasDismissed(true); setLoadingState('idle'); - }, []); + dispatch(clearPendingReplies({ statusId })); + }, [dispatch, statusId]); useEffect(() => { let timeoutId: ReturnType; @@ -89,36 +84,51 @@ export const RefreshController: React.FC<{ const scheduleRefresh = (refresh: AsyncRefreshHeader) => { timeoutId = setTimeout(() => { void apiGetAsyncRefresh(refresh.id).then((result) => { - if (result.async_refresh.status === 'finished') { - dispatch(completeContextRefresh({ statusId })); - - if (result.async_refresh.result_count > 0) { - if (autoRefresh) { - void dispatch(fetchContext({ statusId })).then(() => { - setLoadingState('idle'); - }); - } else { - setLoadingState('more-available'); - } - } else { - setLoadingState('idle'); - } - } else { + // If the refresh status is not finished, + // schedule another refresh and exit + if (result.async_refresh.status !== 'finished') { scheduleRefresh(refresh); + return; + } + + // Refresh status is finished. The action below will clear `refreshHeader` + dispatch(completeContextRefresh({ statusId })); + + // Exit if there's nothing to fetch + if (result.async_refresh.result_count === 0) { + setLoadingState('idle'); + return; } + + // A positive result count means there _might_ be new replies, + // so we fetch the context in the background to check if there + // are any new replies. + // If so, they will populate `contexts.pendingReplies[statusId]` + void dispatch(fetchContext({ statusId, prefetchOnly: true })) + .then(() => { + // Reset loading state to `idle` – but if the fetch + // has resulted in new pending replies, the `hasPendingReplies` + // flag will switch the loading state to 'more-available' + setLoadingState('idle'); + }) + .catch(() => { + // Show an error if the fetch failed + setLoadingState('error'); + }); }); }, refresh.retry * 1000); }; - if (refresh && !wasDismissed) { - scheduleRefresh(refresh); - setLoadingState('loading-initial'); + // Initialise a refresh + if (refreshHeader && !wasDismissed) { + scheduleRefresh(refreshHeader); + setLoadingState('loading'); } return () => { clearTimeout(timeoutId); }; - }, [dispatch, statusId, refresh, autoRefresh, wasDismissed]); + }, [dispatch, statusId, refreshHeader, wasDismissed]); useEffect(() => { // Hide success message after a short delay @@ -134,20 +144,19 @@ export const RefreshController: React.FC<{ return () => ''; }, [loadingState]); + useEffect(() => { + // Clear pending replies on unmount + return () => { + dispatch(clearPendingReplies({ statusId })); + }; + }, [dispatch, statusId]); + const handleClick = useCallback(() => { - setLoadingState('loading-more'); - - dispatch(fetchContext({ statusId })) - .then(() => { - setLoadingState('success'); - return ''; - }) - .catch(() => { - setLoadingState('error'); - }); + dispatch(showPendingReplies({ statusId })); + setLoadingState('success'); }, [dispatch, statusId]); - if (loadingState === 'loading-initial') { + if (loadingState === 'loading') { return (
- ; replies: Record; + pendingReplies: Record< + string, + Pick[] + >; refreshing: Record; } const initialState: State = { inReplyTos: {}, replies: {}, + pendingReplies: {}, refreshing: {}, }; +const addReply = ( + state: Draft, + { id, in_reply_to_id }: Pick, +) => { + if (!in_reply_to_id) { + return; + } + + if (!state.inReplyTos[id]) { + const siblings = (state.replies[in_reply_to_id] ??= []); + const index = siblings.findIndex((sibling) => compareId(sibling, id) < 0); + siblings.splice(index + 1, 0, id); + state.inReplyTos[id] = in_reply_to_id; + } +}; + const normalizeContext = ( state: Draft, id: string, { ancestors, descendants }: ApiContextJSON, ): void => { - const addReply = ({ - id, - in_reply_to_id, - }: { - id: string; - in_reply_to_id?: string; - }) => { - if (!in_reply_to_id) { - return; - } - - if (!state.inReplyTos[id]) { - const siblings = (state.replies[in_reply_to_id] ??= []); - const index = siblings.findIndex((sibling) => compareId(sibling, id) < 0); - siblings.splice(index + 1, 0, id); - state.inReplyTos[id] = in_reply_to_id; - } - }; + ancestors.forEach((item) => { + addReply(state, item); + }); // We know in_reply_to_id of statuses but `id` itself. // So we assume that the status of the id replies to last ancestors. - - ancestors.forEach(addReply); - if (ancestors[0]) { - addReply({ + addReply(state, { id, in_reply_to_id: ancestors[ancestors.length - 1]?.id, }); } - descendants.forEach(addReply); + descendants.forEach((item) => { + addReply(state, item); + }); +}; + +const applyPrefetchedReplies = (state: Draft, statusId: string) => { + const pendingReplies = state.pendingReplies[statusId]; + if (pendingReplies?.length) { + pendingReplies.forEach((item) => { + addReply(state, item); + }); + delete state.pendingReplies[statusId]; + } +}; + +const storePrefetchedReplies = ( + state: Draft, + statusId: string, + { descendants }: ApiContextJSON, +): void => { + descendants.forEach(({ id, in_reply_to_id }) => { + if (!in_reply_to_id) { + return; + } + const isNewReply = !state.replies[in_reply_to_id]?.includes(id); + if (isNewReply) { + const pendingReplies = (state.pendingReplies[statusId] ??= []); + pendingReplies.push({ id, in_reply_to_id }); + } + }); }; const deleteFromContexts = (state: Draft, ids: string[]): void => { @@ -129,12 +166,30 @@ const updateContext = (state: Draft, status: ApiStatusJSON): void => { export const contextsReducer = createReducer(initialState, (builder) => { builder .addCase(fetchContext.fulfilled, (state, action) => { - normalizeContext(state, action.meta.arg.statusId, action.payload.context); + if (action.payload.prefetchOnly) { + storePrefetchedReplies( + state, + action.meta.arg.statusId, + action.payload.context, + ); + } else { + normalizeContext( + state, + action.meta.arg.statusId, + action.payload.context, + ); - if (action.payload.refresh) { - state.refreshing[action.meta.arg.statusId] = action.payload.refresh; + if (action.payload.refresh) { + state.refreshing[action.meta.arg.statusId] = action.payload.refresh; + } } }) + .addCase(showPendingReplies, (state, action) => { + applyPrefetchedReplies(state, action.payload.statusId); + }) + .addCase(clearPendingReplies, (state, action) => { + delete state.pendingReplies[action.payload.statusId]; + }) .addCase(completeContextRefresh, (state, action) => { delete state.refreshing[action.payload.statusId]; }) From 7f5232c377f07c8496b1181fb14b189d13bb8575 Mon Sep 17 00:00:00 2001 From: Echo Date: Mon, 6 Oct 2025 18:20:15 +0200 Subject: [PATCH 115/853] [Glitch] Emoji: Remove re: from handleElement in StatusContent Port 9027d604204121808019e4f9b45e5e86565e7f3d to glitch-soc Signed-off-by: Claire --- app/javascript/flavours/glitch/components/status_content.jsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/javascript/flavours/glitch/components/status_content.jsx b/app/javascript/flavours/glitch/components/status_content.jsx index 8b0ec56c823d1e..4cf47adda56697 100644 --- a/app/javascript/flavours/glitch/components/status_content.jsx +++ b/app/javascript/flavours/glitch/components/status_content.jsx @@ -304,7 +304,7 @@ class StatusContent extends PureComponent { this.node = c; }; - handleElement = (element, {key, ...props}) => { + handleElement = (element, { key, ...props }) => { if (element instanceof HTMLAnchorElement) { const mention = this.props.status.get('mentions').find(item => element.href === item.get('url')); return ( @@ -317,6 +317,8 @@ class StatusContent extends PureComponent { key={key} /> ); + } else if (element instanceof HTMLParagraphElement && element.classList.contains('quote-inline')) { + return null; } return undefined; } From 1c278df42488ec1ffb78efab0f90d556bb3f79b3 Mon Sep 17 00:00:00 2001 From: Brad Dunbar Date: Tue, 7 Oct 2025 10:42:15 -0400 Subject: [PATCH 116/853] [Glitch] Resolve typescript eslint warning Port c578a0cb74bdc6492bed58007f8b7971eef43e30 to glitch-soc Signed-off-by: Claire --- app/javascript/flavours/glitch/polyfills/index.ts | 2 +- app/javascript/flavours/glitch/reducers/modal.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/javascript/flavours/glitch/polyfills/index.ts b/app/javascript/flavours/glitch/polyfills/index.ts index 0ff0dd72690cc8..1abfe0a935e2ac 100644 --- a/app/javascript/flavours/glitch/polyfills/index.ts +++ b/app/javascript/flavours/glitch/polyfills/index.ts @@ -19,7 +19,7 @@ export function loadPolyfills() { return Promise.all([ loadIntlPolyfills(), // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- those properties might not exist in old browsers, even if they are always here in types - needsExtraPolyfills && importExtraPolyfills(), + needsExtraPolyfills ? importExtraPolyfills() : Promise.resolve(), loadEmojiPolyfills(), ]); } diff --git a/app/javascript/flavours/glitch/reducers/modal.ts b/app/javascript/flavours/glitch/reducers/modal.ts index 280695ead74db7..7144cb4d226062 100644 --- a/app/javascript/flavours/glitch/reducers/modal.ts +++ b/app/javascript/flavours/glitch/reducers/modal.ts @@ -41,7 +41,7 @@ const popModal = ( modalType === state.get('stack').get(0)?.get('modalType') ) { return state - .set('ignoreFocus', !!ignoreFocus) + .set('ignoreFocus', ignoreFocus) .update('stack', (stack) => stack.shift()); } else { return state; From f870904e5fa50cdf65de82a49ad9560c0770d3d7 Mon Sep 17 00:00:00 2001 From: Echo Date: Tue, 7 Oct 2025 17:21:50 +0200 Subject: [PATCH 117/853] [Glitch] Emoji: Bypass legacy emoji normalization Port 3c9b828c714c71598493fe39231175bb156ef6fd to glitch-soc Signed-off-by: Claire --- .../flavours/glitch/components/account_bio.tsx | 2 +- .../glitch/components/display_name/no-domain.tsx | 8 +------- .../glitch/components/display_name/simple.tsx | 8 +------- .../flavours/glitch/components/status_content.jsx | 3 --- .../flavours/glitch/entrypoints/public.tsx | 2 +- .../flavours/glitch/features/emoji/emoji.js | 13 ++++++++++++- 6 files changed, 16 insertions(+), 20 deletions(-) diff --git a/app/javascript/flavours/glitch/components/account_bio.tsx b/app/javascript/flavours/glitch/components/account_bio.tsx index 8c221239efea58..f620d9c090f19f 100644 --- a/app/javascript/flavours/glitch/components/account_bio.tsx +++ b/app/javascript/flavours/glitch/components/account_bio.tsx @@ -61,7 +61,7 @@ export const AccountBio: React.FC = ({ if (!account) { return ''; } - return isModernEmojiEnabled() ? account.note : account.note_emojified; + return account.note_emojified; }); const extraEmojis = useAppSelector((state) => { const account = state.accounts.get(accountId); diff --git a/app/javascript/flavours/glitch/components/display_name/no-domain.tsx b/app/javascript/flavours/glitch/components/display_name/no-domain.tsx index 5320fba0902469..ee6e84050c3b89 100644 --- a/app/javascript/flavours/glitch/components/display_name/no-domain.tsx +++ b/app/javascript/flavours/glitch/components/display_name/no-domain.tsx @@ -2,8 +2,6 @@ import type { ComponentPropsWithoutRef, FC } from 'react'; import classNames from 'classnames'; -import { isModernEmojiEnabled } from '@/flavours/glitch/utils/environment'; - import { AnimateEmojiProvider } from '../emoji/context'; import { EmojiHTML } from '../emoji/html'; import { Skeleton } from '../skeleton'; @@ -24,11 +22,7 @@ export const DisplayNameWithoutDomain: FC< {account ? ( diff --git a/app/javascript/flavours/glitch/components/display_name/simple.tsx b/app/javascript/flavours/glitch/components/display_name/simple.tsx index 901b0b8fd4992f..29d9ee217b1063 100644 --- a/app/javascript/flavours/glitch/components/display_name/simple.tsx +++ b/app/javascript/flavours/glitch/components/display_name/simple.tsx @@ -1,7 +1,5 @@ import type { ComponentPropsWithoutRef, FC } from 'react'; -import { isModernEmojiEnabled } from '@/flavours/glitch/utils/environment'; - import { EmojiHTML } from '../emoji/html'; import type { DisplayNameProps } from './index'; @@ -19,11 +17,7 @@ export const DisplayNameSimple: FC< diff --git a/app/javascript/flavours/glitch/components/status_content.jsx b/app/javascript/flavours/glitch/components/status_content.jsx index 4cf47adda56697..d3c48dcbe9d7bd 100644 --- a/app/javascript/flavours/glitch/components/status_content.jsx +++ b/app/javascript/flavours/glitch/components/status_content.jsx @@ -84,9 +84,6 @@ const isLinkMisleading = (link) => { * @returns {string} */ export function getStatusContent(status) { - if (isModernEmojiEnabled()) { - return status.getIn(['translation', 'content']) || status.get('content'); - } return status.getIn(['translation', 'contentHtml']) || status.get('contentHtml'); } diff --git a/app/javascript/flavours/glitch/entrypoints/public.tsx b/app/javascript/flavours/glitch/entrypoints/public.tsx index 105b877bc7c3dd..f4300bc119f282 100644 --- a/app/javascript/flavours/glitch/entrypoints/public.tsx +++ b/app/javascript/flavours/glitch/entrypoints/public.tsx @@ -70,7 +70,7 @@ function loaded() { }; document.querySelectorAll('.emojify').forEach((content) => { - content.innerHTML = emojify(content.innerHTML); + content.innerHTML = emojify(content.innerHTML, {}, true); // Force emojify as public doesn't load the new emoji system. }); document diff --git a/app/javascript/flavours/glitch/features/emoji/emoji.js b/app/javascript/flavours/glitch/features/emoji/emoji.js index 55fc382a5def90..cc4948a6c66309 100644 --- a/app/javascript/flavours/glitch/features/emoji/emoji.js +++ b/app/javascript/flavours/glitch/features/emoji/emoji.js @@ -1,5 +1,6 @@ import Trie from 'substring-trie'; +import { isModernEmojiEnabled } from '@/flavours/glitch/utils/environment'; import { assetHost } from 'flavours/glitch/utils/config'; import { autoPlayGif, useSystemEmojiFont } from '../../initial_state'; @@ -148,7 +149,17 @@ const emojifyNode = (node, customEmojis) => { } }; -const emojify = (str, customEmojis = {}) => { +/** + * Legacy emoji processing function. + * @param {string} str + * @param {object} customEmojis + * @param {boolean} force If true, always emojify even if modern emoji is enabled + * @returns {string} + */ +const emojify = (str, customEmojis = {}, force = false) => { + if (isModernEmojiEnabled() && !force) { + return str; + } const wrapper = document.createElement('div'); wrapper.innerHTML = str; From fc1b407d89abf595118a0555cbdca333a38fba53 Mon Sep 17 00:00:00 2001 From: Echo Date: Tue, 7 Oct 2025 17:22:00 +0200 Subject: [PATCH 118/853] [Glitch] Emoji: Compare history modal Port e02ea3e1109b717ffc7fc178ec62eb460cab9703 to glitch-soc Signed-off-by: Claire --- .../ui/components/compare_history_modal.jsx | 85 ++++++++++--------- 1 file changed, 47 insertions(+), 38 deletions(-) diff --git a/app/javascript/flavours/glitch/features/ui/components/compare_history_modal.jsx b/app/javascript/flavours/glitch/features/ui/components/compare_history_modal.jsx index 7e84a578c29aae..78dddf2de003ee 100644 --- a/app/javascript/flavours/glitch/features/ui/components/compare_history_modal.jsx +++ b/app/javascript/flavours/glitch/features/ui/components/compare_history_modal.jsx @@ -15,6 +15,8 @@ import InlineAccount from 'flavours/glitch/components/inline_account'; import MediaAttachments from 'flavours/glitch/components/media_attachments'; import { RelativeTimestamp } from 'flavours/glitch/components/relative_timestamp'; import emojify from 'flavours/glitch/features/emoji/emoji'; +import { EmojiHTML } from '@/flavours/glitch/components/emoji/html'; +import { CustomEmojiProvider } from '@/flavours/glitch/components/emoji/context'; const mapStateToProps = (state, { statusId }) => ({ language: state.getIn(['statuses', statusId, 'language']), @@ -51,8 +53,8 @@ class CompareHistoryModal extends PureComponent { return obj; }, {}); - const content = { __html: emojify(currentVersion.get('content'), emojiMap) }; - const spoilerContent = { __html: emojify(escapeTextContentForBrowser(currentVersion.get('spoiler_text')), emojiMap) }; + const content = emojify(currentVersion.get('content'), emojiMap); + const spoilerContent = emojify(escapeTextContentForBrowser(currentVersion.get('spoiler_text')), emojiMap); const formattedDate = ; const formattedName = ; @@ -65,43 +67,50 @@ class CompareHistoryModal extends PureComponent { return (
-
- - {label} -
- -
-
- {currentVersion.get('spoiler_text').length > 0 && ( - <> -
-
- - )} - -
- - {!!currentVersion.get('poll') && ( -
-
    - {currentVersion.getIn(['poll', 'options']).map(option => ( -
  • - - - -
  • - ))} -
-
- )} - - + +
+ + {label}
-
+ +
+
+ {currentVersion.get('spoiler_text').length > 0 && ( + <> + +
+ + )} + + + + {!!currentVersion.get('poll') && ( +
+
    + {currentVersion.getIn(['poll', 'options']).map(option => ( +
  • + + + +
  • + ))} +
+
+ )} + + +
+
+
); } From c52473eebc8e5d8c887bb9cafdb9c21120a3939d Mon Sep 17 00:00:00 2001 From: diondiondion Date: Tue, 7 Oct 2025 18:43:40 +0200 Subject: [PATCH 119/853] [Glitch] Ensure Fetch-all-replies snackbar is shown at the bottom of the screen Port e4c3854ae8332bc3273e2949b050bd25205c5404 to glitch-soc Signed-off-by: Claire --- .../flavours/glitch/features/status/index.jsx | 2 +- .../flavours/glitch/styles/components.scss | 15 ++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/app/javascript/flavours/glitch/features/status/index.jsx b/app/javascript/flavours/glitch/features/status/index.jsx index d4dfe4074754fc..bc625fa9fd99bd 100644 --- a/app/javascript/flavours/glitch/features/status/index.jsx +++ b/app/javascript/flavours/glitch/features/status/index.jsx @@ -635,7 +635,7 @@ class Status extends ImmutablePureComponent { /> -
+
{ancestors} diff --git a/app/javascript/flavours/glitch/styles/components.scss b/app/javascript/flavours/glitch/styles/components.scss index 6461d5f2b2f123..0457f7515e61e3 100644 --- a/app/javascript/flavours/glitch/styles/components.scss +++ b/app/javascript/flavours/glitch/styles/components.scss @@ -3218,18 +3218,23 @@ a.account__display-name { .column__alert { position: sticky; - bottom: 1rem; + bottom: 0; z-index: 10; box-sizing: border-box; display: grid; width: 100%; max-width: 360px; - padding-inline: 10px; - margin-top: 1rem; - margin-inline: auto; + padding: 1rem; + margin: auto auto 0; + overflow: clip; + + &:empty { + padding: 0; + } @media (max-width: #{$mobile-menu-breakpoint - 1}) { - bottom: 4rem; + // Compensate for mobile menubar + bottom: var(--mobile-bottom-nav-height); } & > * { From c4ef050eb6bb48c0ee12c920375a2224b8d21376 Mon Sep 17 00:00:00 2001 From: Echo Date: Wed, 8 Oct 2025 13:11:25 +0200 Subject: [PATCH 120/853] [Glitch] Emoji: Account page Port 6abda76d13b46c82741de8618e2c141b29fe5355 to glitch-soc Signed-off-by: Claire --- .../{account.tsx => account/index.tsx} | 8 ++- .../glitch/components/account_bio.tsx | 27 ++----- .../glitch/components/account_fields.tsx | 70 ++++++++++++------ .../flavours/glitch/components/emoji/html.tsx | 16 ++++- .../glitch/components/hover_card_account.tsx | 13 +++- .../glitch/components/status/handled_link.tsx | 31 ++++++++ .../glitch/components/verified_badge.tsx | 31 +++++++- .../components/account_header.tsx | 51 +------------ .../flavours/glitch/hooks/useLinks.ts | 7 ++ app/javascript/flavours/glitch/utils/html.ts | 72 ++++++++++--------- 10 files changed, 192 insertions(+), 134 deletions(-) rename app/javascript/flavours/glitch/components/{account.tsx => account/index.tsx} (97%) diff --git a/app/javascript/flavours/glitch/components/account.tsx b/app/javascript/flavours/glitch/components/account/index.tsx similarity index 97% rename from app/javascript/flavours/glitch/components/account.tsx rename to app/javascript/flavours/glitch/components/account/index.tsx index 826d3c3ebb49b0..bcb84f2f4e8016 100644 --- a/app/javascript/flavours/glitch/components/account.tsx +++ b/app/javascript/flavours/glitch/components/account/index.tsx @@ -4,6 +4,7 @@ import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; import classNames from 'classnames'; +import { EmojiHTML } from '@/flavours/glitch/components/emoji/html'; import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react'; import { blockAccount, @@ -33,7 +34,7 @@ import { me } from 'flavours/glitch/initial_state'; import type { MenuItem } from 'flavours/glitch/models/dropdown_menu'; import { useAppSelector, useAppDispatch } from 'flavours/glitch/store'; -import { Permalink } from './permalink'; +import { Permalink } from '../permalink'; const messages = defineMessages({ follow: { id: 'account.follow', defaultMessage: 'Follow' }, @@ -333,9 +334,10 @@ export const Account: React.FC = ({ {account && withBio && (account.note.length > 0 ? ( -
) : (
diff --git a/app/javascript/flavours/glitch/components/account_bio.tsx b/app/javascript/flavours/glitch/components/account_bio.tsx index f620d9c090f19f..fe692151a6fa70 100644 --- a/app/javascript/flavours/glitch/components/account_bio.tsx +++ b/app/javascript/flavours/glitch/components/account_bio.tsx @@ -6,10 +6,9 @@ import { useLinks } from 'flavours/glitch/hooks/useLinks'; import { useAppSelector } from '../store'; import { isModernEmojiEnabled } from '../utils/environment'; -import type { OnElementHandler } from '../utils/html'; import { EmojiHTML } from './emoji/html'; -import { HandledLink } from './status/handled_link'; +import { useElementHandledLink } from './status/handled_link'; interface AccountBioProps { className: string; @@ -38,23 +37,9 @@ export const AccountBio: React.FC = ({ [showDropdown, accountId], ); - const handleLink = useCallback( - (element, { key, ...props }) => { - if (element instanceof HTMLAnchorElement) { - return ( - - ); - } - return undefined; - }, - [accountId], - ); + const htmlHandlers = useElementHandledLink({ + hashtagAccountId: showDropdown ? accountId : undefined, + }); const note = useAppSelector((state) => { const account = state.accounts.get(accountId); @@ -77,9 +62,9 @@ export const AccountBio: React.FC = ({ htmlString={note} extraEmojis={extraEmojis} className={classNames(className, 'translate')} - onClickCapture={isModernEmojiEnabled() ? undefined : handleClick} + onClickCapture={handleClick} ref={handleNodeChange} - onElement={handleLink} + {...htmlHandlers} /> ); }; diff --git a/app/javascript/flavours/glitch/components/account_fields.tsx b/app/javascript/flavours/glitch/components/account_fields.tsx index 768eb1fa4b343d..422dcc4b89fc75 100644 --- a/app/javascript/flavours/glitch/components/account_fields.tsx +++ b/app/javascript/flavours/glitch/components/account_fields.tsx @@ -1,42 +1,70 @@ +import { useIntl } from 'react-intl'; + import classNames from 'classnames'; import CheckIcon from '@/material-icons/400-24px/check.svg?react'; import { Icon } from 'flavours/glitch/components/icon'; -import { useLinks } from 'flavours/glitch/hooks/useLinks'; import type { Account } from 'flavours/glitch/models/account'; -export const AccountFields: React.FC<{ - fields: Account['fields']; - limit: number; -}> = ({ fields, limit = -1 }) => { - const handleClick = useLinks(); +import { CustomEmojiProvider } from './emoji/context'; +import { EmojiHTML } from './emoji/html'; +import { useElementHandledLink } from './status/handled_link'; + +export const AccountFields: React.FC> = ({ + fields, + emojis, +}) => { + const intl = useIntl(); + const htmlHandlers = useElementHandledLink(); if (fields.size === 0) { return null; } return ( -
- {fields.take(limit).map((pair, i) => ( -
-
+ {fields.map((pair, i) => ( +
+ -
- {pair.get('verified_at') && ( - - )} - + {pair.verified_at && ( + + + + )}{' '} +
))} -
+ ); }; + +const dateFormatOptions: Intl.DateTimeFormatOptions = { + month: 'short', + day: 'numeric', + year: 'numeric', + hour: '2-digit', + minute: '2-digit', +}; diff --git a/app/javascript/flavours/glitch/components/emoji/html.tsx b/app/javascript/flavours/glitch/components/emoji/html.tsx index dea389426511bc..b4689101d55f2b 100644 --- a/app/javascript/flavours/glitch/components/emoji/html.tsx +++ b/app/javascript/flavours/glitch/components/emoji/html.tsx @@ -4,7 +4,10 @@ import classNames from 'classnames'; import type { CustomEmojiMapArg } from '@/flavours/glitch/features/emoji/types'; import { isModernEmojiEnabled } from '@/flavours/glitch/utils/environment'; -import type { OnElementHandler } from '@/flavours/glitch/utils/html'; +import type { + OnAttributeHandler, + OnElementHandler, +} from '@/flavours/glitch/utils/html'; import { htmlStringToComponents } from '@/flavours/glitch/utils/html'; import { polymorphicForwardRef } from '@/types/polymorphic'; @@ -16,6 +19,7 @@ interface EmojiHTMLProps { extraEmojis?: CustomEmojiMapArg; className?: string; onElement?: OnElementHandler; + onAttribute?: OnAttributeHandler; } export const ModernEmojiHTML = polymorphicForwardRef<'div', EmojiHTMLProps>( @@ -26,14 +30,19 @@ export const ModernEmojiHTML = polymorphicForwardRef<'div', EmojiHTMLProps>( as: asProp = 'div', // Rename for syntax highlighting className = '', onElement, + onAttribute, ...props }, ref, ) => { const contents = useMemo( () => - htmlStringToComponents(htmlString, { onText: textToEmojis, onElement }), - [htmlString, onElement], + htmlStringToComponents(htmlString, { + onText: textToEmojis, + onElement, + onAttribute, + }), + [htmlString, onAttribute, onElement], ); return ( @@ -60,6 +69,7 @@ export const LegacyEmojiHTML = polymorphicForwardRef<'div', EmojiHTMLProps>( extraEmojis, className, onElement, + onAttribute, ...rest } = props; const Wrapper = asElement ?? 'div'; diff --git a/app/javascript/flavours/glitch/components/hover_card_account.tsx b/app/javascript/flavours/glitch/components/hover_card_account.tsx index 58ce247c58045b..66231f3154c9be 100644 --- a/app/javascript/flavours/glitch/components/hover_card_account.tsx +++ b/app/javascript/flavours/glitch/components/hover_card_account.tsx @@ -23,6 +23,8 @@ import { domain } from 'flavours/glitch/initial_state'; import { getAccountHidden } from 'flavours/glitch/selectors/accounts'; import { useAppSelector, useAppDispatch } from 'flavours/glitch/store'; +import { useLinks } from '../hooks/useLinks'; + export const HoverCardAccount = forwardRef< HTMLDivElement, { accountId?: string } @@ -64,6 +66,8 @@ export const HoverCardAccount = forwardRef< !isMutual && !isFollower; + const handleClick = useLinks(); + return (
- + +
+ +
+ {note && note.length > 0 && (
diff --git a/app/javascript/flavours/glitch/components/status/handled_link.tsx b/app/javascript/flavours/glitch/components/status/handled_link.tsx index ee41321283b22d..b3a113764514b7 100644 --- a/app/javascript/flavours/glitch/components/status/handled_link.tsx +++ b/app/javascript/flavours/glitch/components/status/handled_link.tsx @@ -1,7 +1,10 @@ +import { useCallback } from 'react'; import type { ComponentProps, FC } from 'react'; import { Link } from 'react-router-dom'; +import type { OnElementHandler } from '@/flavours/glitch/utils/html'; + export interface HandledLinkProps { href: string; text: string; @@ -77,3 +80,31 @@ export const HandledLink: FC> = ({ return text; } }; + +export const useElementHandledLink = ({ + hashtagAccountId, + mentionAccountId, +}: { + hashtagAccountId?: string; + mentionAccountId?: string; +} = {}) => { + const onElement = useCallback( + (element, { key, ...props }) => { + if (element instanceof HTMLAnchorElement) { + return ( + + ); + } + return undefined; + }, + [hashtagAccountId, mentionAccountId], + ); + return { onElement }; +}; diff --git a/app/javascript/flavours/glitch/components/verified_badge.tsx b/app/javascript/flavours/glitch/components/verified_badge.tsx index 626cc500d6a672..dffa57ef24a7c8 100644 --- a/app/javascript/flavours/glitch/components/verified_badge.tsx +++ b/app/javascript/flavours/glitch/components/verified_badge.tsx @@ -1,10 +1,17 @@ +import { EmojiHTML } from '@/flavours/glitch/components/emoji/html'; import CheckIcon from '@/material-icons/400-24px/check.svg?react'; +import { isModernEmojiEnabled } from '../utils/environment'; +import type { OnAttributeHandler } from '../utils/html'; + import { Icon } from './icon'; const domParser = new DOMParser(); const stripRelMe = (html: string) => { + if (isModernEmojiEnabled()) { + return html; + } const document = domParser.parseFromString(html, 'text/html').documentElement; document.querySelectorAll('a[rel]').forEach((link) => { @@ -15,7 +22,23 @@ const stripRelMe = (html: string) => { }); const body = document.querySelector('body'); - return body ? { __html: body.innerHTML } : undefined; + return body?.innerHTML ?? ''; +}; + +const onAttribute: OnAttributeHandler = (name, value, tagName) => { + if (name === 'rel' && tagName === 'a') { + if (value === 'me') { + return null; + } + return [ + name, + value + .split(' ') + .filter((x) => x !== 'me') + .join(' '), + ]; + } + return undefined; }; interface Props { @@ -24,6 +47,10 @@ interface Props { export const VerifiedBadge: React.FC = ({ link }) => ( - + ); diff --git a/app/javascript/flavours/glitch/features/account_timeline/components/account_header.tsx b/app/javascript/flavours/glitch/features/account_timeline/components/account_header.tsx index fe42d6486fc870..074a403b24fe89 100644 --- a/app/javascript/flavours/glitch/features/account_timeline/components/account_header.tsx +++ b/app/javascript/flavours/glitch/features/account_timeline/components/account_header.tsx @@ -7,9 +7,9 @@ import { Helmet } from 'react-helmet'; import { NavLink } from 'react-router-dom'; import { AccountBio } from '@/flavours/glitch/components/account_bio'; +import { AccountFields } from '@/flavours/glitch/components/account_fields'; import { DisplayName } from '@/flavours/glitch/components/display_name'; import { AnimateEmojiProvider } from '@/flavours/glitch/components/emoji/context'; -import CheckIcon from '@/material-icons/400-24px/check.svg?react'; import LockIcon from '@/material-icons/400-24px/lock.svg?react'; import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react'; import NotificationsIcon from '@/material-icons/400-24px/notifications.svg?react'; @@ -190,14 +190,6 @@ const titleFromAccount = (account: Account) => { return `${prefix} (@${acct})`; }; -const dateFormatOptions: Intl.DateTimeFormatOptions = { - month: 'short', - day: 'numeric', - year: 'numeric', - hour: '2-digit', - minute: '2-digit', -}; - export const AccountHeader: React.FC<{ accountId: string; hideTabs?: boolean; @@ -895,46 +887,7 @@ export const AccountHeader: React.FC<{
- {fields.map((pair, i) => ( -
-
- -
- {pair.verified_at && ( - - - - )}{' '} - -
-
- ))} +
diff --git a/app/javascript/flavours/glitch/hooks/useLinks.ts b/app/javascript/flavours/glitch/hooks/useLinks.ts index ab9ac4ef474a33..14c6e2e8f6a943 100644 --- a/app/javascript/flavours/glitch/hooks/useLinks.ts +++ b/app/javascript/flavours/glitch/hooks/useLinks.ts @@ -7,6 +7,8 @@ import { isFulfilled, isRejected } from '@reduxjs/toolkit'; import { openURL } from 'flavours/glitch/actions/search'; import { useAppDispatch } from 'flavours/glitch/store'; +import { isModernEmojiEnabled } from '../utils/environment'; + const isMentionClick = (element: HTMLAnchorElement) => element.classList.contains('mention') && !element.classList.contains('hashtag'); @@ -53,6 +55,11 @@ export const useLinks = (skipHashtags?: boolean) => { const handleClick = useCallback( (e: React.MouseEvent) => { + // Exit early if modern emoji is enabled, as this is handled by HandledLink. + if (isModernEmojiEnabled()) { + return; + } + const target = (e.target as HTMLElement).closest('a'); if (!target || e.button !== 0 || e.ctrlKey || e.metaKey) { diff --git a/app/javascript/flavours/glitch/utils/html.ts b/app/javascript/flavours/glitch/utils/html.ts index bbda1b7be37192..dd2865f2e6243f 100644 --- a/app/javascript/flavours/glitch/utils/html.ts +++ b/app/javascript/flavours/glitch/utils/html.ts @@ -41,18 +41,22 @@ export type OnElementHandler< extra: Arg, ) => React.ReactNode; +export type OnAttributeHandler< + Arg extends Record = Record, +> = ( + name: string, + value: string, + tagName: string, + extra: Arg, +) => [string, unknown] | undefined | null; + export interface HTMLToStringOptions< Arg extends Record = Record, > { maxDepth?: number; onText?: (text: string, extra: Arg) => React.ReactNode; onElement?: OnElementHandler; - onAttribute?: ( - name: string, - value: string, - tagName: string, - extra: Arg, - ) => [string, unknown] | null; + onAttribute?: OnAttributeHandler; allowedTags?: AllowedTagsType; extraArgs?: Arg; } @@ -140,44 +144,44 @@ export function htmlStringToComponents>( // Custom attribute handler. if (onAttribute) { - const result = onAttribute( - name, - attr.value, - node.tagName.toLowerCase(), - extraArgs, - ); + const result = onAttribute(name, attr.value, tagName, extraArgs); + // Rewrite this attribute. if (result) { const [cbName, value] = result; props[cbName] = value; - } - } else { - // Check global attributes first, then tag-specific ones. - const globalAttr = globalAttributes[name]; - const tagAttr = tagInfo.attributes?.[name]; - - // Exit if neither global nor tag-specific attribute is allowed. - if (!globalAttr && !tagAttr) { + continue; + } else if (result === null) { + // Explicitly remove this attribute. continue; } + } - // Rename if needed. - if (typeof tagAttr === 'string') { - name = tagAttr; - } else if (typeof globalAttr === 'string') { - name = globalAttr; - } + // Check global attributes first, then tag-specific ones. + const globalAttr = globalAttributes[name]; + const tagAttr = tagInfo.attributes?.[name]; - let value: string | boolean | number = attr.value; + // Exit if neither global nor tag-specific attribute is allowed. + if (!globalAttr && !tagAttr) { + continue; + } - // Handle boolean attributes. - if (value === 'true') { - value = true; - } else if (value === 'false') { - value = false; - } + // Rename if needed. + if (typeof tagAttr === 'string') { + name = tagAttr; + } else if (typeof globalAttr === 'string') { + name = globalAttr; + } + + let value: string | boolean | number = attr.value; - props[name] = value; + // Handle boolean attributes. + if (value === 'true') { + value = true; + } else if (value === 'false') { + value = false; } + + props[name] = value; } // If onElement is provided, use it to create the element. From c08a874ba9ebd9bc491bfa31cbb8d7130f9bbd9f Mon Sep 17 00:00:00 2001 From: Echo Date: Wed, 8 Oct 2025 16:18:11 +0200 Subject: [PATCH 121/853] [Glitch] Emoji: Statuses Port 0c1ca6c969fcc2ba1c6ad17ff1a94a4ee8711f75 to glitch-soc Signed-off-by: Claire --- .../glitch/components/content_warning.tsx | 55 +++++++++++++------ .../flavours/glitch/components/poll.tsx | 6 +- .../flavours/glitch/components/status.jsx | 4 +- .../glitch/components/status/handled_link.tsx | 9 +-- .../glitch/components/status_banner.tsx | 7 ++- .../compose/components/edit_indicator.jsx | 4 +- .../compose/components/reply_indicator.jsx | 4 +- .../directory/components/account_card.tsx | 8 ++- .../glitch/features/emoji/normalize.ts | 6 ++ .../flavours/glitch/features/emoji/types.ts | 3 +- .../components/account_authorize.jsx | 16 ++++-- .../components/embedded_status.tsx | 28 ++++------ .../components/embedded_status_content.tsx | 45 ++++++++++----- .../status/components/detailed_status.tsx | 18 +++--- 14 files changed, 128 insertions(+), 85 deletions(-) diff --git a/app/javascript/flavours/glitch/components/content_warning.tsx b/app/javascript/flavours/glitch/components/content_warning.tsx index 2312d69c278dcf..f3535b9fb584e6 100644 --- a/app/javascript/flavours/glitch/components/content_warning.tsx +++ b/app/javascript/flavours/glitch/components/content_warning.tsx @@ -1,25 +1,48 @@ +import type { List } from 'immutable'; + +import type { CustomEmoji } from '../models/custom_emoji'; +import type { Status } from '../models/status'; + +import { EmojiHTML } from './emoji/html'; import type { IconName } from './media_icon'; import { MediaIcon } from './media_icon'; import { StatusBanner, BannerVariant } from './status_banner'; export const ContentWarning: React.FC<{ - text: string; + status: Status; expanded?: boolean; onClick?: () => void; icons?: IconName[]; -}> = ({ text, expanded, onClick, icons }) => ( - - {icons?.map((icon) => ( - = ({ status, expanded, onClick, icons }) => { + const hasSpoiler = !!status.get('spoiler_text'); + if (!hasSpoiler) { + return null; + } + + const text = + status.getIn(['translation', 'spoilerHtml']) || status.get('spoilerHtml'); + if (typeof text !== 'string' || text.length === 0) { + return null; + } + + return ( + + {icons?.map((icon) => ( + + ))} + } /> - ))} - - -); + + ); +}; diff --git a/app/javascript/flavours/glitch/components/poll.tsx b/app/javascript/flavours/glitch/components/poll.tsx index 851d0f02f9613f..2dde24fe7ce621 100644 --- a/app/javascript/flavours/glitch/components/poll.tsx +++ b/app/javascript/flavours/glitch/components/poll.tsx @@ -8,6 +8,7 @@ import classNames from 'classnames'; import { animated, useSpring } from '@react-spring/web'; import escapeTextContentForBrowser from 'escape-html'; +import { EmojiHTML } from '@/flavours/glitch/components/emoji/html'; import CheckIcon from '@/material-icons/400-24px/check.svg?react'; import { openModal } from 'flavours/glitch/actions/modal'; import { fetchPoll, vote } from 'flavours/glitch/actions/polls'; @@ -305,10 +306,11 @@ const PollOption: React.FC = (props) => { )} - {!!voted && ( diff --git a/app/javascript/flavours/glitch/components/status.jsx b/app/javascript/flavours/glitch/components/status.jsx index 4362b704372f6c..335e5e20b6b22b 100644 --- a/app/javascript/flavours/glitch/components/status.jsx +++ b/app/javascript/flavours/glitch/components/status.jsx @@ -118,7 +118,7 @@ class Status extends ImmutablePureComponent { prepend: PropTypes.string, withDismiss: PropTypes.bool, isQuotedPost: PropTypes.bool, - shouldHighlightOnMount: PropTypes.bool, + shouldHighlightOnMount: PropTypes.bool, getScrollPosition: PropTypes.func, updateScrollBottom: PropTypes.func, expanded: PropTypes.bool, @@ -739,7 +739,7 @@ class Status extends ImmutablePureComponent { )} - {status.get('spoiler_text').length > 0 && } + {expanded && ( <> diff --git a/app/javascript/flavours/glitch/components/status/handled_link.tsx b/app/javascript/flavours/glitch/components/status/handled_link.tsx index b3a113764514b7..c153053b233a5d 100644 --- a/app/javascript/flavours/glitch/components/status/handled_link.tsx +++ b/app/javascript/flavours/glitch/components/status/handled_link.tsx @@ -83,14 +83,15 @@ export const HandledLink: FC> = ({ export const useElementHandledLink = ({ hashtagAccountId, - mentionAccountId, + hrefToMentionAccountId, }: { hashtagAccountId?: string; - mentionAccountId?: string; + hrefToMentionAccountId?: (href: string) => string | undefined; } = {}) => { const onElement = useCallback( (element, { key, ...props }) => { if (element instanceof HTMLAnchorElement) { + const mentionId = hrefToMentionAccountId?.(element.href); return ( ); } return undefined; }, - [hashtagAccountId, mentionAccountId], + [hashtagAccountId, hrefToMentionAccountId], ); return { onElement }; }; diff --git a/app/javascript/flavours/glitch/components/status_banner.tsx b/app/javascript/flavours/glitch/components/status_banner.tsx index e11b2c9279b761..a1d200133f8062 100644 --- a/app/javascript/flavours/glitch/components/status_banner.tsx +++ b/app/javascript/flavours/glitch/components/status_banner.tsx @@ -3,6 +3,8 @@ import { useCallback, useRef, useId } from 'react'; import { FormattedMessage } from 'react-intl'; +import { AnimateEmojiProvider } from './emoji/context'; + export enum BannerVariant { Warning = 'warning', Filter = 'filter', @@ -34,8 +36,7 @@ export const StatusBanner: React.FC<{ return ( // Element clicks are passed on to button - // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions -
)} -
+ ); }; diff --git a/app/javascript/flavours/glitch/features/compose/components/edit_indicator.jsx b/app/javascript/flavours/glitch/features/compose/components/edit_indicator.jsx index bccb716daeeafe..88c58774d93009 100644 --- a/app/javascript/flavours/glitch/features/compose/components/edit_indicator.jsx +++ b/app/javascript/flavours/glitch/features/compose/components/edit_indicator.jsx @@ -49,9 +49,7 @@ export const EditIndicator = () => { {(status.get('poll') || status.get('media_attachments').size > 0) && ( diff --git a/app/javascript/flavours/glitch/features/compose/components/reply_indicator.jsx b/app/javascript/flavours/glitch/features/compose/components/reply_indicator.jsx index d88fb5ef9327f5..048b23c7759394 100644 --- a/app/javascript/flavours/glitch/features/compose/components/reply_indicator.jsx +++ b/app/javascript/flavours/glitch/features/compose/components/reply_indicator.jsx @@ -34,9 +34,7 @@ export const ReplyIndicator = () => { {(status.get('poll') || status.get('media_attachments').size > 0) && ( diff --git a/app/javascript/flavours/glitch/features/directory/components/account_card.tsx b/app/javascript/flavours/glitch/features/directory/components/account_card.tsx index b07928573e8142..ebfea75218368c 100644 --- a/app/javascript/flavours/glitch/features/directory/components/account_card.tsx +++ b/app/javascript/flavours/glitch/features/directory/components/account_card.tsx @@ -1,5 +1,6 @@ import { FormattedMessage } from 'react-intl'; +import { EmojiHTML } from '@/flavours/glitch/components/emoji/html'; import { Avatar } from 'flavours/glitch/components/avatar'; import { DisplayName } from 'flavours/glitch/components/display_name'; import { FollowButton } from 'flavours/glitch/components/follow_button'; @@ -42,9 +43,10 @@ export const AccountCard: React.FC<{ accountId: string }> = ({ accountId }) => { {account.get('note').length > 0 && ( -
)} diff --git a/app/javascript/flavours/glitch/features/emoji/normalize.ts b/app/javascript/flavours/glitch/features/emoji/normalize.ts index f9d725521b939d..8934f9a20da2bb 100644 --- a/app/javascript/flavours/glitch/features/emoji/normalize.ts +++ b/app/javascript/flavours/glitch/features/emoji/normalize.ts @@ -154,6 +154,12 @@ export function cleanExtraEmojis(extraEmojis?: CustomEmojiMapArg) { if (!extraEmojis) { return null; } + if (Array.isArray(extraEmojis)) { + return extraEmojis.reduce( + (acc, emoji) => ({ ...acc, [emoji.shortcode]: emoji }), + {}, + ); + } if (!isList(extraEmojis)) { return extraEmojis; } diff --git a/app/javascript/flavours/glitch/features/emoji/types.ts b/app/javascript/flavours/glitch/features/emoji/types.ts index 792be277a23b3f..e90831e44fb500 100644 --- a/app/javascript/flavours/glitch/features/emoji/types.ts +++ b/app/javascript/flavours/glitch/features/emoji/types.ts @@ -56,7 +56,8 @@ export type EmojiStateMap = LimitedCache; export type CustomEmojiMapArg = | ExtraCustomEmojiMap - | ImmutableList; + | ImmutableList + | CustomEmoji[]; export type ExtraCustomEmojiMap = Record< string, diff --git a/app/javascript/flavours/glitch/features/follow_requests/components/account_authorize.jsx b/app/javascript/flavours/glitch/features/follow_requests/components/account_authorize.jsx index 877d84c632478b..079b742c5a3571 100644 --- a/app/javascript/flavours/glitch/features/follow_requests/components/account_authorize.jsx +++ b/app/javascript/flavours/glitch/features/follow_requests/components/account_authorize.jsx @@ -8,10 +8,11 @@ import ImmutablePureComponent from 'react-immutable-pure-component'; import CheckIcon from '@/material-icons/400-24px/check.svg?react'; import CloseIcon from '@/material-icons/400-24px/close.svg?react'; -import { Avatar } from '../../../components/avatar'; -import { DisplayName } from '../../../components/display_name'; -import { IconButton } from '../../../components/icon_button'; -import { Permalink } from '../../../components/permalink'; +import { Avatar } from '@/flavours/glitch/components/avatar'; +import { DisplayName } from '@/flavours/glitch/components/display_name'; +import { IconButton } from '@/flavours/glitch/components/icon_button'; +import { EmojiHTML } from '@/flavours/glitch/components/emoji/html'; +import { Permalink } from '@/flavours/glitch/components/permalink'; const messages = defineMessages({ authorize: { id: 'follow_request.authorize', defaultMessage: 'Authorize' }, @@ -29,7 +30,6 @@ class AccountAuthorize extends ImmutablePureComponent { render () { const { intl, account, onAuthorize, onReject } = this.props; - const content = { __html: account.get('note_emojified') }; return (
@@ -39,7 +39,11 @@ class AccountAuthorize extends ImmutablePureComponent { -
+
diff --git a/app/javascript/flavours/glitch/features/notifications_v2/components/embedded_status.tsx b/app/javascript/flavours/glitch/features/notifications_v2/components/embedded_status.tsx index b11962e38efed8..4db1dfa0da2a26 100644 --- a/app/javascript/flavours/glitch/features/notifications_v2/components/embedded_status.tsx +++ b/app/javascript/flavours/glitch/features/notifications_v2/components/embedded_status.tsx @@ -6,6 +6,7 @@ import { useHistory } from 'react-router-dom'; import type { List as ImmutableList, RecordOf } from 'immutable'; +import type { ApiMentionJSON } from '@/flavours/glitch/api_types/statuses'; import { AnimateEmojiProvider } from '@/flavours/glitch/components/emoji/context'; import BarChart4BarsIcon from '@/material-icons/400-24px/bar_chart_4_bars.svg?react'; import PhotoLibraryIcon from '@/material-icons/400-24px/photo_library.svg?react'; @@ -18,7 +19,7 @@ import { useAppSelector, useAppDispatch } from 'flavours/glitch/store'; import { EmbeddedStatusContent } from './embedded_status_content'; -export type Mention = RecordOf<{ url: string; acct: string }>; +export type Mention = RecordOf; export const EmbeddedStatus: React.FC<{ statusId: string }> = ({ statusId, @@ -86,12 +87,9 @@ export const EmbeddedStatus: React.FC<{ statusId: string }> = ({ } // Assign status attributes to variables with a forced type, as status is not yet properly typed - const contentHtml = status.get('contentHtml') as string; - const contentWarning = status.get('spoilerHtml') as string; + const hasContentWarning = !!status.get('spoiler_text'); const poll = status.get('poll'); - const language = status.get('language') as string; - const mentions = status.get('mentions') as ImmutableList; - const expanded = !status.get('hidden') || !contentWarning; + const expanded = !status.get('hidden') || !hasContentWarning; const mediaAttachmentsSize = ( status.get('media_attachments') as ImmutableList ).size; @@ -109,20 +107,16 @@ export const EmbeddedStatus: React.FC<{ statusId: string }> = ({
- {contentWarning && ( - - )} + - {(!contentWarning || expanded) && ( + {(!hasContentWarning || expanded) && ( )} diff --git a/app/javascript/flavours/glitch/features/notifications_v2/components/embedded_status_content.tsx b/app/javascript/flavours/glitch/features/notifications_v2/components/embedded_status_content.tsx index 855e160fac657d..3cb1e12ed41e15 100644 --- a/app/javascript/flavours/glitch/features/notifications_v2/components/embedded_status_content.tsx +++ b/app/javascript/flavours/glitch/features/notifications_v2/components/embedded_status_content.tsx @@ -1,4 +1,4 @@ -import { useCallback } from 'react'; +import { useCallback, useMemo } from 'react'; import { useHistory } from 'react-router-dom'; @@ -6,16 +6,22 @@ import type { List } from 'immutable'; import type { History } from 'history'; +import type { ApiMentionJSON } from '@/flavours/glitch/api_types/statuses'; +import { EmojiHTML } from '@/flavours/glitch/components/emoji/html'; +import { useElementHandledLink } from '@/flavours/glitch/components/status/handled_link'; +import type { Status } from '@/flavours/glitch/models/status'; +import { isModernEmojiEnabled } from '@/flavours/glitch/utils/environment'; + import type { Mention } from './embedded_status'; const handleMentionClick = ( history: History, - mention: Mention, + mention: ApiMentionJSON, e: MouseEvent, ) => { if (e.button === 0 && !(e.ctrlKey || e.metaKey)) { e.preventDefault(); - history.push(`/@${mention.get('acct')}`); + history.push(`/@${mention.acct}`); } }; @@ -31,16 +37,26 @@ const handleHashtagClick = ( }; export const EmbeddedStatusContent: React.FC<{ - content: string; - mentions: List; - language: string; + status: Status; className?: string; -}> = ({ content, mentions, language, className }) => { +}> = ({ status, className }) => { const history = useHistory(); + const mentions = useMemo( + () => (status.get('mentions') as List).toJS(), + [status], + ); + const htmlHandlers = useElementHandledLink({ + hashtagAccountId: status.get('account') as string | undefined, + hrefToMentionAccountId(href) { + const mention = mentions.find((item) => item.url === href); + return mention?.id; + }, + }); + const handleContentRef = useCallback( (node: HTMLDivElement | null) => { - if (!node) { + if (!node || isModernEmojiEnabled()) { return; } @@ -53,7 +69,7 @@ export const EmbeddedStatusContent: React.FC<{ link.classList.add('status-link'); - const mention = mentions.find((item) => link.href === item.get('url')); + const mention = mentions.find((item) => link.href === item.url); if (mention) { link.addEventListener( @@ -61,8 +77,8 @@ export const EmbeddedStatusContent: React.FC<{ handleMentionClick.bind(null, history, mention), false, ); - link.setAttribute('title', `@${mention.get('acct')}`); - link.setAttribute('href', `/@${mention.get('acct')}`); + link.setAttribute('title', `@${mention.acct}`); + link.setAttribute('href', `/@${mention.acct}`); } else if ( link.textContent.startsWith('#') || link.previousSibling?.textContent?.endsWith('#') @@ -83,11 +99,12 @@ export const EmbeddedStatusContent: React.FC<{ ); return ( -
); }; diff --git a/app/javascript/flavours/glitch/features/status/components/detailed_status.tsx b/app/javascript/flavours/glitch/features/status/components/detailed_status.tsx index 6c7d719cd220ba..a43744f9fe3841 100644 --- a/app/javascript/flavours/glitch/features/status/components/detailed_status.tsx +++ b/app/javascript/flavours/glitch/features/status/components/detailed_status.tsx @@ -429,17 +429,13 @@ export const DetailedStatus: React.FC<{ /> )} - {status.get('spoiler_text').length > 0 && - (!matchedFilters || showDespiteFilter) && ( - - )} + {(!matchedFilters || showDespiteFilter) && ( + + )} {expanded && ( <> From 62fc92dfd865b9b1fc51e5926363b8cfe46a9112 Mon Sep 17 00:00:00 2001 From: Echo Date: Wed, 8 Oct 2025 17:07:01 +0200 Subject: [PATCH 122/853] [Glitch] Emoji: Announcements Port babb7b2b9d13d6c9041edfe3ab6fe9fba708709c to glitch-soc Co-authored-by: diondiondion Signed-off-by: Claire --- .../glitch/api_types/announcements.ts | 28 +++++ .../glitch/features/emoji/normalize.ts | 16 +-- .../flavours/glitch/features/emoji/types.ts | 3 +- .../components/announcements/announcement.tsx | 119 ++++++++++++++++++ .../components/announcements/index.tsx | 118 +++++++++++++++++ .../components/announcements/reactions.tsx | 111 ++++++++++++++++ .../glitch/features/home_timeline/index.jsx | 4 +- 7 files changed, 388 insertions(+), 11 deletions(-) create mode 100644 app/javascript/flavours/glitch/api_types/announcements.ts create mode 100644 app/javascript/flavours/glitch/features/home_timeline/components/announcements/announcement.tsx create mode 100644 app/javascript/flavours/glitch/features/home_timeline/components/announcements/index.tsx create mode 100644 app/javascript/flavours/glitch/features/home_timeline/components/announcements/reactions.tsx diff --git a/app/javascript/flavours/glitch/api_types/announcements.ts b/app/javascript/flavours/glitch/api_types/announcements.ts new file mode 100644 index 00000000000000..03e8922d8f189f --- /dev/null +++ b/app/javascript/flavours/glitch/api_types/announcements.ts @@ -0,0 +1,28 @@ +// See app/serializers/rest/announcement_serializer.rb + +import type { ApiCustomEmojiJSON } from './custom_emoji'; +import type { ApiMentionJSON, ApiStatusJSON, ApiTagJSON } from './statuses'; + +export interface ApiAnnouncementJSON { + id: string; + content: string; + starts_at: null | string; + ends_at: null | string; + all_day: boolean; + published_at: string; + updated_at: null | string; + read: boolean; + mentions: ApiMentionJSON[]; + statuses: ApiStatusJSON[]; + tags: ApiTagJSON[]; + emojis: ApiCustomEmojiJSON[]; + reactions: ApiAnnouncementReactionJSON[]; +} + +export interface ApiAnnouncementReactionJSON { + name: string; + count: number; + me: boolean; + url?: string; + static_url?: string; +} diff --git a/app/javascript/flavours/glitch/features/emoji/normalize.ts b/app/javascript/flavours/glitch/features/emoji/normalize.ts index 8934f9a20da2bb..f0a502dcb5def4 100644 --- a/app/javascript/flavours/glitch/features/emoji/normalize.ts +++ b/app/javascript/flavours/glitch/features/emoji/normalize.ts @@ -160,15 +160,15 @@ export function cleanExtraEmojis(extraEmojis?: CustomEmojiMapArg) { {}, ); } - if (!isList(extraEmojis)) { - return extraEmojis; + if (isList(extraEmojis)) { + return extraEmojis + .toJS() + .reduce( + (acc, emoji) => ({ ...acc, [emoji.shortcode]: emoji }), + {}, + ); } - return extraEmojis - .toJSON() - .reduce( - (acc, emoji) => ({ ...acc, [emoji.shortcode]: emoji }), - {}, - ); + return extraEmojis; } function hexStringToNumbers(hexString: string): number[] { diff --git a/app/javascript/flavours/glitch/features/emoji/types.ts b/app/javascript/flavours/glitch/features/emoji/types.ts index e90831e44fb500..b9c53e0697ec06 100644 --- a/app/javascript/flavours/glitch/features/emoji/types.ts +++ b/app/javascript/flavours/glitch/features/emoji/types.ts @@ -57,7 +57,8 @@ export type EmojiStateMap = LimitedCache; export type CustomEmojiMapArg = | ExtraCustomEmojiMap | ImmutableList - | CustomEmoji[]; + | CustomEmoji[] + | ApiCustomEmojiJSON[]; export type ExtraCustomEmojiMap = Record< string, diff --git a/app/javascript/flavours/glitch/features/home_timeline/components/announcements/announcement.tsx b/app/javascript/flavours/glitch/features/home_timeline/components/announcements/announcement.tsx new file mode 100644 index 00000000000000..1bc8cdb9dacc02 --- /dev/null +++ b/app/javascript/flavours/glitch/features/home_timeline/components/announcements/announcement.tsx @@ -0,0 +1,119 @@ +import { useEffect, useState } from 'react'; +import type { FC } from 'react'; + +import { FormattedDate, FormattedMessage } from 'react-intl'; + +import type { ApiAnnouncementJSON } from '@/flavours/glitch/api_types/announcements'; +import { AnimateEmojiProvider } from '@/flavours/glitch/components/emoji/context'; +import { EmojiHTML } from '@/flavours/glitch/components/emoji/html'; + +import { ReactionsBar } from './reactions'; + +export interface IAnnouncement extends ApiAnnouncementJSON { + contentHtml: string; +} + +interface AnnouncementProps { + announcement: IAnnouncement; + selected: boolean; +} + +export const Announcement: FC = ({ + announcement, + selected, +}) => { + const [unread, setUnread] = useState(!announcement.read); + useEffect(() => { + // Only update `unread` marker once the announcement is out of view + if (!selected && unread !== !announcement.read) { + setUnread(!announcement.read); + } + }, [announcement.read, selected, unread]); + + return ( + + + + + {' · '} + + + + + + + + + {unread && } + + ); +}; + +const Timestamp: FC> = ({ + announcement, +}) => { + const startsAt = announcement.starts_at && new Date(announcement.starts_at); + const endsAt = announcement.ends_at && new Date(announcement.ends_at); + const now = new Date(); + const hasTimeRange = startsAt && endsAt; + const skipTime = announcement.all_day; + + if (hasTimeRange) { + const skipYear = + startsAt.getFullYear() === endsAt.getFullYear() && + endsAt.getFullYear() === now.getFullYear(); + const skipEndDate = + startsAt.getDate() === endsAt.getDate() && + startsAt.getMonth() === endsAt.getMonth() && + startsAt.getFullYear() === endsAt.getFullYear(); + return ( + <> + {' '} + -{' '} + + + ); + } + const publishedAt = new Date(announcement.published_at); + return ( + + ); +}; diff --git a/app/javascript/flavours/glitch/features/home_timeline/components/announcements/index.tsx b/app/javascript/flavours/glitch/features/home_timeline/components/announcements/index.tsx new file mode 100644 index 00000000000000..6ce56beebb81ad --- /dev/null +++ b/app/javascript/flavours/glitch/features/home_timeline/components/announcements/index.tsx @@ -0,0 +1,118 @@ +import { useCallback, useState } from 'react'; +import type { FC } from 'react'; + +import { defineMessages, useIntl } from 'react-intl'; + +import type { Map, List } from 'immutable'; + +import ReactSwipeableViews from 'react-swipeable-views'; + +import { CustomEmojiProvider } from '@/flavours/glitch/components/emoji/context'; +import { IconButton } from '@/flavours/glitch/components/icon_button'; +import LegacyAnnouncements from '@/flavours/glitch/features/getting_started/containers/announcements_container'; +import { mascot, reduceMotion } from '@/flavours/glitch/initial_state'; +import { createAppSelector, useAppSelector } from '@/flavours/glitch/store'; +import { isModernEmojiEnabled } from '@/flavours/glitch/utils/environment'; +import elephantUIPlane from '@/images/elephant_ui_plane.svg'; +import ChevronLeftIcon from '@/material-icons/400-24px/chevron_left.svg?react'; +import ChevronRightIcon from '@/material-icons/400-24px/chevron_right.svg?react'; + +import type { IAnnouncement } from './announcement'; +import { Announcement } from './announcement'; + +const messages = defineMessages({ + close: { id: 'lightbox.close', defaultMessage: 'Close' }, + previous: { id: 'lightbox.previous', defaultMessage: 'Previous' }, + next: { id: 'lightbox.next', defaultMessage: 'Next' }, +}); + +const announcementSelector = createAppSelector( + [(state) => state.announcements as Map>>], + (announcements) => + (announcements.get('items')?.toJS() as IAnnouncement[] | undefined) ?? [], +); + +export const ModernAnnouncements: FC = () => { + const intl = useIntl(); + + const announcements = useAppSelector(announcementSelector); + const emojis = useAppSelector((state) => state.custom_emojis); + + const [index, setIndex] = useState(0); + const handleChangeIndex = useCallback( + (idx: number) => { + setIndex(idx % announcements.length); + }, + [announcements.length], + ); + const handleNextIndex = useCallback(() => { + setIndex((prevIndex) => (prevIndex + 1) % announcements.length); + }, [announcements.length]); + const handlePrevIndex = useCallback(() => { + setIndex((prevIndex) => + prevIndex === 0 ? announcements.length - 1 : prevIndex - 1, + ); + }, [announcements.length]); + + if (announcements.length === 0) { + return null; + } + + return ( +
+ + +
+ + + {announcements + .map((announcement, idx) => ( + + )) + .reverse()} + + + + {announcements.length > 1 && ( +
+ + + {index + 1} / {announcements.length} + + +
+ )} +
+
+ ); +}; + +export const Announcements = isModernEmojiEnabled() + ? ModernAnnouncements + : LegacyAnnouncements; diff --git a/app/javascript/flavours/glitch/features/home_timeline/components/announcements/reactions.tsx b/app/javascript/flavours/glitch/features/home_timeline/components/announcements/reactions.tsx new file mode 100644 index 00000000000000..9efd14e0bc9323 --- /dev/null +++ b/app/javascript/flavours/glitch/features/home_timeline/components/announcements/reactions.tsx @@ -0,0 +1,111 @@ +import { useCallback, useMemo } from 'react'; +import type { FC, HTMLAttributes } from 'react'; + +import classNames from 'classnames'; + +import type { AnimatedProps } from '@react-spring/web'; +import { animated, useTransition } from '@react-spring/web'; + +import { + addReaction, + removeReaction, +} from '@/flavours/glitch/actions/announcements'; +import type { ApiAnnouncementReactionJSON } from '@/flavours/glitch/api_types/announcements'; +import { AnimatedNumber } from '@/flavours/glitch/components/animated_number'; +import { Emoji } from '@/flavours/glitch/components/emoji'; +import { Icon } from '@/flavours/glitch/components/icon'; +import EmojiPickerDropdown from '@/flavours/glitch/features/compose/containers/emoji_picker_dropdown_container'; +import { isUnicodeEmoji } from '@/flavours/glitch/features/emoji/utils'; +import { useAppDispatch } from '@/flavours/glitch/store'; +import AddIcon from '@/material-icons/400-24px/add.svg?react'; + +export const ReactionsBar: FC<{ + reactions: ApiAnnouncementReactionJSON[]; + id: string; +}> = ({ reactions, id }) => { + const visibleReactions = useMemo( + () => reactions.filter((x) => x.count > 0), + [reactions], + ); + + const dispatch = useAppDispatch(); + const handleEmojiPick = useCallback( + (emoji: { native: string }) => { + dispatch(addReaction(id, emoji.native.replaceAll(/:/g, ''))); + }, + [dispatch, id], + ); + + const transitions = useTransition(visibleReactions, { + from: { + scale: 0, + }, + enter: { + scale: 1, + }, + leave: { + scale: 0, + }, + keys: visibleReactions.map((x) => x.name), + }); + + return ( +
+ {transitions(({ scale }, reaction) => ( + `scale(${s})`) }} + id={id} + /> + ))} + + {visibleReactions.length < 8 && ( + } + /> + )} +
+ ); +}; + +const Reaction: FC<{ + reaction: ApiAnnouncementReactionJSON; + id: string; + style: AnimatedProps>['style']; +}> = ({ id, reaction, style }) => { + const dispatch = useAppDispatch(); + const handleClick = useCallback(() => { + if (reaction.me) { + dispatch(removeReaction(id, reaction.name)); + } else { + dispatch(addReaction(id, reaction.name)); + } + }, [dispatch, id, reaction.me, reaction.name]); + + const code = isUnicodeEmoji(reaction.name) + ? reaction.name + : `:${reaction.name}:`; + + return ( + + + + + + + + + ); +}; diff --git a/app/javascript/flavours/glitch/features/home_timeline/index.jsx b/app/javascript/flavours/glitch/features/home_timeline/index.jsx index 68832a7408b760..76d4037ca6a5cf 100644 --- a/app/javascript/flavours/glitch/features/home_timeline/index.jsx +++ b/app/javascript/flavours/glitch/features/home_timeline/index.jsx @@ -14,7 +14,6 @@ import { SymbolLogo } from 'flavours/glitch/components/logo'; import { fetchAnnouncements, toggleShowAnnouncements } from 'flavours/glitch/actions/announcements'; import { IconWithBadge } from 'flavours/glitch/components/icon_with_badge'; import { NotSignedInIndicator } from 'flavours/glitch/components/not_signed_in_indicator'; -import AnnouncementsContainer from 'flavours/glitch/features/getting_started/containers/announcements_container'; import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context'; import { criticalUpdatesPending } from 'flavours/glitch/initial_state'; import { withBreakpoint } from 'flavours/glitch/features/ui/hooks/useBreakpoint'; @@ -27,6 +26,7 @@ import StatusListContainer from '../ui/containers/status_list_container'; import { ColumnSettings } from './components/column_settings'; import { CriticalUpdateBanner } from './components/critical_update_banner'; +import { Announcements } from './components/announcements'; const messages = defineMessages({ title: { id: 'column.home', defaultMessage: 'Home' }, @@ -164,7 +164,7 @@ class HomeTimeline extends PureComponent { pinned={pinned} multiColumn={multiColumn} extraButton={announcementsButton} - appendContent={hasAnnouncements && showAnnouncements && } + appendContent={hasAnnouncements && showAnnouncements && } > From 5bc7c4b7e880ee1456dc21987d8fba32e340d31e Mon Sep 17 00:00:00 2001 From: Echo Date: Wed, 8 Oct 2025 19:17:03 +0200 Subject: [PATCH 123/853] Emoji: Fixes issue with handled link not correctly showing remote users (#36403) --- .../status/handled_link.stories.tsx | 29 +++++++++----- .../components/status/handled_link.tsx | 38 +++++++++---------- .../mastodon/components/status_content.jsx | 2 +- .../components/embedded_status_content.tsx | 5 +-- 4 files changed, 42 insertions(+), 32 deletions(-) diff --git a/app/javascript/mastodon/components/status/handled_link.stories.tsx b/app/javascript/mastodon/components/status/handled_link.stories.tsx index a45e33626ae995..71bf8eee63de6b 100644 --- a/app/javascript/mastodon/components/status/handled_link.stories.tsx +++ b/app/javascript/mastodon/components/status/handled_link.stories.tsx @@ -1,19 +1,28 @@ import type { Meta, StoryObj } from '@storybook/react-vite'; import { HashtagMenuController } from '@/mastodon/features/ui/components/hashtag_menu_controller'; -import { accountFactoryState } from '@/testing/factories'; import { HoverCardController } from '../hover_card_controller'; import type { HandledLinkProps } from './handled_link'; import { HandledLink } from './handled_link'; +type HandledLinkStoryProps = Pick & { + mentionAccount: 'local' | 'remote' | 'none'; +}; + const meta = { title: 'Components/Status/HandledLink', - render(args) { + render({ mentionAccount, ...args }) { + let mention: HandledLinkProps['mention'] | undefined; + if (mentionAccount === 'local') { + mention = { id: '1', acct: 'testuser' }; + } else if (mentionAccount === 'remote') { + mention = { id: '2', acct: 'remoteuser@mastodon.social' }; + } return ( <> - + @@ -22,15 +31,16 @@ const meta = { args: { href: 'https://example.com/path/subpath?query=1#hash', text: 'https://example.com', + mentionAccount: 'none', }, - parameters: { - state: { - accounts: { - '1': accountFactoryState(), - }, + argTypes: { + mentionAccount: { + control: { type: 'select' }, + options: ['local', 'remote', 'none'], + defaultValue: 'none', }, }, -} satisfies Meta>; +} satisfies Meta; export default meta; @@ -47,6 +57,7 @@ export const Hashtag: Story = { export const Mention: Story = { args: { text: '@user', + mentionAccount: 'local', }, }; diff --git a/app/javascript/mastodon/components/status/handled_link.tsx b/app/javascript/mastodon/components/status/handled_link.tsx index 83262886e85c77..0f486b33e95b53 100644 --- a/app/javascript/mastodon/components/status/handled_link.tsx +++ b/app/javascript/mastodon/components/status/handled_link.tsx @@ -1,22 +1,25 @@ import { useCallback } from 'react'; import type { ComponentProps, FC } from 'react'; +import classNames from 'classnames'; import { Link } from 'react-router-dom'; +import type { ApiMentionJSON } from '@/mastodon/api_types/statuses'; import type { OnElementHandler } from '@/mastodon/utils/html'; export interface HandledLinkProps { href: string; text: string; hashtagAccountId?: string; - mentionAccountId?: string; + mention?: Pick; } export const HandledLink: FC> = ({ href, text, hashtagAccountId, - mentionAccountId, + mention, + className, ...props }) => { // Handle hashtags @@ -24,8 +27,7 @@ export const HandledLink: FC> = ({ const hashtag = text.slice(1).trim(); return ( > = ({ #{hashtag} ); - } else if (text.startsWith('@')) { + } else if (text.startsWith('@') && mention) { // Handle mentions - const mention = text.slice(1).trim(); return ( - @{mention} + @{text.slice(1).trim()} ); } @@ -52,7 +52,7 @@ export const HandledLink: FC> = ({ // Non-absolute paths treated as internal links. if (href.startsWith('/')) { return ( - + {text} ); @@ -66,7 +66,7 @@ export const HandledLink: FC> = ({ {...props} href={href} title={href} - className='unhandled-link' + className={classNames('unhandled-link', className)} target='_blank' rel='noreferrer noopener' translate='no' @@ -83,15 +83,15 @@ export const HandledLink: FC> = ({ export const useElementHandledLink = ({ hashtagAccountId, - hrefToMentionAccountId, + hrefToMention, }: { hashtagAccountId?: string; - hrefToMentionAccountId?: (href: string) => string | undefined; + hrefToMention?: (href: string) => ApiMentionJSON | undefined; } = {}) => { const onElement = useCallback( (element, { key, ...props }) => { if (element instanceof HTMLAnchorElement) { - const mentionId = hrefToMentionAccountId?.(element.href); + const mention = hrefToMention?.(element.href); return ( ); } return undefined; }, - [hashtagAccountId, hrefToMentionAccountId], + [hashtagAccountId, hrefToMention], ); return { onElement }; }; diff --git a/app/javascript/mastodon/components/status_content.jsx b/app/javascript/mastodon/components/status_content.jsx index ede98cc81a3b2f..54579a1134fffd 100644 --- a/app/javascript/mastodon/components/status_content.jsx +++ b/app/javascript/mastodon/components/status_content.jsx @@ -213,7 +213,7 @@ class StatusContent extends PureComponent { href={element.href} text={element.innerText} hashtagAccountId={this.props.status.getIn(['account', 'id'])} - mentionAccountId={mention?.get('id')} + mention={mention?.toJSON()} key={key} /> ); diff --git a/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx b/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx index 91c3abde38da31..b7dc998a479f2d 100644 --- a/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx +++ b/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx @@ -48,9 +48,8 @@ export const EmbeddedStatusContent: React.FC<{ ); const htmlHandlers = useElementHandledLink({ hashtagAccountId: status.get('account') as string | undefined, - hrefToMentionAccountId(href) { - const mention = mentions.find((item) => item.url === href); - return mention?.id; + hrefToMention(href) { + return mentions.find((item) => item.url === href); }, }); From 01526592451074ab45cfecfc70da4244aaad7257 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 9 Oct 2025 04:08:29 -0400 Subject: [PATCH 124/853] Use tag filter for pending tag count on admin dashboard (#36404) --- app/controllers/admin/dashboard_controller.rb | 8 +++++++- spec/system/admin/dashboard_spec.rb | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/controllers/admin/dashboard_controller.rb b/app/controllers/admin/dashboard_controller.rb index 5b0867dcfbac2f..fe314daeca69f6 100644 --- a/app/controllers/admin/dashboard_controller.rb +++ b/app/controllers/admin/dashboard_controller.rb @@ -9,10 +9,16 @@ def index @pending_appeals_count = Appeal.pending.async_count @pending_reports_count = Report.unresolved.async_count - @pending_tags_count = Tag.pending_review.async_count + @pending_tags_count = pending_tags.async_count @pending_users_count = User.pending.async_count @system_checks = Admin::SystemCheck.perform(current_user) @time_period = (29.days.ago.to_date...Time.now.utc.to_date) end + + private + + def pending_tags + ::Trends::TagFilter.new(status: :pending_review).results + end end end diff --git a/spec/system/admin/dashboard_spec.rb b/spec/system/admin/dashboard_spec.rb index 06d31cde44e965..d0cedd2ed19ffa 100644 --- a/spec/system/admin/dashboard_spec.rb +++ b/spec/system/admin/dashboard_spec.rb @@ -9,6 +9,7 @@ before do stub_system_checks Fabricate :software_update + Fabricate :tag, requested_review_at: 5.minutes.ago sign_in(user) end @@ -18,6 +19,7 @@ expect(page) .to have_title(I18n.t('admin.dashboard.title')) .and have_content(I18n.t('admin.system_checks.software_version_patch_check.message_html')) + .and have_content('0 pending hashtags') end private From ba70dcf827ccd97117f146665c02b7310d367e2f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 9 Oct 2025 10:25:26 +0200 Subject: [PATCH 125/853] Update docker.io/ruby Docker tag to v3.4.7 (#36407) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index f2164ffd94102a..ad8150552a4c05 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,7 +13,7 @@ ARG BASE_REGISTRY="docker.io" # Ruby image to use for base image, change with [--build-arg RUBY_VERSION="3.4.x"] # renovate: datasource=docker depName=docker.io/ruby -ARG RUBY_VERSION="3.4.6" +ARG RUBY_VERSION="3.4.7" # # Node.js version to use in base image, change with [--build-arg NODE_MAJOR_VERSION="20"] # renovate: datasource=node-version depName=node ARG NODE_MAJOR_VERSION="22" From a459ccf616d3573c9837c29636286ffceb176382 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 9 Oct 2025 11:12:27 +0200 Subject: [PATCH 126/853] New Crowdin Translations (automated) (#36406) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/sq.json | 22 ++++++++++++++++++++++ config/locales/simple_form.sq.yml | 12 ++++++++++++ config/locales/sq.yml | 16 ++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/app/javascript/mastodon/locales/sq.json b/app/javascript/mastodon/locales/sq.json index 059a97b0f306fb..8e76cd8fe05bb9 100644 --- a/app/javascript/mastodon/locales/sq.json +++ b/app/javascript/mastodon/locales/sq.json @@ -113,6 +113,7 @@ "alt_text_modal.describe_for_people_with_visual_impairments": "Përshkruajeni këtë për persona me mangësi shikimi…", "alt_text_modal.done": "U bë", "announcement.announcement": "Lajmërim", + "annual_report.summary.archetype.oracle": "Orakulli", "annual_report.summary.followers.followers": "ndjekës", "annual_report.summary.followers.total": "{count} gjithsej", "annual_report.summary.here_it_is": "Ja {year} juaj e shqyrtuar:", @@ -299,6 +300,7 @@ "domain_pill.your_handle": "Targa juaj:", "domain_pill.your_server": "Shtëpia juaj dixhitale, kur gjenden krejt postimet tuaja. S’ju pëlqen kjo këtu? Shpërngulni shërbyes kur të doni dhe sillni edhe ndjekësit tuaj.", "domain_pill.your_username": "Identifikuesi juja unik në këtë shërbyes. Është e mundur të gjenden përdorues me të njëjtin emër përdoruesi në shërbyes të ndryshëm.", + "dropdown.empty": "Përzgjidhni një mundësi", "embed.instructions": "Trupëzojeni këtë gjendje në sajtin tuaj duke kopjuar kodin më poshtë.", "embed.preview": "Ja si do të duket:", "emoji_button.activity": "Veprimtari", @@ -568,6 +570,8 @@ "navigation_bar.follows_and_followers": "Ndjekje dhe ndjekës", "navigation_bar.import_export": "Importim dhe eksportim", "navigation_bar.lists": "Lista", + "navigation_bar.live_feed_local": "Pryrje e atypëratyshme (vendore)", + "navigation_bar.live_feed_public": "Prurje e atypëratyshme (publike)", "navigation_bar.logout": "Dalje", "navigation_bar.moderation": "Moderim", "navigation_bar.more": "Më tepër", @@ -737,11 +741,18 @@ "privacy.private.short": "Ndjekës", "privacy.public.long": "Cilido që hyn e del në Mastodon", "privacy.public.short": "Publik", + "privacy.quote.anyone": "{visibility}, mund të citojë cilido", + "privacy.quote.disabled": "{visibility}, citimet janë çaktivizuar", + "privacy.quote.limited": "{visibility}, citime të kufizuara", "privacy.unlisted.additional": "Ky sillet saktësisht si publik, vetëm se postimi s’do të shfaqet në prurje të drejtpërdrejta, ose në hashtag-ë, te eksploroni, apo kërkim në Mastodon, edhe kur keni zgjedhur të jetë për tërë llogarinë.", "privacy.unlisted.long": "Fshehur nga përfundime kërkimi në Mastodon, rrjedha kohore gjërash në modë dhe publike", "privacy.unlisted.short": "Publik i qetë", "privacy_policy.last_updated": "Përditësuar së fundi më {date}", "privacy_policy.title": "Rregulla Privatësie", + "quote_error.poll": "Me pyetësorët nuk lejohet citim.", + "quote_error.quote": "Lejohet vetëm një citim në herë.", + "quote_error.unauthorized": "S’jen i autorizuar ta citoni këtë postim.", + "quote_error.upload": "Me bashkëngjitjet media nuk lejohet citim.", "recommended": "E rekomanduar", "refresh": "Rifreskoje", "regeneration_indicator.please_stand_by": "Ju lutemi, mos u largoni.", @@ -851,6 +862,7 @@ "status.admin_account": "Hap ndërfaqe moderimi për @{name}", "status.admin_domain": "Hap ndërfaqe moderimi për {domain}", "status.admin_status": "Hape këtë mesazh te ndërfaqja e moderimit", + "status.all_disabled": "Përforcimet dhe citime janë të çaktivizuara", "status.block": "Blloko @{name}", "status.bookmark": "Faqeruaje", "status.cancel_reblog_private": "Shpërforcojeni", @@ -889,6 +901,8 @@ "status.mute_conversation": "Heshtoje bisedën", "status.open": "Zgjeroje këtë mesazh", "status.pin": "Fiksoje në profil", + "status.quote": "Citojeni", + "status.quote.cancel": "Anuloje citimin", "status.quote_error.filtered": "Fshehur për shkak të njërit nga filtrat tuaj", "status.quote_error.limited_account_hint.action": "Shfaqe, sido qoftë", "status.quote_error.limited_account_hint.title": "Kjo llogari është fshehur nga moderatorët e {domain}.", @@ -899,7 +913,9 @@ "status.quote_followers_only": "Këtë postim mund ta citojnë vetëm ndjekës", "status.quote_manual_review": "Autori do ta shqyrtojë dorazi", "status.quote_noun": "Citim", + "status.quote_policy_change": "Ndryshoni cilët mund të citojnë", "status.quote_post_author": "U citua një postim nga @{name}", + "status.quote_private": "Postimet private s’mund të citohen", "status.quotes": "{count, plural, one {citim} other {citime}}", "status.quotes.empty": "Këtë postim ende s’e ka cituar kush. Kur dikush ta bëjë, do të shfaqet këtu.", "status.quotes.local_other_disclaimer": "Citimet e hedhura poshtë nga autori s’do të shfaqen.", @@ -959,6 +975,7 @@ "upload_button.label": "Shtoni figura, një video ose një kartelë audio", "upload_error.limit": "U tejkalua kufi ngarkimi kartelash.", "upload_error.poll": "Me pyetësorët s’lejohet ngarkim kartelash.", + "upload_error.quote": "Nuk lejohet ngarkim kartelash me citime.", "upload_form.drag_and_drop.instructions": "Që të merrni një bashkëngjitje media, shtypni tastin Space ose Enter. Teksa bëhet tërheqje, përdorni tastet shigjetë për ta shpënë bashkëngjitjen media në cilëndo drejtori që doni. Shtypni sërish Space ose Enter që të lihet bashkëngjitja media në pozicionin e vet të ri, ose shtypni Esc, që të anulohet veprimi.", "upload_form.drag_and_drop.on_drag_cancel": "Tërheqja u anulua. Bashkëngjitja media {item} u la.", "upload_form.drag_and_drop.on_drag_end": "Bashkëngjitja media {item} u la.", @@ -982,13 +999,18 @@ "video.unmute": "Hiqi heshtimin", "video.volume_down": "Ulje volumi", "video.volume_up": "Ngritje volumi", + "visibility_modal.button_title": "Caktoni dukshmëri", + "visibility_modal.header": "Dukshmëri dhe ndërveprim", "visibility_modal.helper.direct_quoting": "Përmendje private të krijuara në Mastodon s’mund të citohen nga të tjerë.", "visibility_modal.helper.privacy_editing": "Dukshmëria s’mund të ndryshohet pasi postimi botohet.", "visibility_modal.helper.privacy_private_self_quote": "Citimet nga ju vetë të postime private s’mund të bëhen publike.", "visibility_modal.helper.private_quoting": "Postime vetëm për ndjekësit, të krijuara në Mastodon s’mund të citohen nga të tjerë.", + "visibility_modal.helper.unlisted_quoting": "Kur njerëzit ju citojnë, nga rrjedha kohore e gjërave në modë do të kalohen si të fshehura edhe postimet e tyre.", "visibility_modal.instructions": "Kontrolloni cilët mund të ndërveprojnë me këtë postim. Rregullime mund të aplikooni edhe mbi krejt postimet e ardshme, që nga Parapëlqime > Parazgjedhje postimi.", "visibility_modal.privacy_label": "Dukshmëri", + "visibility_modal.quote_followers": "Vetëm ndjekës", "visibility_modal.quote_label": "Cilët mund të citojnë", "visibility_modal.quote_nobody": "Thjesht unë", + "visibility_modal.quote_public": "Cilido", "visibility_modal.save": "Ruaje" } diff --git a/config/locales/simple_form.sq.yml b/config/locales/simple_form.sq.yml index db975ec65a584e..15d9e09e29134b 100644 --- a/config/locales/simple_form.sq.yml +++ b/config/locales/simple_form.sq.yml @@ -148,6 +148,9 @@ sq: min_age: S’duhet të jetë nën moshën minimum të domosdoshme nga ligjet në juridiksionin tuaj. user: chosen_languages: Në iu vëntë shenjë, te rrjedha kohore publike do të shfaqen vetëm mesazhe në gjuhët e përzgjedhura + date_of_birth: + one: Na duhet të sigurohemi se jeni të paktën %{count} që të përdorni %{domain}. S’do ta depozitojmë këtë. + other: Na duhet të sigurohemi se jeni të paktën %{count} që të përdorni %{domain}. S’do ta depozitojmë këtë. role: Roli kontrollon cilat leje ka përdoruesi. user_role: color: Ngjyrë për t’u përdorur për rolin nëpër UI, si RGB në format gjashtëmbëdhjetësh @@ -237,6 +240,7 @@ sq: setting_display_media_default: Parazgjedhje setting_display_media_hide_all: Fshihi krejt setting_display_media_show_all: Shfaqi krejt + setting_emoji_style: Stil emoji-sh setting_expand_spoilers: Mesazhet me sinjalizime mbi lëndën, zgjeroji përherë setting_hide_network: Fshiheni rrjetin tuaj setting_missing_alt_text_modal: Shfaq dialog ripohimi, para postimi mediash pa tekst alternativ @@ -273,12 +277,16 @@ sq: content_cache_retention_period: Periudhë mbajtjeje lënde të largët custom_css: CSS Vetjake favicon: Favikonë + local_live_feed_access: Hyrje te prurje të atypëratyshme që përmbajnë postime vendore + local_topic_feed_access: Hyrje te prurje hashtag-ësh dhe lidhjesh që përmbajnë postime vendore mascot: Simbol vetjak (e dikurshme) media_cache_retention_period: Periudhë mbajtjeje lënde media min_age: Domosdosmëri moshe minimum peers_api_enabled: Publiko te API listë shërbyesish të zbuluar profile_directory: Aktivizo drejtori profilesh registrations_mode: Kush mund të regjistrohet + remote_live_feed_access: Hyrje te prurje të atypëratyshme që përmbajnë postime nga larg + remote_topic_feed_access: Hyrje te prurje hashtag-ësh dhe lidhjesh që përmbajnë postime nga larg require_invite_text: Kërko një arsye për pjesëmarrje show_domain_blocks: Shfaq bllokime përkatësish show_domain_blocks_rationale: Shfaq pse janë bllokuar përkatësitë @@ -365,6 +373,10 @@ sq: name: Emër permissions_as_keys: Leje position: Përparësi + username_block: + allow_with_approval: Lejo regjistrim me miratim + comparison: Metodë krahasimi + username: Fjalë për t’u vëzhguar webhook: events: Akte të aktivizuar template: Gjedhe ngarkese diff --git a/config/locales/sq.yml b/config/locales/sq.yml index b0ce5965645412..3f1978f7c81b38 100644 --- a/config/locales/sq.yml +++ b/config/locales/sq.yml @@ -190,6 +190,7 @@ sq: create_relay: Krijoni Rele create_unavailable_domain: Krijo Përkatësi të Papërdorshme create_user_role: Krijoni Rol + create_username_block: Krijoni Rregull Emrash Përdoruesish demote_user: Zhgradoje Përdoruesin destroy_announcement: Fshije Lajmërimin destroy_canonical_email_block: Fshini Bllokim Email-esh @@ -203,6 +204,7 @@ sq: destroy_status: Fshi Gjendje destroy_unavailable_domain: Fshi Përkatësi të Papërdorshme destroy_user_role: Asgjësoje Rolin + destroy_username_block: Fshini Rregull Emrash Përdoruesish disable_2fa_user: Çaktivizo 2FA-në disable_custom_emoji: Çaktivizo Emotikon Vetjak disable_relay: Çaktivizoje Relenë @@ -237,6 +239,7 @@ sq: update_report: Përditësoni Raportimin update_status: Përditëso Gjendjen update_user_role: Përditësoni Rol + update_username_block: Përditësoni Rregull Emrash Përdoruesish actions: approve_appeal_html: "%{name} miratoi apelim vendimi moderimi nga %{target}" approve_user_html: "%{name} miratoi regjistrim nga %{target}" @@ -255,6 +258,7 @@ sq: create_relay_html: "%{name} krijoi një rele %{target}" create_unavailable_domain_html: "%{name} ndali dërgimin drejt përkatësisë %{target}" create_user_role_html: "%{name} krijoi rolin %{target}" + create_username_block_html: "%{name} shtoi rregull për emra përdoruesish që përmbajnë %{target}" demote_user_html: "%{name} zhgradoi përdoruesin %{target}" destroy_announcement_html: "%{name} fshiu lajmërimin për %{target}" destroy_canonical_email_block_html: "%{name} zhbllokoi email me hashin %{target}" @@ -268,6 +272,7 @@ sq: destroy_status_html: "%{name} hoqi gjendje nga %{target}" destroy_unavailable_domain_html: "%{name} rinisi dërgimin drejt përkatësisë %{target}" destroy_user_role_html: "%{name} fshiu rolin %{target}" + destroy_username_block_html: "%{name} hoqi rregull për emra përdoruesish që përmbajnë %{target}" disable_2fa_user_html: "%{name} çaktivizoi domosdoshmërinë për dyfaktorësh për përdoruesin %{target}" disable_custom_emoji_html: "%{name} çaktivizoi emoxhin %{target}" disable_relay_html: "%{name} çaktivizoi relenë %{target}" @@ -302,6 +307,7 @@ sq: update_report_html: "%{name} përditësoi raportimin %{target}" update_status_html: "%{name} përditësoi gjendjen me %{target}" update_user_role_html: "%{name} ndryshoi rolin për %{target}" + update_username_block_html: "%{name} përditësoi rregull për emra përdoruesish që përmbajnë %{target}" deleted_account: fshiu llogarinë empty: S’u gjetën regjistra. filter_by_action: Filtroji sipas veprimit @@ -505,6 +511,7 @@ sq: select_capabilities: Përzgjidhni Aftësi sign_in: Hyni status: Gjendje + title: Shërbyes Shërbimesh Ndihmëse Fediversi title: FASP follow_recommendations: description_html: "Rekomandimet për ndjekje ndihmojnë përdoruesit e rinj të gjejnë shpejt lëndë me interes. Kur një përdorues nuk ka ndërvepruar mjaftueshëm me të tjerët, që të formohen rekomandime të personalizuara ndjekjeje, rekomandohen këto llogari. Ato përzgjidhen çdo ditë, prej një përzierje llogarish me shkallën më të lartë të angazhimit dhe numrin më të lartë të ndjekësve vendorë për një gjuhë të dhënë." @@ -1090,6 +1097,14 @@ sq: delete: Fshije edit: title: Përpunoni rregull emrash përdoruesi + matches_exactly_html: Baras me %{string} + new: + create: Krijoni rregull + title: Krijoni rregull të ri emrash përdoruesish + no_username_block_selected: S’u ndryshua ndonjë rregull emrash përdoruesishm ngaqë s’u përzgjodh ndonjë + not_permitted: Jo i lejuar + title: Rregulla emrash përdoruesish + updated_msg: Rregulli i emrave të përdoruesve u përditësua me sukses warning_presets: add_new: Shtoni të ri delete: Fshije @@ -1880,6 +1895,7 @@ sq: edited_at_html: Përpunuar më %{date} errors: in_reply_not_found: Gjendja të cilës po provoni t’i përgjigjeni s’duket se ekziston. + quoted_status_not_found: Postimi që po rrekeni të citoni nuk duket se ekziston. over_character_limit: u tejkalua kufi shenjash prej %{max} pin_errors: direct: Postimet që janë të dukshme vetëm për përdoruesit e përmendur s’mund të fiksohen From b7c5e60426bba0bc719eee9370706108ec89f54f Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 9 Oct 2025 11:53:45 +0200 Subject: [PATCH 127/853] Fix quote post state sometimes not being updated through streaming server (#36408) --- app/services/activitypub/process_status_update_service.rb | 2 ++ app/workers/activitypub/refetch_and_verify_quote_worker.rb | 1 + 2 files changed, 3 insertions(+) diff --git a/app/services/activitypub/process_status_update_service.rb b/app/services/activitypub/process_status_update_service.rb index 66c8da2b604df9..62805eaddc182b 100644 --- a/app/services/activitypub/process_status_update_service.rb +++ b/app/services/activitypub/process_status_update_service.rb @@ -74,6 +74,8 @@ def handle_implicit_update! update_quote_approval! update_counts! end + + broadcast_updates! if @status.quote&.state_previously_changed? end def update_interaction_policies! diff --git a/app/workers/activitypub/refetch_and_verify_quote_worker.rb b/app/workers/activitypub/refetch_and_verify_quote_worker.rb index 0c7ecd9b2ac021..e2df0231030767 100644 --- a/app/workers/activitypub/refetch_and_verify_quote_worker.rb +++ b/app/workers/activitypub/refetch_and_verify_quote_worker.rb @@ -10,6 +10,7 @@ class ActivityPub::RefetchAndVerifyQuoteWorker def perform(quote_id, quoted_uri, options = {}) quote = Quote.find(quote_id) ActivityPub::VerifyQuoteService.new.call(quote, fetchable_quoted_uri: quoted_uri, request_id: options[:request_id]) + ::DistributionWorker.perform_async(quote.status_id, { 'update' => true }) if quote.state_previously_changed? rescue ActiveRecord::RecordNotFound # Do nothing true From d4a4a7177ae0a89b2fe44778e92c5da123173535 Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 9 Oct 2025 15:52:38 +0200 Subject: [PATCH 128/853] Fix crash when serializing quotes of deleted posts for ActivityPub (#36381) --- app/lib/activitypub/activity/create.rb | 4 +- app/lib/activitypub/parser/status_parser.rb | 8 ++++ app/models/quote.rb | 2 +- .../activitypub/note_serializer.rb | 10 +++-- .../process_status_update_service.rb | 4 +- spec/lib/activitypub/activity/create_spec.rb | 24 ++++++++++++ .../activitypub/note_serializer_spec.rb | 15 ++++++++ .../process_status_update_service_spec.rb | 38 +++++++++++++++++++ 8 files changed, 97 insertions(+), 8 deletions(-) diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index 607e9be8cc70fd..3d52c9a56ca83d 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -218,11 +218,11 @@ def process_tags def process_quote @quote_uri = @status_parser.quote_uri - return if @quote_uri.blank? + return unless @status_parser.quote? approval_uri = @status_parser.quote_approval_uri approval_uri = nil if unsupported_uri_scheme?(approval_uri) || TagManager.instance.local_url?(approval_uri) - @quote = Quote.new(account: @account, approval_uri: approval_uri, legacy: @status_parser.legacy_quote?) + @quote = Quote.new(account: @account, approval_uri: approval_uri, legacy: @status_parser.legacy_quote?, state: @status_parser.deleted_quote? ? :deleted : :pending) end def process_hashtag(tag) diff --git a/app/lib/activitypub/parser/status_parser.rb b/app/lib/activitypub/parser/status_parser.rb index 7439cca5b2eee5..57e6cb926c4294 100644 --- a/app/lib/activitypub/parser/status_parser.rb +++ b/app/lib/activitypub/parser/status_parser.rb @@ -118,6 +118,14 @@ def quote_policy flags end + def quote? + %w(quote _misskey_quote quoteUrl quoteUri).any? { |key| @object[key].present? } + end + + def deleted_quote? + @object['quote'].is_a?(Hash) && @object['quote']['type'] == 'Tombstone' + end + def quote_uri %w(quote _misskey_quote quoteUrl quoteUri).filter_map do |key| value_or_id(as_array(@object[key]).first) diff --git a/app/models/quote.rb b/app/models/quote.rb index dcfcd3b353cf6e..0d24cb239a8fd4 100644 --- a/app/models/quote.rb +++ b/app/models/quote.rb @@ -25,7 +25,7 @@ class Quote < ApplicationRecord REFRESH_DEADLINE = 6.hours enum :state, - { pending: 0, accepted: 1, rejected: 2, revoked: 3 }, + { pending: 0, accepted: 1, rejected: 2, revoked: 3, deleted: 4 }, validate: true belongs_to :status diff --git a/app/serializers/activitypub/note_serializer.rb b/app/serializers/activitypub/note_serializer.rb index 4c5d3f4cf8f3e8..f162f4ee243ec8 100644 --- a/app/serializers/activitypub/note_serializer.rb +++ b/app/serializers/activitypub/note_serializer.rb @@ -32,8 +32,8 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer attribute :voters_count, if: :poll_and_voters_count? attribute :quote, if: :quote? - attribute :quote, key: :_misskey_quote, if: :quote? - attribute :quote, key: :quote_uri, if: :quote? + attribute :quote, key: :_misskey_quote, if: :serializable_quote? + attribute :quote, key: :quote_uri, if: :serializable_quote? attribute :quote_authorization, if: :quote_authorization? attribute :interaction_policy @@ -214,13 +214,17 @@ def quote? object.quote&.present? end + def serializable_quote? + object.quote&.quoted_status&.present? + end + def quote_authorization? object.quote.present? && ActivityPub::TagManager.instance.approval_uri_for(object.quote).present? end def quote # TODO: handle inlining self-quotes - ActivityPub::TagManager.instance.uri_for(object.quote.quoted_status) + object.quote.quoted_status.present? ? ActivityPub::TagManager.instance.uri_for(object.quote.quoted_status) : { type: 'Tombstone' } end def quote_authorization diff --git a/app/services/activitypub/process_status_update_service.rb b/app/services/activitypub/process_status_update_service.rb index 62805eaddc182b..7e267342580a80 100644 --- a/app/services/activitypub/process_status_update_service.rb +++ b/app/services/activitypub/process_status_update_service.rb @@ -300,7 +300,7 @@ def update_quote_approval! def update_quote! quote_uri = @status_parser.quote_uri - if quote_uri.present? + if @status_parser.quote? approval_uri = @status_parser.quote_approval_uri approval_uri = nil if unsupported_uri_scheme?(approval_uri) || TagManager.instance.local_url?(approval_uri) @@ -310,7 +310,7 @@ def update_quote! # Revoke the quote while we get a chance… maybe this should be a `before_destroy` hook? RevokeQuoteService.new.call(@status.quote) if @status.quote.quoted_account&.local? && @status.quote.accepted? @status.quote.destroy - quote = Quote.create(status: @status, approval_uri: approval_uri, legacy: @status_parser.legacy_quote?) + quote = Quote.create(status: @status, approval_uri: approval_uri, legacy: @status_parser.legacy_quote?, state: @status_parser.deleted_quote? ? :deleted : :pending) @quote_changed = true else quote = @status.quote diff --git a/spec/lib/activitypub/activity/create_spec.rb b/spec/lib/activitypub/activity/create_spec.rb index 80a5c6907c4255..2f2f91e369e4a8 100644 --- a/spec/lib/activitypub/activity/create_spec.rb +++ b/spec/lib/activitypub/activity/create_spec.rb @@ -938,6 +938,30 @@ def activity_for_object(json) end end + context 'with an unverifiable quote of a dead post' do + let(:quoted_status) { Fabricate(:status) } + + let(:object_json) do + build_object( + type: 'Note', + content: 'woah what she said is amazing', + quote: { type: 'Tombstone' } + ) + end + + it 'creates a status with an unverified quote' do + expect { subject.perform }.to change(sender.statuses, :count).by(1) + + status = sender.statuses.first + expect(status).to_not be_nil + expect(status.quote).to_not be_nil + expect(status.quote).to have_attributes( + state: 'deleted', + approval_uri: nil + ) + end + end + context 'with an unverifiable unknown post' do let(:unknown_post_uri) { 'https://unavailable.example.com/unavailable-post' } diff --git a/spec/serializers/activitypub/note_serializer_spec.rb b/spec/serializers/activitypub/note_serializer_spec.rb index 04179e9bf4dd15..0d11386d57b777 100644 --- a/spec/serializers/activitypub/note_serializer_spec.rb +++ b/spec/serializers/activitypub/note_serializer_spec.rb @@ -58,6 +58,21 @@ def reply_items end end + context 'with a deleted quote' do + let(:quoted_status) { Fabricate(:status) } + + before do + Fabricate(:quote, status: parent, quoted_status: nil, state: :accepted) + end + + it 'has the expected shape' do + expect(subject).to include({ + 'type' => 'Note', + 'quote' => { 'type' => 'Tombstone' }, + }) + end + end + context 'with a quote policy' do let(:parent) { Fabricate(:status, quote_approval_policy: Status::QUOTE_APPROVAL_POLICY_FLAGS[:followers] << 16) } diff --git a/spec/services/activitypub/process_status_update_service_spec.rb b/spec/services/activitypub/process_status_update_service_spec.rb index 7af2c67387fb4a..56a8c71cbe8478 100644 --- a/spec/services/activitypub/process_status_update_service_spec.rb +++ b/spec/services/activitypub/process_status_update_service_spec.rb @@ -1053,6 +1053,44 @@ end end + context 'when the status swaps a verified quote with an ID-less Tombstone through an explicit update' do + let(:quoted_account) { Fabricate(:account, domain: 'quoted.example.com') } + let(:quoted_status) { Fabricate(:status, account: quoted_account) } + let(:second_quoted_status) { Fabricate(:status, account: quoted_account) } + let!(:quote) { Fabricate(:quote, status: status, quoted_status: quoted_status, approval_uri: approval_uri, state: :accepted) } + let(:approval_uri) { 'https://quoted.example.com/approvals/1' } + + let(:payload) do + { + '@context': [ + 'https://www.w3.org/ns/activitystreams', + { + '@id': 'https://w3id.org/fep/044f#quote', + '@type': '@id', + }, + { + '@id': 'https://w3id.org/fep/044f#quoteAuthorization', + '@type': '@id', + }, + ], + id: 'foo', + type: 'Note', + summary: 'Show more', + content: 'Hello universe', + updated: '2021-09-08T22:39:25Z', + quote: { type: 'Tombstone' }, + } + end + + it 'updates the URI and unverifies the quote' do + expect { subject.call(status, json, json) } + .to change { status.quote.quoted_status }.from(quoted_status).to(nil) + .and change { status.quote.state }.from('accepted').to('deleted') + + expect { quote.reload }.to raise_error(ActiveRecord::RecordNotFound) + end + end + context 'when the status swaps a verified quote with another verifiable quote through an explicit update' do let(:quoted_account) { Fabricate(:account, domain: 'quoted.example.com') } let(:second_quoted_account) { Fabricate(:account, domain: 'second-quoted.example.com') } From 258869278e8f42ff7c1795eb024c7c2ed6cfebca Mon Sep 17 00:00:00 2001 From: Echo Date: Thu, 9 Oct 2025 16:08:36 +0200 Subject: [PATCH 129/853] Fix: Embed author handle using wrong DisplayName (#36413) --- .../explore/components/author_link.jsx | 23 ------------------- .../explore/components/author_link.tsx | 22 ++++++++++++++++++ 2 files changed, 22 insertions(+), 23 deletions(-) delete mode 100644 app/javascript/mastodon/features/explore/components/author_link.jsx create mode 100644 app/javascript/mastodon/features/explore/components/author_link.tsx diff --git a/app/javascript/mastodon/features/explore/components/author_link.jsx b/app/javascript/mastodon/features/explore/components/author_link.jsx deleted file mode 100644 index cf92ebc78b36a0..00000000000000 --- a/app/javascript/mastodon/features/explore/components/author_link.jsx +++ /dev/null @@ -1,23 +0,0 @@ -import PropTypes from 'prop-types'; - -import { Avatar } from 'mastodon/components/avatar'; -import { useAppSelector } from 'mastodon/store'; -import { LinkedDisplayName } from '@/mastodon/components/display_name'; - -export const AuthorLink = ({ accountId }) => { - const account = useAppSelector(state => state.getIn(['accounts', accountId])); - - if (!account) { - return null; - } - - return ( - - - - ); -}; - -AuthorLink.propTypes = { - accountId: PropTypes.string.isRequired, -}; diff --git a/app/javascript/mastodon/features/explore/components/author_link.tsx b/app/javascript/mastodon/features/explore/components/author_link.tsx new file mode 100644 index 00000000000000..a4667693a59ad5 --- /dev/null +++ b/app/javascript/mastodon/features/explore/components/author_link.tsx @@ -0,0 +1,22 @@ +import type { FC } from 'react'; + +import { LinkedDisplayName } from '@/mastodon/components/display_name'; +import { Avatar } from 'mastodon/components/avatar'; +import { useAppSelector } from 'mastodon/store'; + +export const AuthorLink: FC<{ accountId: string }> = ({ accountId }) => { + const account = useAppSelector((state) => state.accounts.get(accountId)); + + if (!account) { + return null; + } + + return ( + + + + ); +}; From c858fc77ef194be0217fd98eae84efd261dba798 Mon Sep 17 00:00:00 2001 From: Echo Date: Thu, 9 Oct 2025 16:31:13 +0200 Subject: [PATCH 130/853] Fixes handled link formatting (#36410) Co-authored-by: Claire --- .../status/handled_link.stories.tsx | 32 ++++++++++- .../components/status/handled_link.tsx | 56 +++++++++---------- .../mastodon/components/status_content.jsx | 6 +- 3 files changed, 60 insertions(+), 34 deletions(-) diff --git a/app/javascript/mastodon/components/status/handled_link.stories.tsx b/app/javascript/mastodon/components/status/handled_link.stories.tsx index 71bf8eee63de6b..e34383370486c3 100644 --- a/app/javascript/mastodon/components/status/handled_link.stories.tsx +++ b/app/javascript/mastodon/components/status/handled_link.stories.tsx @@ -1,19 +1,24 @@ import type { Meta, StoryObj } from '@storybook/react-vite'; import { HashtagMenuController } from '@/mastodon/features/ui/components/hashtag_menu_controller'; +import { accountFactoryState } from '@/testing/factories'; import { HoverCardController } from '../hover_card_controller'; import type { HandledLinkProps } from './handled_link'; import { HandledLink } from './handled_link'; -type HandledLinkStoryProps = Pick & { +type HandledLinkStoryProps = Pick< + HandledLinkProps, + 'href' | 'text' | 'prevText' +> & { mentionAccount: 'local' | 'remote' | 'none'; + hashtagAccount: boolean; }; const meta = { title: 'Components/Status/HandledLink', - render({ mentionAccount, ...args }) { + render({ mentionAccount, hashtagAccount, ...args }) { let mention: HandledLinkProps['mention'] | undefined; if (mentionAccount === 'local') { mention = { id: '1', acct: 'testuser' }; @@ -22,7 +27,13 @@ const meta = { } return ( <> - + + {args.text} + @@ -32,6 +43,7 @@ const meta = { href: 'https://example.com/path/subpath?query=1#hash', text: 'https://example.com', mentionAccount: 'none', + hashtagAccount: false, }, argTypes: { mentionAccount: { @@ -40,6 +52,13 @@ const meta = { defaultValue: 'none', }, }, + parameters: { + state: { + accounts: { + '1': accountFactoryState({ id: '1', acct: 'hashtaguser' }), + }, + }, + }, } satisfies Meta; export default meta; @@ -48,9 +67,16 @@ type Story = StoryObj; export const Default: Story = {}; +export const Simple: Story = { + args: { + href: 'https://example.com/test', + }, +}; + export const Hashtag: Story = { args: { text: '#example', + hashtagAccount: true, }, }; diff --git a/app/javascript/mastodon/components/status/handled_link.tsx b/app/javascript/mastodon/components/status/handled_link.tsx index 0f486b33e95b53..3c8973992bdd1c 100644 --- a/app/javascript/mastodon/components/status/handled_link.tsx +++ b/app/javascript/mastodon/components/status/handled_link.tsx @@ -10,6 +10,7 @@ import type { OnElementHandler } from '@/mastodon/utils/html'; export interface HandledLinkProps { href: string; text: string; + prevText?: string; hashtagAccountId?: string; mention?: Pick; } @@ -17,13 +18,15 @@ export interface HandledLinkProps { export const HandledLink: FC> = ({ href, text, + prevText, hashtagAccountId, mention, className, + children, ...props }) => { // Handle hashtags - if (text.startsWith('#')) { + if (text.startsWith('#') || prevText?.endsWith('#')) { const hashtag = text.slice(1).trim(); return ( > = ({ rel='tag' data-menu-hashtag={hashtagAccountId} > - #{hashtag} + {children} ); - } else if (text.startsWith('@') && mention) { + } else if ((text.startsWith('@') || prevText?.endsWith('@')) && mention) { // Handle mentions return ( > = ({ title={`@${mention.acct}`} data-hover-card-account={mention.id} > - @{text.slice(1).trim()} + {children} ); } - // Non-absolute paths treated as internal links. + // Non-absolute paths treated as internal links. This shouldn't happen, but just in case. if (href.startsWith('/')) { return ( - {text} + {children} ); } - try { - const url = new URL(href); - const [first, ...rest] = url.pathname.split('/').slice(1); // Start at 1 to skip the leading slash. - return ( - - {url.protocol + '//'} - {`${url.hostname}/${first ?? ''}`} - {'/' + rest.join('/')} - - ); - } catch { - return text; - } + return ( + + {children} + + ); }; export const useElementHandledLink = ({ @@ -89,7 +84,7 @@ export const useElementHandledLink = ({ hrefToMention?: (href: string) => ApiMentionJSON | undefined; } = {}) => { const onElement = useCallback( - (element, { key, ...props }) => { + (element, { key, ...props }, children) => { if (element instanceof HTMLAnchorElement) { const mention = hrefToMention?.(element.href); return ( @@ -98,9 +93,12 @@ export const useElementHandledLink = ({ key={key as string} // React requires keys to not be part of spread props. href={element.href} text={element.innerText} + prevText={element.previousSibling?.textContent ?? undefined} hashtagAccountId={hashtagAccountId} mention={mention} - /> + > + {children} + ); } return undefined; diff --git a/app/javascript/mastodon/components/status_content.jsx b/app/javascript/mastodon/components/status_content.jsx index 54579a1134fffd..14779ce3a4375e 100644 --- a/app/javascript/mastodon/components/status_content.jsx +++ b/app/javascript/mastodon/components/status_content.jsx @@ -204,7 +204,7 @@ class StatusContent extends PureComponent { this.node = c; }; - handleElement = (element, { key, ...props }) => { + handleElement = (element, { key, ...props }, children) => { if (element instanceof HTMLAnchorElement) { const mention = this.props.status.get('mentions').find(item => element.href === item.get('url')); return ( @@ -215,7 +215,9 @@ class StatusContent extends PureComponent { hashtagAccountId={this.props.status.getIn(['account', 'id'])} mention={mention?.toJSON()} key={key} - /> + > + {children} + ); } else if (element instanceof HTMLParagraphElement && element.classList.contains('quote-inline')) { return null; From 48bb64cde35b6146c1f96a6d7a31ac95c2f30346 Mon Sep 17 00:00:00 2001 From: Echo Date: Wed, 8 Oct 2025 19:17:03 +0200 Subject: [PATCH 131/853] [Glitch] Emoji: Fixes issue with handled link not correctly showing remote users Port 5bc7c4b7e880ee1456dc21987d8fba32e340d31e to glitch-soc Signed-off-by: Claire --- .../status/handled_link.stories.tsx | 29 +++++++++----- .../glitch/components/status/handled_link.tsx | 38 +++++++++---------- .../glitch/components/status_content.jsx | 2 +- .../components/embedded_status_content.tsx | 5 +-- 4 files changed, 42 insertions(+), 32 deletions(-) diff --git a/app/javascript/flavours/glitch/components/status/handled_link.stories.tsx b/app/javascript/flavours/glitch/components/status/handled_link.stories.tsx index abc2aa6cefa2f4..9fab8997387606 100644 --- a/app/javascript/flavours/glitch/components/status/handled_link.stories.tsx +++ b/app/javascript/flavours/glitch/components/status/handled_link.stories.tsx @@ -1,19 +1,28 @@ import type { Meta, StoryObj } from '@storybook/react-vite'; import { HashtagMenuController } from '@/flavours/glitch/features/ui/components/hashtag_menu_controller'; -import { accountFactoryState } from '@/testing/factories'; import { HoverCardController } from '../hover_card_controller'; import type { HandledLinkProps } from './handled_link'; import { HandledLink } from './handled_link'; +type HandledLinkStoryProps = Pick & { + mentionAccount: 'local' | 'remote' | 'none'; +}; + const meta = { title: 'Components/Status/HandledLink', - render(args) { + render({ mentionAccount, ...args }) { + let mention: HandledLinkProps['mention'] | undefined; + if (mentionAccount === 'local') { + mention = { id: '1', acct: 'testuser' }; + } else if (mentionAccount === 'remote') { + mention = { id: '2', acct: 'remoteuser@mastodon.social' }; + } return ( <> - + @@ -22,15 +31,16 @@ const meta = { args: { href: 'https://example.com/path/subpath?query=1#hash', text: 'https://example.com', + mentionAccount: 'none', }, - parameters: { - state: { - accounts: { - '1': accountFactoryState(), - }, + argTypes: { + mentionAccount: { + control: { type: 'select' }, + options: ['local', 'remote', 'none'], + defaultValue: 'none', }, }, -} satisfies Meta>; +} satisfies Meta; export default meta; @@ -47,6 +57,7 @@ export const Hashtag: Story = { export const Mention: Story = { args: { text: '@user', + mentionAccount: 'local', }, }; diff --git a/app/javascript/flavours/glitch/components/status/handled_link.tsx b/app/javascript/flavours/glitch/components/status/handled_link.tsx index c153053b233a5d..d86ec4785203ef 100644 --- a/app/javascript/flavours/glitch/components/status/handled_link.tsx +++ b/app/javascript/flavours/glitch/components/status/handled_link.tsx @@ -1,22 +1,25 @@ import { useCallback } from 'react'; import type { ComponentProps, FC } from 'react'; +import classNames from 'classnames'; import { Link } from 'react-router-dom'; +import type { ApiMentionJSON } from '@/flavours/glitch/api_types/statuses'; import type { OnElementHandler } from '@/flavours/glitch/utils/html'; export interface HandledLinkProps { href: string; text: string; hashtagAccountId?: string; - mentionAccountId?: string; + mention?: Pick; } export const HandledLink: FC> = ({ href, text, hashtagAccountId, - mentionAccountId, + mention, + className, ...props }) => { // Handle hashtags @@ -24,8 +27,7 @@ export const HandledLink: FC> = ({ const hashtag = text.slice(1).trim(); return ( > = ({ #{hashtag} ); - } else if (text.startsWith('@')) { + } else if (text.startsWith('@') && mention) { // Handle mentions - const mention = text.slice(1).trim(); return ( - @{mention} + @{text.slice(1).trim()} ); } @@ -52,7 +52,7 @@ export const HandledLink: FC> = ({ // Non-absolute paths treated as internal links. if (href.startsWith('/')) { return ( - + {text} ); @@ -66,7 +66,7 @@ export const HandledLink: FC> = ({ {...props} href={href} title={href} - className='unhandled-link' + className={classNames('unhandled-link', className)} target='_blank' rel='noreferrer noopener' translate='no' @@ -83,15 +83,15 @@ export const HandledLink: FC> = ({ export const useElementHandledLink = ({ hashtagAccountId, - hrefToMentionAccountId, + hrefToMention, }: { hashtagAccountId?: string; - hrefToMentionAccountId?: (href: string) => string | undefined; + hrefToMention?: (href: string) => ApiMentionJSON | undefined; } = {}) => { const onElement = useCallback( (element, { key, ...props }) => { if (element instanceof HTMLAnchorElement) { - const mentionId = hrefToMentionAccountId?.(element.href); + const mention = hrefToMention?.(element.href); return ( ); } return undefined; }, - [hashtagAccountId, hrefToMentionAccountId], + [hashtagAccountId, hrefToMention], ); return { onElement }; }; diff --git a/app/javascript/flavours/glitch/components/status_content.jsx b/app/javascript/flavours/glitch/components/status_content.jsx index d3c48dcbe9d7bd..81ce42a0a91e01 100644 --- a/app/javascript/flavours/glitch/components/status_content.jsx +++ b/app/javascript/flavours/glitch/components/status_content.jsx @@ -310,7 +310,7 @@ class StatusContent extends PureComponent { href={element.href} text={element.innerText} hashtagAccountId={this.props.status.getIn(['account', 'id'])} - mentionAccountId={mention?.get('id')} + mention={mention?.toJSON()} key={key} /> ); diff --git a/app/javascript/flavours/glitch/features/notifications_v2/components/embedded_status_content.tsx b/app/javascript/flavours/glitch/features/notifications_v2/components/embedded_status_content.tsx index 3cb1e12ed41e15..5d9d23e2e9df73 100644 --- a/app/javascript/flavours/glitch/features/notifications_v2/components/embedded_status_content.tsx +++ b/app/javascript/flavours/glitch/features/notifications_v2/components/embedded_status_content.tsx @@ -48,9 +48,8 @@ export const EmbeddedStatusContent: React.FC<{ ); const htmlHandlers = useElementHandledLink({ hashtagAccountId: status.get('account') as string | undefined, - hrefToMentionAccountId(href) { - const mention = mentions.find((item) => item.url === href); - return mention?.id; + hrefToMention(href) { + return mentions.find((item) => item.url === href); }, }); From 3c3a812a9c41ff59275453ef49fc4784a3656755 Mon Sep 17 00:00:00 2001 From: Echo Date: Thu, 9 Oct 2025 16:08:36 +0200 Subject: [PATCH 132/853] [Glitch] Fix: Embed author handle using wrong DisplayName Port 258869278e8f42ff7c1795eb024c7c2ed6cfebca to glitch-soc Signed-off-by: Claire --- .../explore/components/author_link.jsx | 23 ------------------- .../explore/components/author_link.tsx | 22 ++++++++++++++++++ 2 files changed, 22 insertions(+), 23 deletions(-) delete mode 100644 app/javascript/flavours/glitch/features/explore/components/author_link.jsx create mode 100644 app/javascript/flavours/glitch/features/explore/components/author_link.tsx diff --git a/app/javascript/flavours/glitch/features/explore/components/author_link.jsx b/app/javascript/flavours/glitch/features/explore/components/author_link.jsx deleted file mode 100644 index 9dad72b48aca1e..00000000000000 --- a/app/javascript/flavours/glitch/features/explore/components/author_link.jsx +++ /dev/null @@ -1,23 +0,0 @@ -import PropTypes from 'prop-types'; - -import { Avatar } from 'flavours/glitch/components/avatar'; -import { useAppSelector } from 'flavours/glitch/store'; -import { LinkedDisplayName } from '../../../components/display_name'; - -export const AuthorLink = ({ accountId }) => { - const account = useAppSelector(state => state.getIn(['accounts', accountId])); - - if (!account) { - return null; - } - - return ( - - - - ); -}; - -AuthorLink.propTypes = { - accountId: PropTypes.string.isRequired, -}; diff --git a/app/javascript/flavours/glitch/features/explore/components/author_link.tsx b/app/javascript/flavours/glitch/features/explore/components/author_link.tsx new file mode 100644 index 00000000000000..fefd5803a28ce3 --- /dev/null +++ b/app/javascript/flavours/glitch/features/explore/components/author_link.tsx @@ -0,0 +1,22 @@ +import type { FC } from 'react'; + +import { LinkedDisplayName } from '@/flavours/glitch/components/display_name'; +import { Avatar } from 'flavours/glitch/components/avatar'; +import { useAppSelector } from 'flavours/glitch/store'; + +export const AuthorLink: FC<{ accountId: string }> = ({ accountId }) => { + const account = useAppSelector((state) => state.accounts.get(accountId)); + + if (!account) { + return null; + } + + return ( + + + + ); +}; From 8a50fb02ce46d33439ff0c15533e12bdab140291 Mon Sep 17 00:00:00 2001 From: Echo Date: Thu, 9 Oct 2025 16:31:13 +0200 Subject: [PATCH 133/853] [Glitch] Fixes handled link formatting Port c858fc77ef194be0217fd98eae84efd261dba798 to glitch-soc Co-authored-by: Claire Signed-off-by: Claire --- .../status/handled_link.stories.tsx | 32 ++++++++++- .../glitch/components/status/handled_link.tsx | 56 +++++++++---------- .../glitch/components/status_content.jsx | 6 +- 3 files changed, 60 insertions(+), 34 deletions(-) diff --git a/app/javascript/flavours/glitch/components/status/handled_link.stories.tsx b/app/javascript/flavours/glitch/components/status/handled_link.stories.tsx index 9fab8997387606..f29f957dfeb039 100644 --- a/app/javascript/flavours/glitch/components/status/handled_link.stories.tsx +++ b/app/javascript/flavours/glitch/components/status/handled_link.stories.tsx @@ -1,19 +1,24 @@ import type { Meta, StoryObj } from '@storybook/react-vite'; import { HashtagMenuController } from '@/flavours/glitch/features/ui/components/hashtag_menu_controller'; +import { accountFactoryState } from '@/testing/factories'; import { HoverCardController } from '../hover_card_controller'; import type { HandledLinkProps } from './handled_link'; import { HandledLink } from './handled_link'; -type HandledLinkStoryProps = Pick & { +type HandledLinkStoryProps = Pick< + HandledLinkProps, + 'href' | 'text' | 'prevText' +> & { mentionAccount: 'local' | 'remote' | 'none'; + hashtagAccount: boolean; }; const meta = { title: 'Components/Status/HandledLink', - render({ mentionAccount, ...args }) { + render({ mentionAccount, hashtagAccount, ...args }) { let mention: HandledLinkProps['mention'] | undefined; if (mentionAccount === 'local') { mention = { id: '1', acct: 'testuser' }; @@ -22,7 +27,13 @@ const meta = { } return ( <> - + + {args.text} + @@ -32,6 +43,7 @@ const meta = { href: 'https://example.com/path/subpath?query=1#hash', text: 'https://example.com', mentionAccount: 'none', + hashtagAccount: false, }, argTypes: { mentionAccount: { @@ -40,6 +52,13 @@ const meta = { defaultValue: 'none', }, }, + parameters: { + state: { + accounts: { + '1': accountFactoryState({ id: '1', acct: 'hashtaguser' }), + }, + }, + }, } satisfies Meta; export default meta; @@ -48,9 +67,16 @@ type Story = StoryObj; export const Default: Story = {}; +export const Simple: Story = { + args: { + href: 'https://example.com/test', + }, +}; + export const Hashtag: Story = { args: { text: '#example', + hashtagAccount: true, }, }; diff --git a/app/javascript/flavours/glitch/components/status/handled_link.tsx b/app/javascript/flavours/glitch/components/status/handled_link.tsx index d86ec4785203ef..dfc81cb96bbc23 100644 --- a/app/javascript/flavours/glitch/components/status/handled_link.tsx +++ b/app/javascript/flavours/glitch/components/status/handled_link.tsx @@ -10,6 +10,7 @@ import type { OnElementHandler } from '@/flavours/glitch/utils/html'; export interface HandledLinkProps { href: string; text: string; + prevText?: string; hashtagAccountId?: string; mention?: Pick; } @@ -17,13 +18,15 @@ export interface HandledLinkProps { export const HandledLink: FC> = ({ href, text, + prevText, hashtagAccountId, mention, className, + children, ...props }) => { // Handle hashtags - if (text.startsWith('#')) { + if (text.startsWith('#') || prevText?.endsWith('#')) { const hashtag = text.slice(1).trim(); return ( > = ({ rel='tag' data-menu-hashtag={hashtagAccountId} > - #{hashtag} + {children} ); - } else if (text.startsWith('@') && mention) { + } else if ((text.startsWith('@') || prevText?.endsWith('@')) && mention) { // Handle mentions return ( > = ({ title={`@${mention.acct}`} data-hover-card-account={mention.id} > - @{text.slice(1).trim()} + {children} ); } - // Non-absolute paths treated as internal links. + // Non-absolute paths treated as internal links. This shouldn't happen, but just in case. if (href.startsWith('/')) { return ( - {text} + {children} ); } - try { - const url = new URL(href); - const [first, ...rest] = url.pathname.split('/').slice(1); // Start at 1 to skip the leading slash. - return ( - - {url.protocol + '//'} - {`${url.hostname}/${first ?? ''}`} - {'/' + rest.join('/')} - - ); - } catch { - return text; - } + return ( + + {children} + + ); }; export const useElementHandledLink = ({ @@ -89,7 +84,7 @@ export const useElementHandledLink = ({ hrefToMention?: (href: string) => ApiMentionJSON | undefined; } = {}) => { const onElement = useCallback( - (element, { key, ...props }) => { + (element, { key, ...props }, children) => { if (element instanceof HTMLAnchorElement) { const mention = hrefToMention?.(element.href); return ( @@ -98,9 +93,12 @@ export const useElementHandledLink = ({ key={key as string} // React requires keys to not be part of spread props. href={element.href} text={element.innerText} + prevText={element.previousSibling?.textContent ?? undefined} hashtagAccountId={hashtagAccountId} mention={mention} - /> + > + {children} + ); } return undefined; diff --git a/app/javascript/flavours/glitch/components/status_content.jsx b/app/javascript/flavours/glitch/components/status_content.jsx index 81ce42a0a91e01..6f7b9e0fdf5f64 100644 --- a/app/javascript/flavours/glitch/components/status_content.jsx +++ b/app/javascript/flavours/glitch/components/status_content.jsx @@ -301,7 +301,7 @@ class StatusContent extends PureComponent { this.node = c; }; - handleElement = (element, { key, ...props }) => { + handleElement = (element, { key, ...props }, children) => { if (element instanceof HTMLAnchorElement) { const mention = this.props.status.get('mentions').find(item => element.href === item.get('url')); return ( @@ -312,7 +312,9 @@ class StatusContent extends PureComponent { hashtagAccountId={this.props.status.getIn(['account', 'id'])} mention={mention?.toJSON()} key={key} - /> + > + {children} + ); } else if (element instanceof HTMLParagraphElement && element.classList.contains('quote-inline')) { return null; From 81350c7cfb217349d0d73b6250faaf05c054fd08 Mon Sep 17 00:00:00 2001 From: Emelia Smith Date: Fri, 10 Oct 2025 10:43:48 +0200 Subject: [PATCH 134/853] Add support for displaying link previews for Admin UI (#35958) --- app/helpers/statuses_helper.rb | 14 +++++ app/javascript/entrypoints/admin.tsx | 41 ++++++++++++++ app/javascript/styles/mastodon/admin.scss | 55 +++++++++++++++++++ app/models/status_edit.rb | 4 ++ .../admin/shared/_preview_card.html.haml | 30 ++++++++++ .../shared/_status_attachments.html.haml | 3 + config/locales/en.yml | 7 +++ 7 files changed, 154 insertions(+) create mode 100644 app/views/admin/shared/_preview_card.html.haml diff --git a/app/helpers/statuses_helper.rb b/app/helpers/statuses_helper.rb index 9cf64d09b4d0ad..68e9b130478514 100644 --- a/app/helpers/statuses_helper.rb +++ b/app/helpers/statuses_helper.rb @@ -57,6 +57,20 @@ def status_description(status) components.compact_blank.join("\n\n") end + # This logic should be kept in sync with https://github.com/mastodon/mastodon/blob/425311e1d95c8a64ddac6c724fca247b8b893a82/app/javascript/mastodon/features/status/components/card.jsx#L160 + def preview_card_aspect_ratio_classname(preview_card) + interactive = preview_card.type == 'video' + large_image = (preview_card.image.present? && preview_card.width > preview_card.height) || interactive + + if large_image && interactive + 'status-card__image--video' + elsif large_image + 'status-card__image--large' + else + 'status-card__image--normal' + end + end + def visibility_icon(status) VISIBLITY_ICONS[status.visibility.to_sym] end diff --git a/app/javascript/entrypoints/admin.tsx b/app/javascript/entrypoints/admin.tsx index a60778f0c045f7..af9309d342c450 100644 --- a/app/javascript/entrypoints/admin.tsx +++ b/app/javascript/entrypoints/admin.tsx @@ -1,6 +1,7 @@ import { createRoot } from 'react-dom/client'; import Rails from '@rails/ujs'; +import { decode, ValidationError } from 'blurhash'; import ready from '../mastodon/ready'; @@ -362,6 +363,46 @@ ready(() => { document.querySelectorAll('[data-admin-component]').forEach((element) => { void mountReactComponent(element); }); + + document + .querySelectorAll('canvas[data-blurhash]') + .forEach((canvas) => { + const blurhash = canvas.dataset.blurhash; + if (blurhash) { + try { + // decode returns a Uint8ClampedArray not Uint8ClampedArray + const pixels = decode( + blurhash, + 32, + 32, + ) as Uint8ClampedArray; + const ctx = canvas.getContext('2d'); + const imageData = new ImageData(pixels, 32, 32); + + ctx?.putImageData(imageData, 0, 0); + } catch (err) { + if (err instanceof ValidationError) { + // ignore blurhash validation errors + return; + } + + throw err; + } + } + }); + + document + .querySelectorAll('.preview-card') + .forEach((previewCard) => { + const spoilerButton = previewCard.querySelector('.spoiler-button'); + if (!spoilerButton) { + return; + } + + spoilerButton.addEventListener('click', () => { + previewCard.classList.toggle('preview-card--image-visible'); + }); + }); }).catch((reason: unknown) => { throw reason; }); diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss index e2a3f0c0afe06a..4299004df799d9 100644 --- a/app/javascript/styles/mastodon/admin.scss +++ b/app/javascript/styles/mastodon/admin.scss @@ -1969,6 +1969,61 @@ a.sparkline { display: list-item; } } + + .preview-card { + position: relative; + max-width: 566px; + + .status-card__image { + &--video { + aspect-ratio: 16 / 9; + } + + &--large { + aspect-ratio: 1.91 / 1; + } + + aspect-ratio: 1; + } + + .spoiler-button__overlay__label { + outline: 1px solid var(--media-outline-color); + } + + .hide-button { + // Toggled to appear when the preview-card is unblurred: + display: none; + position: absolute; + top: 5px; + right: 5px; + color: $white; + border: 0; + outline: 1px solid var(--media-outline-color); + background-color: color.change($black, $alpha: 0.45); + backdrop-filter: $backdrop-blur-filter; + padding: 3px 12px; + border-radius: 99px; + font-size: 14px; + font-weight: 700; + line-height: 20px; + + &:hover, + &:focus { + background-color: color.change($black, $alpha: 0.9); + } + } + + &.preview-card--image-visible { + .hide-button { + display: block; + } + + .spoiler-button__overlay, + .status-card__image-preview { + display: none; + } + } + } } .admin { diff --git a/app/models/status_edit.rb b/app/models/status_edit.rb index d99591d79929da..060866e50c3518 100644 --- a/app/models/status_edit.rb +++ b/app/models/status_edit.rb @@ -52,6 +52,10 @@ def quote underlying_quote end + def with_preview_card? + false + end + def with_media? ordered_media_attachments.any? end diff --git a/app/views/admin/shared/_preview_card.html.haml b/app/views/admin/shared/_preview_card.html.haml new file mode 100644 index 00000000000000..c4796dc59cc384 --- /dev/null +++ b/app/views/admin/shared/_preview_card.html.haml @@ -0,0 +1,30 @@ +/# locals: (preview_card:) + +.preview-card + .status-card.expanded + .status-card__image{ class: preview_card_aspect_ratio_classname(preview_card) } + .spoiler-button + %button.hide-button{ type: 'button' }= t('link_preview.potentially_sensitive_content.hide_button') + %button.spoiler-button__overlay{ type: 'button' } + %span.spoiler-button__overlay__label + %span= t('link_preview.potentially_sensitive_content.label') + %span.spoiler-button__overlay__action + %span= t('link_preview.potentially_sensitive_content.action') + %canvas.status-card__image-preview{ 'data-blurhash': preview_card.blurhash, width: 32, height: 32 } + = image_tag preview_card.image.url, alt: '', class: 'status-card__image-image' + = link_to preview_card.url, target: '_blank', rel: 'noopener', data: { confirm: t('link_preview.potentially_sensitive_content.confirm_visit') } do + .status-card__content{ dir: 'auto' } + %span.status-card__host + %span{ lang: preview_card.language } + = preview_card.provider_name + - if preview_card.published_at + · + %time.relative-formatted{ datetime: preview_card.published_at.iso8601, title: l(preview_card.published_at) }= l(preview_card.published_at) + %strong.status-card__title{ title: preview_card.title, lang: preview_card.language } + = preview_card.title + - if preview_card.author_name.present? + %span.status-card__author + = t('link_preview.author_html', name: content_tag(:strong, preview_card.author_name)) + - else + %span.status-card__description{ lang: preview_card.language } + = preview_card.description diff --git a/app/views/admin/shared/_status_attachments.html.haml b/app/views/admin/shared/_status_attachments.html.haml index d34a4221db72aa..8fca4add52e4e9 100644 --- a/app/views/admin/shared/_status_attachments.html.haml +++ b/app/views/admin/shared/_status_attachments.html.haml @@ -13,6 +13,9 @@ %button.button.button-secondary{ disabled: true } = t('polls.vote') +- if status.with_preview_card? + = render partial: 'admin/shared/preview_card', locals: { preview_card: status.preview_card } + - if status.with_media? - if status.ordered_media_attachments.first.video? = render_video_component(status, visible: false) diff --git a/config/locales/en.yml b/config/locales/en.yml index 91b5b23bd0cffd..025ad1ea08aa32 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1591,6 +1591,13 @@ en: expires_at: Expires uses: Uses title: Invite people + link_preview: + author_html: By %{name} + potentially_sensitive_content: + action: Click to show + confirm_visit: Are you sure you wish to open this link? + hide_button: Hide + label: Potentially sensitive content lists: errors: limit: You have reached the maximum number of lists From 8898f120dc1b5ad0d543360541fe99b5c10fa77b Mon Sep 17 00:00:00 2001 From: Emelia Smith Date: Fri, 10 Oct 2025 10:55:41 +0200 Subject: [PATCH 135/853] Improve display of content warnings in Admin UI (#35935) --- app/javascript/styles/mastodon/admin.scss | 47 +++++++++++++++++-- .../admin/shared/_status_content.html.haml | 10 +++- config/locales/en.yml | 3 ++ 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss index 4299004df799d9..2e05284e2828f5 100644 --- a/app/javascript/styles/mastodon/admin.scss +++ b/app/javascript/styles/mastodon/admin.scss @@ -1946,7 +1946,6 @@ a.sparkline { .status__card { padding: 15px; border-radius: 4px; - background: $ui-base-color; font-size: 15px; line-height: 20px; word-wrap: break-word; @@ -1965,8 +1964,50 @@ a.sparkline { .status__content { padding-top: 0; - summary { - display: list-item; + > details { + summary { + display: block; + box-sizing: border-box; + background: var(--nested-card-background); + color: var(--nested-card-text); + border: var(--nested-card-border); + border-radius: 8px; + padding: 8px 13px; + position: relative; + font-size: 15px; + line-height: 22px; + cursor: pointer; + + &::after { + content: attr(data-show, 'Show more'); + margin-top: 8px; + display: block; + font-size: 15px; + line-height: 20px; + color: $highlight-text-color; + cursor: pointer; + border: 0; + background: transparent; + padding: 0; + text-decoration: none; + font-weight: 500; + } + + &:hover, + &:focus-visible { + &::after { + text-decoration: underline !important; + } + } + } + + &[open] summary { + margin-bottom: 16px; + + &::after { + content: attr(data-hide, 'Hide post'); + } + } } } diff --git a/app/views/admin/shared/_status_content.html.haml b/app/views/admin/shared/_status_content.html.haml index aedd84bdd679ef..465696fe5e9547 100644 --- a/app/views/admin/shared/_status_content.html.haml +++ b/app/views/admin/shared/_status_content.html.haml @@ -1,8 +1,14 @@ .status__content>< - if status.spoiler_text.present? %details< - %summary>< - %strong> Content warning: #{prerender_custom_emojis(h(status.spoiler_text), status.emojis)} + %summary{ + data: { + show: t('statuses.content_warnings.show'), + hide: t('statuses.content_warnings.hide'), + } + }>< + %strong> + = prerender_custom_emojis(h(status.spoiler_text), status.emojis) = prerender_custom_emojis(status_content_format(status), status.emojis) = render partial: 'admin/shared/status_attachments', locals: { status: status.proper } - else diff --git a/config/locales/en.yml b/config/locales/en.yml index 025ad1ea08aa32..e6604e9284a031 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1909,6 +1909,9 @@ en: other: "%{count} videos" boosted_from_html: Boosted from %{acct_link} content_warning: 'Content warning: %{warning}' + content_warnings: + hide: Hide post + show: Show more default_language: Same as interface language disallowed_hashtags: one: 'contained a disallowed hashtag: %{tags}' From 3f2ee09827503a47b5db765ad06bf4c8cf23088f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 10 Oct 2025 11:06:57 +0200 Subject: [PATCH 136/853] New Crowdin Translations (automated) (#36420) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/br.json | 9 ++++++++- config/locales/br.yml | 4 +++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/app/javascript/mastodon/locales/br.json b/app/javascript/mastodon/locales/br.json index 79eb948ba8abdf..3d87c0fd93d1fb 100644 --- a/app/javascript/mastodon/locales/br.json +++ b/app/javascript/mastodon/locales/br.json @@ -40,6 +40,9 @@ "account.featured_tags.last_status_never": "Embann ebet", "account.follow": "Heuliañ", "account.follow_back": "Heuliañ d'ho tro", + "account.follow_back_short": "Heuliañ d'ho tro", + "account.follow_request": "Reked d'ho heuliañ", + "account.follow_request_cancel": "Nullañ ar reked", "account.follow_request_cancel_short": "Nullañ", "account.followers": "Tud koumanantet", "account.followers.empty": "Den na heul an implijer·ez-mañ c'hoazh.", @@ -212,6 +215,7 @@ "confirmations.missing_alt_text.secondary": "Embann memes tra", "confirmations.missing_alt_text.title": "Ouzhpennañ an eiltestenn?", "confirmations.mute.confirm": "Kuzhat", + "confirmations.quiet_post_quote_info.got_it": "Mat eo", "confirmations.redraft.confirm": "Diverkañ ha skrivañ en-dro", "confirmations.redraft.title": "Diverkañ ha skrivañ an embann en-dro?", "confirmations.remove_from_followers.confirm": "Dilemel an heulier·ez", @@ -246,6 +250,7 @@ "domain_block_modal.block_account_instead": "Stankañ @{name} kentoc'h", "domain_block_modal.title": "Stankañ an domani?", "domain_pill.server": "Dafariad", + "domain_pill.their_handle": "H·ec'h anaouder:", "domain_pill.username": "Anv-implijer", "domain_pill.whats_in_a_handle": "Petra eo an anaouder?", "domain_pill.your_handle": "Hoc'h anaouder:", @@ -267,6 +272,7 @@ "emoji_button.search_results": "Disoc'hoù an enklask", "emoji_button.symbols": "Arouezioù", "emoji_button.travel": "Beajiñ & Lec'hioù", + "empty_column.account_featured_other.unknown": "N'eo ket bet lakaet netra en a-raok gant ar gont-mañ.", "empty_column.account_suspended": "Kont astalet", "empty_column.account_timeline": "Embannadur ebet amañ!", "empty_column.account_unavailable": "Profil dihegerz", @@ -493,6 +499,7 @@ "notifications.column_settings.admin.sign_up": "Enskrivadurioù nevez :", "notifications.column_settings.alert": "Kemennoù war ar burev", "notifications.column_settings.favourite": "Muiañ-karet:", + "notifications.column_settings.filter_bar.advanced": "Diskouez an holl rummadoù", "notifications.column_settings.follow": "Heulierien nevez:", "notifications.column_settings.follow_request": "Rekedoù heuliañ nevez:", "notifications.column_settings.group": "Strollañ", @@ -518,7 +525,7 @@ "notifications.group": "{count} a gemennoù", "notifications.mark_as_read": "Merkañ an holl kemennoù evel bezañ lennet", "notifications.permission_denied": "Kemennoù war ar burev n'int ket hegerz rak pedadenn aotren ar merdeer a zo bet nullet araok", - "notifications.permission_denied_alert": "Kemennoù wa ar burev na c'hellont ket bezañ lezelet, rak aotre ar merdeer a zo bet nac'het a-raok", + "notifications.permission_denied_alert": "Kemennoù war ar burev na c'hellont ket bezañ lezelet, rak aotre ar merdeer a zo bet nac'het a-raok", "notifications.permission_required": "Kemennoù war ar burev n'int ket hegerz abalamour d'an aotre rekis n'eo ket bet roet.", "notifications.policy.accept": "Asantiñ", "notifications.policy.accept_hint": "Diskouez er c’hemennoù", diff --git a/config/locales/br.yml b/config/locales/br.yml index eef6f11828d5fc..30f4a50fbcedf6 100644 --- a/config/locales/br.yml +++ b/config/locales/br.yml @@ -373,6 +373,7 @@ br: manage_rules: Merañ reolennoù ar servijer title: Diwar-benn appearance: + preamble: Personelaat etrefas web Mastodon. title: Neuz content_retention: danger_zone: Takad dañjer @@ -777,12 +778,13 @@ br: account: Kont account_settings: Arventennoù ar gont aliases: Aliasoù ar gont + appearance: Neuz back: Distreiñ da vMastodon delete: Dilemel ar gont development: Diorren edit_profile: Kemmañ ar profil export: Ezporzhiañ - featured_tags: Gerioù-klik en a-raok + featured_tags: Penngerioù-klik import: Enporzhiañ import_and_export: Enporzhiañ hag ezporzhiañ notifications: Kemennoù dre bostel From 0219b7cad7d9ef800f82cc561571b70da040433f Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 10 Oct 2025 14:26:10 +0200 Subject: [PATCH 137/853] Add `result_count` to `Mastodon-Async-Refresh` header when needed (#36239) --- app/controllers/concerns/async_refreshes_concern.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/controllers/concerns/async_refreshes_concern.rb b/app/controllers/concerns/async_refreshes_concern.rb index 29122e16b5e14e..2d0e9ff4ff4ba5 100644 --- a/app/controllers/concerns/async_refreshes_concern.rb +++ b/app/controllers/concerns/async_refreshes_concern.rb @@ -6,6 +6,9 @@ module AsyncRefreshesConcern def add_async_refresh_header(async_refresh, retry_seconds: 3) return unless async_refresh.running? - response.headers['Mastodon-Async-Refresh'] = "id=\"#{async_refresh.id}\", retry=#{retry_seconds}" + value = "id=\"#{async_refresh.id}\", retry=#{retry_seconds}" + value += ", result_count=#{async_refresh.result_count}" unless async_refresh.result_count.nil? + + response.headers['Mastodon-Async-Refresh'] = value end end From 2575ff5ce2157317f38d9734de5e7d36dbb5933d Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 10 Oct 2025 18:44:33 +0200 Subject: [PATCH 138/853] Fix crowdin download script for glitch-soc stable branches (#3225) --- .github/workflows/crowdin-download-stable.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/crowdin-download-stable.yml b/.github/workflows/crowdin-download-stable.yml index 28890321977479..c9d5f6bbe00650 100644 --- a/.github/workflows/crowdin-download-stable.yml +++ b/.github/workflows/crowdin-download-stable.yml @@ -9,7 +9,7 @@ permissions: jobs: download-translations-stable: runs-on: ubuntu-latest - if: github.repository == 'mastodon/mastodon' + if: github.repository == 'glitch-soc/mastodon' steps: - name: Checkout From bcccfb19dfd8ba5dbbaed097145bae2d4521e974 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 10 Oct 2025 18:52:05 +0200 Subject: [PATCH 139/853] New Crowdin Translations (automated) (#3224) * New Crowdin translations * Fix bogus no.yml * Fix bogus simple_form.no.yml --------- Co-authored-by: GitHub Actions Co-authored-by: Claire --- app/javascript/flavours/glitch/locales/id.json | 1 - app/javascript/flavours/glitch/locales/th.json | 5 +---- config/locales-glitch/simple_form.fr-CA.yml | 2 +- config/locales-glitch/simple_form.fr.yml | 2 +- 4 files changed, 3 insertions(+), 7 deletions(-) diff --git a/app/javascript/flavours/glitch/locales/id.json b/app/javascript/flavours/glitch/locales/id.json index 5fa7577b19efcc..abd39e8b568719 100644 --- a/app/javascript/flavours/glitch/locales/id.json +++ b/app/javascript/flavours/glitch/locales/id.json @@ -45,7 +45,6 @@ "settings.content_warnings_shared_state": "Tampilkan/sembunyikan konten semua salinan sekaligus", "settings.pop_in_right": "Kanan", "settings.preferences": "Preferences", - "settings.prepend_cw_re": "", "settings.status_icons_reply": "Indikator balasan", "settings.status_icons_visibility": "Indikator privasi toot", "settings.swipe_to_change_columns": "Izinkan menggeser untuk mengubah kolom (khusus ponsel)", diff --git a/app/javascript/flavours/glitch/locales/th.json b/app/javascript/flavours/glitch/locales/th.json index 3e572eb8b5fac1..ced2f7cf5b1e04 100644 --- a/app/javascript/flavours/glitch/locales/th.json +++ b/app/javascript/flavours/glitch/locales/th.json @@ -1,8 +1,5 @@ { - "about.fork_disclaimer": ".", - "account.disclaimer_full": ".", - "account.follows": "", - "community.column_settings.allow_local_only": "", + "account.follows": "ติดตาม", "settings.content_warnings": "Content warnings", "settings.preferences": "Preferences" } diff --git a/config/locales-glitch/simple_form.fr-CA.yml b/config/locales-glitch/simple_form.fr-CA.yml index 7518e37f86c14a..f46f2a3b0f66f3 100644 --- a/config/locales-glitch/simple_form.fr-CA.yml +++ b/config/locales-glitch/simple_form.fr-CA.yml @@ -17,7 +17,7 @@ fr-CA: setting_default_content_type_markdown: Markdown setting_default_content_type_plain: Texte brut setting_favourite_modal: Afficher une fenêtre de confirmation avant de mettre en favori un post (s'applique uniquement au mode Glitch) - setting_show_followers_count: Montrez votre nombre d'abonnés + setting_show_followers_count: Montrer votre nombre d'abonné·e·s setting_skin: Thème setting_system_emoji_font: Utiliser la police par défaut du système pour les émojis (s'applique uniquement au mode Glitch) notification_emails: diff --git a/config/locales-glitch/simple_form.fr.yml b/config/locales-glitch/simple_form.fr.yml index 09ce41087b9697..e5e6539e3250f7 100644 --- a/config/locales-glitch/simple_form.fr.yml +++ b/config/locales-glitch/simple_form.fr.yml @@ -17,7 +17,7 @@ fr: setting_default_content_type_markdown: Markdown setting_default_content_type_plain: Texte brut setting_favourite_modal: Demander confirmation avant de mettre un post en favori (s'applique uniquement au mode Glitch) - setting_show_followers_count: Montrez votre nombre d'abonnés + setting_show_followers_count: Montrer votre nombre d'abonné·e·s setting_skin: Thème setting_system_emoji_font: Utiliser la police par défaut du système pour les émojis (s'applique uniquement au mode Glitch) notification_emails: From adc0e151670f3f7d2c8a86f4f61b1d002133a576 Mon Sep 17 00:00:00 2001 From: Emelia Smith Date: Fri, 10 Oct 2025 10:43:48 +0200 Subject: [PATCH 140/853] [Glitch] Add support for displaying link previews for Admin UI Port 81350c7cfb217349d0d73b6250faaf05c054fd08 to glitch-soc Signed-off-by: Claire --- .../flavours/glitch/entrypoints/admin.tsx | 41 ++++++++++++++ .../flavours/glitch/styles/admin.scss | 55 +++++++++++++++++++ 2 files changed, 96 insertions(+) diff --git a/app/javascript/flavours/glitch/entrypoints/admin.tsx b/app/javascript/flavours/glitch/entrypoints/admin.tsx index 2b97ef08f4d545..0c2126e5a89153 100644 --- a/app/javascript/flavours/glitch/entrypoints/admin.tsx +++ b/app/javascript/flavours/glitch/entrypoints/admin.tsx @@ -1,6 +1,7 @@ import { createRoot } from 'react-dom/client'; import Rails from '@rails/ujs'; +import { decode, ValidationError } from 'blurhash'; import ready from 'flavours/glitch/ready'; @@ -362,6 +363,46 @@ ready(() => { document.querySelectorAll('[data-admin-component]').forEach((element) => { void mountReactComponent(element); }); + + document + .querySelectorAll('canvas[data-blurhash]') + .forEach((canvas) => { + const blurhash = canvas.dataset.blurhash; + if (blurhash) { + try { + // decode returns a Uint8ClampedArray not Uint8ClampedArray + const pixels = decode( + blurhash, + 32, + 32, + ) as Uint8ClampedArray; + const ctx = canvas.getContext('2d'); + const imageData = new ImageData(pixels, 32, 32); + + ctx?.putImageData(imageData, 0, 0); + } catch (err) { + if (err instanceof ValidationError) { + // ignore blurhash validation errors + return; + } + + throw err; + } + } + }); + + document + .querySelectorAll('.preview-card') + .forEach((previewCard) => { + const spoilerButton = previewCard.querySelector('.spoiler-button'); + if (!spoilerButton) { + return; + } + + spoilerButton.addEventListener('click', () => { + previewCard.classList.toggle('preview-card--image-visible'); + }); + }); }).catch((reason: unknown) => { throw reason; }); diff --git a/app/javascript/flavours/glitch/styles/admin.scss b/app/javascript/flavours/glitch/styles/admin.scss index 82ea9e8b1e28af..5bf9a5a20651db 100644 --- a/app/javascript/flavours/glitch/styles/admin.scss +++ b/app/javascript/flavours/glitch/styles/admin.scss @@ -1990,6 +1990,61 @@ a.sparkline { display: list-item; } } + + .preview-card { + position: relative; + max-width: 566px; + + .status-card__image { + &--video { + aspect-ratio: 16 / 9; + } + + &--large { + aspect-ratio: 1.91 / 1; + } + + aspect-ratio: 1; + } + + .spoiler-button__overlay__label { + outline: 1px solid var(--media-outline-color); + } + + .hide-button { + // Toggled to appear when the preview-card is unblurred: + display: none; + position: absolute; + top: 5px; + right: 5px; + color: $white; + border: 0; + outline: 1px solid var(--media-outline-color); + background-color: color.change($black, $alpha: 0.45); + backdrop-filter: $backdrop-blur-filter; + padding: 3px 12px; + border-radius: 99px; + font-size: 14px; + font-weight: 700; + line-height: 20px; + + &:hover, + &:focus { + background-color: color.change($black, $alpha: 0.9); + } + } + + &.preview-card--image-visible { + .hide-button { + display: block; + } + + .spoiler-button__overlay, + .status-card__image-preview { + display: none; + } + } + } } .admin { From 5dff3414ceb9a8ce9369acb1592ccd46834c52ea Mon Sep 17 00:00:00 2001 From: Emelia Smith Date: Fri, 10 Oct 2025 10:55:41 +0200 Subject: [PATCH 141/853] [Glitch] Improve display of content warnings in Admin UI Port 8898f120dc1b5ad0d543360541fe99b5c10fa77b to glitch-soc Signed-off-by: Claire --- .../flavours/glitch/styles/admin.scss | 47 +++++++++++++++++-- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/app/javascript/flavours/glitch/styles/admin.scss b/app/javascript/flavours/glitch/styles/admin.scss index 5bf9a5a20651db..fc4e50dfdef861 100644 --- a/app/javascript/flavours/glitch/styles/admin.scss +++ b/app/javascript/flavours/glitch/styles/admin.scss @@ -1967,7 +1967,6 @@ a.sparkline { .status__card { padding: 15px; border-radius: 4px; - background: $ui-base-color; font-size: 15px; line-height: 20px; word-wrap: break-word; @@ -1986,8 +1985,50 @@ a.sparkline { .status__content { padding-top: 0; - summary { - display: list-item; + > details { + summary { + display: block; + box-sizing: border-box; + background: var(--nested-card-background); + color: var(--nested-card-text); + border: var(--nested-card-border); + border-radius: 8px; + padding: 8px 13px; + position: relative; + font-size: 15px; + line-height: 22px; + cursor: pointer; + + &::after { + content: attr(data-show, 'Show more'); + margin-top: 8px; + display: block; + font-size: 15px; + line-height: 20px; + color: $highlight-text-color; + cursor: pointer; + border: 0; + background: transparent; + padding: 0; + text-decoration: none; + font-weight: 500; + } + + &:hover, + &:focus-visible { + &::after { + text-decoration: underline !important; + } + } + } + + &[open] summary { + margin-bottom: 16px; + + &::after { + content: attr(data-hide, 'Hide post'); + } + } } } From ab93e9fc8a6c878bba7d73a31005984a1f10c204 Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 13 Oct 2025 11:13:17 +0200 Subject: [PATCH 142/853] Update dependency `rack` (#36443) --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 38e189a21bbd71..5a88ac2eecccce 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -620,7 +620,7 @@ GEM activesupport (>= 3.0.0) raabro (1.4.0) racc (1.8.1) - rack (3.2.2) + rack (3.2.3) rack-attack (6.7.0) rack (>= 1.0, < 4) rack-cors (3.0.0) From 8b78c033e89c2814cb9955b5d0daffe12c58a70d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 13 Oct 2025 11:25:52 +0200 Subject: [PATCH 143/853] New Crowdin Translations (automated) (#36433) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/da.json | 6 +-- app/javascript/mastodon/locales/de.json | 4 +- app/javascript/mastodon/locales/ku.json | 1 + app/javascript/mastodon/locales/nan.json | 1 + app/javascript/mastodon/locales/sk.json | 3 ++ app/javascript/mastodon/locales/zh-TW.json | 2 +- config/locales/ast.yml | 3 ++ config/locales/be.yml | 10 +++++ config/locales/da.yml | 10 +++++ config/locales/de.yml | 10 +++++ config/locales/el.yml | 10 +++++ config/locales/es-AR.yml | 10 +++++ config/locales/es-MX.yml | 10 +++++ config/locales/es.yml | 10 +++++ config/locales/fi.yml | 10 +++++ config/locales/fo.yml | 7 ++++ config/locales/ga.yml | 10 +++++ config/locales/he.yml | 10 +++++ config/locales/is.yml | 10 +++++ config/locales/nan.yml | 44 ++++++++++++++++++++++ config/locales/nl.yml | 16 ++++++-- config/locales/simple_form.nl.yml | 4 ++ config/locales/simple_form.sq.yml | 4 ++ config/locales/sq.yml | 10 +++++ config/locales/tr.yml | 3 ++ config/locales/vi.yml | 10 +++++ config/locales/zh-CN.yml | 10 +++++ config/locales/zh-TW.yml | 10 +++++ 28 files changed, 239 insertions(+), 9 deletions(-) diff --git a/app/javascript/mastodon/locales/da.json b/app/javascript/mastodon/locales/da.json index 255b41e871aac8..92dd5014db2328 100644 --- a/app/javascript/mastodon/locales/da.json +++ b/app/javascript/mastodon/locales/da.json @@ -172,7 +172,7 @@ "column.domain_blocks": "Blokerede domæner", "column.edit_list": "Redigér liste", "column.favourites": "Favoritter", - "column.firehose": "Live feeds", + "column.firehose": "Aktuelt", "column.follow_requests": "Følgeanmodninger", "column.home": "Hjem", "column.list_members": "Håndtér listemedlemmer", @@ -574,8 +574,8 @@ "navigation_bar.follows_and_followers": "Følges og følgere", "navigation_bar.import_export": "Import og eksport", "navigation_bar.lists": "Lister", - "navigation_bar.live_feed_local": "Live feed (lokalt)", - "navigation_bar.live_feed_public": "Live feed (offentligt)", + "navigation_bar.live_feed_local": "Aktuelt (lokalt)", + "navigation_bar.live_feed_public": "Aktuelt (offentligt)", "navigation_bar.logout": "Log af", "navigation_bar.moderation": "Moderering", "navigation_bar.more": "Mere", diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json index 0cc8b5b2f4cfc2..c1d848ee079a4c 100644 --- a/app/javascript/mastodon/locales/de.json +++ b/app/javascript/mastodon/locales/de.json @@ -257,8 +257,8 @@ "confirmations.revoke_quote.confirm": "Beitrag entfernen", "confirmations.revoke_quote.message": "Diese Aktion kann nicht rückgängig gemacht werden.", "confirmations.revoke_quote.title": "Beitrag entfernen?", - "confirmations.unblock.confirm": "Nicht mehr blockieren", - "confirmations.unblock.title": "{name} nicht mehr blockieren?", + "confirmations.unblock.confirm": "Entsperren", + "confirmations.unblock.title": "{name} entsperren?", "confirmations.unfollow.confirm": "Entfolgen", "confirmations.unfollow.title": "{name} entfolgen?", "confirmations.withdraw_request.confirm": "Anfrage zurückziehen", diff --git a/app/javascript/mastodon/locales/ku.json b/app/javascript/mastodon/locales/ku.json index 092e0f6526a727..cf8d3e2bece325 100644 --- a/app/javascript/mastodon/locales/ku.json +++ b/app/javascript/mastodon/locales/ku.json @@ -27,6 +27,7 @@ "account.direct": "Bi taybetî qale @{name} bike", "account.disable_notifications": "Êdî min agahdar neke gava @{name} diweşîne", "account.edit_profile": "Profîlê serrast bike", + "account.edit_profile_short": "Serrast bike", "account.enable_notifications": "Min agahdar bike gava @{name} diweşîne", "account.endorse": "Taybetiyên li ser profîl", "account.featured.accounts": "Profîl", diff --git a/app/javascript/mastodon/locales/nan.json b/app/javascript/mastodon/locales/nan.json index d2bf7ed8b8e2ce..5d864eeddf1c50 100644 --- a/app/javascript/mastodon/locales/nan.json +++ b/app/javascript/mastodon/locales/nan.json @@ -922,6 +922,7 @@ "status.quotes": "{count, plural, other {# 篇引用ê PO文}}", "status.quotes.empty": "Iáu無lâng引用tsit篇PO文。Nā是有lâng引用,ē佇tsia顯示。.", "status.quotes.local_other_disclaimer": "Hōo作者拒絕引用ê引文bē當顯示。", + "status.quotes.remote_other_disclaimer": "Kan-ta tuì {domain} 來ê引文tsiah保證佇tsia顯示。Hōo作者拒絕ê引文buē顯示。", "status.read_more": "讀詳細", "status.reblog": "轉送", "status.reblog_or_quote": "轉送á是引用", diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json index f3cb42fb9748b3..c11df5d0d2ed58 100644 --- a/app/javascript/mastodon/locales/sk.json +++ b/app/javascript/mastodon/locales/sk.json @@ -243,6 +243,9 @@ "confirmations.redraft.message": "Určite chcete tento príspevok vymazať a prepísať? Prídete o jeho zdieľania a ohviezdičkovania a odpovede na pôvodný príspevok budú odlúčené.", "confirmations.redraft.title": "Vymazať a prepísať príspevok?", "confirmations.remove_from_followers.confirm": "Odstrániť nasledovateľa", + "confirmations.revoke_quote.title": "Vymazať príspevok?", + "confirmations.unblock.confirm": "Odblokovať", + "confirmations.unblock.title": "Odblokovať {name}?", "confirmations.unfollow.confirm": "Zrušiť sledovanie", "content_warning.hide": "Skryť príspevok", "content_warning.show": "Aj tak zobraziť", diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json index f5e285fbebff7f..35e7250f0e3ad2 100644 --- a/app/javascript/mastodon/locales/zh-TW.json +++ b/app/javascript/mastodon/locales/zh-TW.json @@ -42,7 +42,7 @@ "account.follow": "跟隨", "account.follow_back": "跟隨回去", "account.follow_back_short": "跟隨回去", - "account.follow_request": "要求跟隨您", + "account.follow_request": "要求跟隨", "account.follow_request_cancel": "取消跟隨請求", "account.follow_request_cancel_short": "取消", "account.follow_request_short": "跟隨請求", diff --git a/config/locales/ast.yml b/config/locales/ast.yml index 81806695b5e445..e2bca6e8cb8196 100644 --- a/config/locales/ast.yml +++ b/config/locales/ast.yml @@ -326,6 +326,9 @@ ast: all: A tol mundu disabled: A naide users: A los perfiles llocales + feed_access: + modes: + public: Tol mundu registrations: preamble: Controla quién pue crear una cuenta nel sirvidor. title: Rexistros diff --git a/config/locales/be.yml b/config/locales/be.yml index a120dcefb53378..ebbfb8bf6d70f5 100644 --- a/config/locales/be.yml +++ b/config/locales/be.yml @@ -1669,6 +1669,13 @@ be: expires_at: Дзее да uses: Выкарыстанні title: Запрасіць людзей + link_preview: + author_html: Ад %{name} + potentially_sensitive_content: + action: Націсніце, каб паказаць + confirm_visit: Вы ўпэўненыя, што хочаце адкрыць гэту спасылку? + hide_button: Схаваць + label: Патэнцыйна далікатны кантэнт lists: errors: limit: Вы дасягнулі макс. колькасці спісаў @@ -1985,6 +1992,9 @@ be: other: "%{count} відэафайла" boosted_from_html: Пашырыў уліковы запіс %{acct_link} content_warning: 'Папярэджанне аб змесціве: %{warning}' + content_warnings: + hide: Схаваць допіс + show: Паказаць усё роўна default_language: Такая, што і мова інтэрфэйсу disallowed_hashtags: few: 'змяшчае недазволеныя хэштэгі: %{tags}' diff --git a/config/locales/da.yml b/config/locales/da.yml index 377ac4952dfc23..0f8bb88cd3fc7d 100644 --- a/config/locales/da.yml +++ b/config/locales/da.yml @@ -1591,6 +1591,13 @@ da: expires_at: Udløber uses: Benyttelser title: Invitér personer + link_preview: + author_html: Af %{name} + potentially_sensitive_content: + action: Klik for at vise + confirm_visit: Er du sikker på, at du vil åbne dette link? + hide_button: Skjul + label: Potentielt følsomt indhold lists: errors: limit: Maks. listeantal nået @@ -1901,6 +1908,9 @@ da: other: "%{count} videoer" boosted_from_html: Fremhævet fra %{acct_link} content_warning: 'Indholdsadvarsel: %{warning}' + content_warnings: + hide: Skjul indlæg + show: Vis mere default_language: Samme som UI-sproget disallowed_hashtags: one: 'indeholdte et ikke tilladt hashtag: %{tags}' diff --git a/config/locales/de.yml b/config/locales/de.yml index 90b97335db2417..3f16ac94d9bc11 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -1591,6 +1591,13 @@ de: expires_at: Läuft ab uses: Verwendungen title: Einladungen + link_preview: + author_html: Von %{name} + potentially_sensitive_content: + action: Zum Anzeigen anklicken + confirm_visit: Möchtest du diesen Link wirklich öffnen? + hide_button: Ausblenden + label: Inhaltswarnung lists: errors: limit: Du hast die maximale Anzahl an Listen erreicht @@ -1901,6 +1908,9 @@ de: other: "%{count} Videos" boosted_from_html: Geteilt von %{acct_link} content_warning: 'Inhaltswarnung: %{warning}' + content_warnings: + hide: Beitrag ausblenden + show: Beitrag anzeigen default_language: Wie die Sprache des Webinterface disallowed_hashtags: one: 'enthält einen nicht-erlaubten Hashtag: %{tags}' diff --git a/config/locales/el.yml b/config/locales/el.yml index 35f5fe2ff24b25..f5a72625f72404 100644 --- a/config/locales/el.yml +++ b/config/locales/el.yml @@ -1591,6 +1591,13 @@ el: expires_at: Λήγει uses: Χρήσεις title: Προσκάλεσε κόσμο + link_preview: + author_html: Από %{name} + potentially_sensitive_content: + action: Κάνε κλικ για εμφάνιση + confirm_visit: Σίγουρα θες να ανοίξεις αυτόν τον σύνδεσμο; + hide_button: Απόκρυψη + label: Δυνητικά ευαίσθητο περιεχόμενο lists: errors: limit: Έχεις φτάσει το μέγιστο αριθμό λιστών @@ -1901,6 +1908,9 @@ el: other: "%{count} βίντεο" boosted_from_html: Ενισχύθηκε από %{acct_link} content_warning: 'Προειδοποίηση περιεχομένου: %{warning}' + content_warnings: + hide: Απόκρυψη ανάρτησης + show: Εμφάνιση περισσότερων default_language: Ίδια με γλώσσα διεπαφής disallowed_hashtags: one: 'περιέχει μη επιτρεπτή ετικέτα: %{tags}' diff --git a/config/locales/es-AR.yml b/config/locales/es-AR.yml index 8b58313c035090..feded782ba2cc3 100644 --- a/config/locales/es-AR.yml +++ b/config/locales/es-AR.yml @@ -1591,6 +1591,13 @@ es-AR: expires_at: Vence uses: Usos title: Invitar a gente + link_preview: + author_html: Por %{name} + potentially_sensitive_content: + action: Clic para mostrar + confirm_visit: "¿Está seguro de que querés abrir este enlace?" + hide_button: Ocultar + label: Contenido potencialmente sensible lists: errors: limit: Alcanzaste el número máximo de listas @@ -1901,6 +1908,9 @@ es-AR: other: "%{count} videos" boosted_from_html: Adherido desde %{acct_link} content_warning: 'Advertencia de contenido: %{warning}' + content_warnings: + hide: Ocultar mensaje + show: Mostrar más default_language: Igual que el idioma de la interface disallowed_hashtags: one: 'contenía una etiqueta no permitida: %{tags}' diff --git a/config/locales/es-MX.yml b/config/locales/es-MX.yml index 1dde5faf22ccf1..0672b21bc476a5 100644 --- a/config/locales/es-MX.yml +++ b/config/locales/es-MX.yml @@ -1591,6 +1591,13 @@ es-MX: expires_at: Expira uses: Usos title: Invitar a gente + link_preview: + author_html: Por %{name} + potentially_sensitive_content: + action: Pulsa para mostrar + confirm_visit: "¿Seguro que quieres abrir este enlace?" + hide_button: Ocultar + label: Contenido potencialmente sensible lists: errors: limit: Has alcanzado la cantidad máxima de listas @@ -1901,6 +1908,9 @@ es-MX: other: "%{count} vídeos" boosted_from_html: Impulsado desde %{acct_link} content_warning: 'Alerta de contenido: %{warning}' + content_warnings: + hide: Ocultar publicación + show: Mostrar más default_language: Igual que el idioma de la interfaz disallowed_hashtags: one: 'contenía una etiqueta no permitida: %{tags}' diff --git a/config/locales/es.yml b/config/locales/es.yml index b5c4eef3d136ad..15fd191ea41fef 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -1591,6 +1591,13 @@ es: expires_at: Expira uses: Usos title: Invitar a gente + link_preview: + author_html: Por %{name} + potentially_sensitive_content: + action: Pulsa para mostrar + confirm_visit: "¿Seguro que quieres abrir este enlace?" + hide_button: Ocultar + label: Contenido potencialmente sensible lists: errors: limit: Has alcanzado la cantidad máxima de listas @@ -1901,6 +1908,9 @@ es: other: "%{count} vídeos" boosted_from_html: Impulsado desde %{acct_link} content_warning: 'Alerta de contenido: %{warning}' + content_warnings: + hide: Ocultar publicación + show: Mostrar más default_language: Igual que el idioma de la interfaz disallowed_hashtags: one: 'contenía una etiqueta no permitida: %{tags}' diff --git a/config/locales/fi.yml b/config/locales/fi.yml index eb6b143a91ee20..7b19a0d820db6c 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -1591,6 +1591,13 @@ fi: expires_at: Vanhenee uses: Käyttökertoja title: Kutsu käyttäjiä + link_preview: + author_html: Tehnyt %{name} + potentially_sensitive_content: + action: Näytä napsauttamalla + confirm_visit: Haluatko varmasti avata tämän linkin? + hide_button: Piilota + label: Mahdollisesti arkaluonteista sisältöä lists: errors: limit: Sinulla on enimmäismäärä listoja @@ -1901,6 +1908,9 @@ fi: other: "%{count} videota" boosted_from_html: Tehosti lähteestä %{acct_link} content_warning: 'Sisältövaroitus: %{warning}' + content_warnings: + hide: Piilota julkaisu + show: Näytä lisää default_language: Sama kuin käyttöliittymän kieli disallowed_hashtags: one: 'sisälsi kielletyn aihetunnisteen: %{tags}' diff --git a/config/locales/fo.yml b/config/locales/fo.yml index dcddd668991ee7..22ec7bbf25dd65 100644 --- a/config/locales/fo.yml +++ b/config/locales/fo.yml @@ -1591,6 +1591,13 @@ fo: expires_at: Rennir út uses: Brúk title: Bjóða fólki + link_preview: + author_html: Av %{name} + potentially_sensitive_content: + action: Klikka fyri at vísa + confirm_visit: Er tú vís/ur í, at tú vil lata hetta leinkið upp? + hide_button: Fjal + label: Tilfar, sum møguliga er viðkvæmt lists: errors: limit: Tú hevur rokkið mesta talið av listum diff --git a/config/locales/ga.yml b/config/locales/ga.yml index 5790b4c58cf4f7..901a3a3940a675 100644 --- a/config/locales/ga.yml +++ b/config/locales/ga.yml @@ -1708,6 +1708,13 @@ ga: expires_at: In éag uses: Úsáidí title: Tabhair cuireadh do dhaoine + link_preview: + author_html: Le %{name} + potentially_sensitive_content: + action: Cliceáil chun a thaispeáint + confirm_visit: An bhfuil tú cinnte gur mian leat an nasc seo a oscailt? + hide_button: Folaigh + label: Ábhar a d'fhéadfadh a bheith íogair lists: errors: limit: Tá uaslíon na liostaí sroichte agat @@ -2027,6 +2034,9 @@ ga: two: "%{count} físeáin" boosted_from_html: Molta ó %{acct_link} content_warning: 'Rabhadh ábhair: %{warning}' + content_warnings: + hide: Folaigh an post + show: Taispeáin níos mó default_language: Mar an gcéanna le teanga an chomhéadain disallowed_hashtags: few: 'bhí na Haischlib dícheadaithe: %{tags}' diff --git a/config/locales/he.yml b/config/locales/he.yml index f577d64366eaeb..3ea929f76c930d 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -1669,6 +1669,13 @@ he: expires_at: פג תוקף ב- uses: שימושים title: הזמנת אנשים + link_preview: + author_html: מאת %{name} + potentially_sensitive_content: + action: לחץ להצגה + confirm_visit: האם להמשיך ליעד הקישור? + hide_button: להסתיר + label: תוכן שעלול להיות רגיש lists: errors: limit: הגעת למספר הרשימות המירבי @@ -1985,6 +1992,9 @@ he: two: "%{count} סרטונים" boosted_from_html: הודהד מ-%{acct_link} content_warning: 'אזהרת תוכן: %{warning}' + content_warnings: + hide: להסתיר הודעה + show: הצג עוד default_language: זהה לשפת ממשק disallowed_hashtags: many: 'מכיל את התגיות האסורות: %{tags}' diff --git a/config/locales/is.yml b/config/locales/is.yml index ba9a7680ac47cb..39a2150fb5aaf3 100644 --- a/config/locales/is.yml +++ b/config/locales/is.yml @@ -1595,6 +1595,13 @@ is: expires_at: Rennur út uses: Afnot title: Bjóða fólki + link_preview: + author_html: Frá %{name} + potentially_sensitive_content: + action: Smelltu til að birta + confirm_visit: Ertu viss um að þú viljir opna þennan tengil? + hide_button: Fela + label: Mögulega viðkvæmt efni lists: errors: limit: Þú hefur náð hámarksfjölda lista @@ -1905,6 +1912,9 @@ is: other: "%{count} myndskeið" boosted_from_html: Endurbirt frá %{acct_link} content_warning: 'Aðvörun vegna efnis (CW): %{warning}' + content_warnings: + hide: Fela færslu + show: Sýna meira default_language: Sama og tungumál viðmóts disallowed_hashtags: one: 'innihélt óleyfilegt myllumerki: %{tags}' diff --git a/config/locales/nan.yml b/config/locales/nan.yml index 5dbbcdac028c55..74d4fd813feb76 100644 --- a/config/locales/nan.yml +++ b/config/locales/nan.yml @@ -834,6 +834,10 @@ nan: all: Kàu ta̍k ê lâng disabled: 無kàu tó tsi̍t ê users: Kàu ta̍k位登入ê用者 + feed_access: + modes: + authenticated: Kan-ta hōo登入ê用者 + public: Ta̍k lâng registrations: moderation_recommandation: 佇開放hōo ta̍k ê lâng註冊進前,請確認lí有夠額koh主動反應ê管理團隊! preamble: 控制ē當佇lí ê服侍器註冊ê人。 @@ -992,6 +996,7 @@ nan: notified_on_html: 佇 %{date} 通知ê用者 notify_users: 通知用者 preview: + explanation_html: Tsit封email ē送hōo tī %{date} 進前註冊 ê %{display_count} ê用者。Email ē包括下跤ê文字: send_preview: Kā tāi先看ê內容寄kàu %{email} send_to_all: other: 寄出 %{display_count} 張電子phue @@ -1014,6 +1019,7 @@ nan: confirm_allow_provider: Lí kám確定beh允准所揀ê提供者? confirm_disallow: Lí kám確定無愛允准所揀ê連結? confirm_disallow_provider: Lí kám確定無愛允准所揀ê提供者? + description_html: Tsia是連結,現tsú時lí ê服侍器hōo通見ê用者大量分享ê。tse通幫tsān lí ê用者tshuē著tsit-má世間有siánn tāi誌。直kàu lí允准公開者,連結bē公開展示。lí通允准á是拒絕單ê連結。 disallow: 無愛允准連結 disallow_provider: 無愛允准提供者 no_link_selected: 因為無揀任何連結,所以lóng無改變 @@ -1028,6 +1034,7 @@ nan: pending_review: Teh等審核 preview_card_providers: allowed: Tsit ê提供者ê連結通刊tī趨勢 + description_html: Tsiah ê域名來自定定受lí ê服侍器分享ê連結。連結bē變做公開趨勢,除非連結ê域名受允准。Lí ê允准(á是拒絕)擴展kàu kiánn域名。 rejected: Tsit ê提供者ê連結bē刊tī趨勢 title: 發布者 rejected: 拒絕ê @@ -1038,6 +1045,7 @@ nan: confirm_allow_account: Lí kám確定beh允准所揀ê口座? confirm_disallow: Lí kám確定無愛允准所揀ê狀態? confirm_disallow_account: Lí kám確定無愛允准所揀ê口座? + description_html: Tsiah ê是lí ê服侍器所知ê,tsit-má teh受tsē-tsē分享kap收藏ê PO文。PO文bē公開顯示,除非lí允准作者,而且作者允准in ê口座hőng推薦hōo別lâng。Lí通允准á是拒絕個別PO文。 disallow: 無允准PO文 disallow_account: 無允准作者 no_status_selected: 因為無揀任何趨勢PO文,所以lóng無改變 @@ -1050,6 +1058,42 @@ nan: dashboard: tag_accounts_measure: 無重複用 tag_languages_dimension: Tsia̍p用ê語言 + tag_servers_dimension: 人氣服侍器 + tag_servers_measure: 無kâng ê服侍器 + tag_uses_measure: Lóng總使用 + description_html: Tsiah ê是hashtag,tsit-má佇lí ê服侍器看見ê tsē-tsē PO文中出現。Tse通tsān lí ê用者tshuē著ta̍k家上tsē討論ê內容。除非lí核准,hashtag bē公開顯示。 + listable: 通受建議 + no_tag_selected: 因為無揀任何標簽,所以lóng無改變 + not_listable: Bē當受建議 + not_trendable: Bē刊tī趨勢 + not_usable: Bē當用 + peaked_on_and_decaying: 佇 %{date} 日上烘,tsit-má teh退火 + title: 趨勢ê hashtag + trendable: 通刊tī趨勢 + trending_rank: '趨勢 #%{rank}' + usable: Ē當用 + usage_comparison: Tī kin-á日hōo %{today} ê lâng用,比較tsa-hng有 %{yesterday} ê + used_by_over_week: + other: 頂禮拜hōo %{count} 位用者用 + title: 推薦kap趨勢 + trending: 趨勢 + username_blocks: + add_new: 加新ê + block_registrations: 封鎖註冊 + comparison: + contains: 包含 + equals: 等於 + contains_html: 包含 %{string} + created_msg: 成功加添用者名規則 + delete: Thâi掉 + edit: + title: 編輯使用者號名規則 + matches_exactly_html: 等於 %{string} + new: + create: 建立規則 + title: 創造使用者號名規則 + no_username_block_selected: 因為無揀任何使用者號名規則,所以lóng無改變 + not_permitted: 無允准 scheduled_statuses: too_soon: Tio̍h用未來ê日期。 statuses: diff --git a/config/locales/nl.yml b/config/locales/nl.yml index fad7cf91aa412b..2a814367cf024d 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -850,7 +850,7 @@ nl: users: Aan ingelogde lokale gebruikers feed_access: modes: - authenticated: Alleen geverifieerde gebruikers + authenticated: Alleen ingelogde gebruikers public: Iedereen registrations: moderation_recommandation: Zorg ervoor dat je een adequaat en responsief moderatieteam hebt voordat je registraties voor iedereen openstelt! @@ -911,7 +911,7 @@ nl: status_title: Bericht van @%{name} title: Accountberichten - @%{name} trending: Trending - view_publicly: In het openbaar bekijken + view_publicly: Openbaar bericht bekijken visibility: Zichtbaarheid with_media: Met media strikes: @@ -984,7 +984,7 @@ nl: name: Naam newest: Nieuwste oldest: Oudste - open: In het openbaar bekijken + open: Oorspronkelijk bericht bekijken reset: Opnieuw review: Status beoordelen search: Zoeken @@ -1591,6 +1591,13 @@ nl: expires_at: Verloopt op uses: Aantal keer te gebruiken title: Mensen uitnodigen + link_preview: + author_html: Door %{name} + potentially_sensitive_content: + action: Klik om te tonen + confirm_visit: Ben je zeker dat je deze link wilt openen? + hide_button: Verberg + label: Mogelijk gevoelige inhoud lists: errors: limit: Je hebt het maximum aantal lijsten bereikt @@ -1901,6 +1908,9 @@ nl: other: "%{count} video's" boosted_from_html: Geboost van %{acct_link} content_warning: 'Inhoudswaarschuwing: %{warning}' + content_warnings: + hide: Bericht verbergen + show: Meer tonen default_language: Hetzelfde als de taal van de gebruikersomgeving disallowed_hashtags: one: 'bevatte een niet toegestane hashtag: %{tags}' diff --git a/config/locales/simple_form.nl.yml b/config/locales/simple_form.nl.yml index e6c10a9c22f2bf..22e0f3fa70f433 100644 --- a/config/locales/simple_form.nl.yml +++ b/config/locales/simple_form.nl.yml @@ -283,12 +283,16 @@ nl: content_cache_retention_period: Bewaartermijn voor externe inhoud custom_css: Aangepaste CSS favicon: Favicon + local_live_feed_access: Toegang tot openbare lokale berichten + local_topic_feed_access: Toegang tot overzicht met lokale hashtags en links mascot: Aangepaste mascotte (legacy) media_cache_retention_period: Bewaartermijn mediacache min_age: Vereiste minimumleeftijd peers_api_enabled: Lijst van bekende servers via de API publiceren profile_directory: Gebruikersgids inschakelen registrations_mode: Wie kan zich registreren + remote_live_feed_access: Toegang tot openbare berichten van andere servers + remote_topic_feed_access: Toegang tot overzicht met hashtags en links van andere servers require_invite_text: Opgeven van een reden is verplicht show_domain_blocks: Domeinblokkades tonen show_domain_blocks_rationale: Redenen voor domeinblokkades tonen diff --git a/config/locales/simple_form.sq.yml b/config/locales/simple_form.sq.yml index 15d9e09e29134b..a942a2d0300b5f 100644 --- a/config/locales/simple_form.sq.yml +++ b/config/locales/simple_form.sq.yml @@ -158,6 +158,10 @@ sq: name: Emër publik për rolin, nëse roli është ujdisur të shfaqet si një stemë permissions_as_keys: Përdoruesit me këtë rol do të mund të… position: Role më të lartë vendosin zgjidhje përplasje në disa raste. Disa veprime mund të kryhen vetëm mbi role të një shkalle më të ulët + username_block: + allow_with_approval: Në vend të pengimit aty për aty të regjistrimit, regjistrime me përkim do të duan miratimin tuaj + comparison: Ju lutemi, mbani parasysh Problemin Scunthorpe, kur bllokohen përkime të pjesshme + username: Do të merret si përkim, pavarësisht shkrimit me të mëdha apo të vogla dhe pavarësisht homoglifesh të tilla si "4" për "a", ose "3" për "e" webhook: events: Përzgjidhni akte për dërgim template: Hartoni ngarkesë tuajën JSON, duke përdorur ndërkëmbim ndryshoresh. Lëreni të zbrazët, për JSON-in parazgjedhje. diff --git a/config/locales/sq.yml b/config/locales/sq.yml index 3f1978f7c81b38..5a978ed66684df 100644 --- a/config/locales/sq.yml +++ b/config/locales/sq.yml @@ -1578,6 +1578,13 @@ sq: expires_at: Skadon më uses: Përdorime title: Ftoni njerëz + link_preview: + author_html: Nga %{name} + potentially_sensitive_content: + action: Klikoni për shfaqje + confirm_visit: Jeni i sigurt se doni të hapet kjo lidhje? + hide_button: Fshihe + label: Lëndë potencalisht me spec lists: errors: limit: Keni mbërritur në numrin maksimum të listave @@ -1888,6 +1895,9 @@ sq: other: "%{count} video" boosted_from_html: Përforcuar nga %{acct_link} content_warning: 'Sinjalizim lënde: %{warning}' + content_warnings: + hide: Fshihe postimin + show: Shfaq më tepër default_language: Njësoj me gjuhën e ndërfaqes disallowed_hashtags: one: 'përmbante një hashtag të palejuar: %{tags}' diff --git a/config/locales/tr.yml b/config/locales/tr.yml index 0c470b29d1fb82..f07a66d327e586 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -1901,6 +1901,9 @@ tr: other: "%{count} videolar" boosted_from_html: "%{acct_link} kişisinden yeniden paylaştı" content_warning: 'İçerik uyarısı: %{warning}' + content_warnings: + hide: Gönderiyi gizle + show: Daha fazlasını göster default_language: Arayüz diliyle aynı disallowed_hashtags: one: 'izin verilmeyen bir etiket içeriyordu: %{tags}' diff --git a/config/locales/vi.yml b/config/locales/vi.yml index d460f44468880c..b38035ab071626 100644 --- a/config/locales/vi.yml +++ b/config/locales/vi.yml @@ -1552,6 +1552,13 @@ vi: expires_at: Hết hạn uses: Sử dụng title: Mời bạn bè + link_preview: + author_html: Bởi %{name} + potentially_sensitive_content: + action: Nhấn để xem + confirm_visit: Bạn có chắc muốn mở liên kết này? + hide_button: Ẩn + label: Có khả năng là nội dung nhạy cảm lists: errors: limit: Bạn đã đạt đến số lượng danh sách tối đa @@ -1859,6 +1866,9 @@ vi: other: "%{count} video" boosted_from_html: Đã đăng lại từ %{acct_link} content_warning: 'Cảnh báo nội dung: %{warning}' + content_warnings: + hide: Ẩn tút + show: Mở rộng default_language: Giống giao diện disallowed_hashtags: other: 'chứa các hashtag bị cấm: %{tags}' diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index 724f7287f57044..60ab656e7ddeb5 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -1552,6 +1552,13 @@ zh-CN: expires_at: 失效时间 uses: 已使用次数 title: 邀请用户 + link_preview: + author_html: 来自 %{name} + potentially_sensitive_content: + action: 点击查看 + confirm_visit: 您确定要打开此链接吗? + hide_button: 隐藏 + label: 可能为敏感内容 lists: errors: limit: 你已达到列表数量的上限 @@ -1859,6 +1866,9 @@ zh-CN: other: "%{count} 段视频" boosted_from_html: 转嘟自 %{acct_link} content_warning: 内容警告:%{warning} + content_warnings: + hide: 隐藏嘟文 + show: 显示更多 default_language: 与界面显示语言相同 disallowed_hashtags: other: 包含以下被禁止的话题:%{tags} diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index c5478d8a64b550..0a0c3a1ee5626b 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -1554,6 +1554,13 @@ zh-TW: expires_at: 失效時間 uses: 已使用次數 title: 邀請使用者 + link_preview: + author_html: 來自 %{name} + potentially_sensitive_content: + action: 點擊以顯示 + confirm_visit: 您確定要開啟此連結嗎? + hide_button: 隱藏 + label: 可能為敏感內容 lists: errors: limit: 您所建立之列表數量已達上限 @@ -1861,6 +1868,9 @@ zh-TW: other: "%{count} 段影片" boosted_from_html: 轉嘟自 %{acct_link} content_warning: 內容警告: %{warning} + content_warnings: + hide: 隱藏嘟文 + show: 顯示更多 default_language: 與介面語言相同 disallowed_hashtags: other: 含有不得使用的標籤: %{tags} From 692cfe27fa13d155ccaed929494e5a89a0c50d75 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 Oct 2025 12:01:00 +0200 Subject: [PATCH 144/853] Update dependency opentelemetry-instrumentation-excon to v0.25.2 (#36436) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 5a88ac2eecccce..ee5f481e34a7eb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -537,7 +537,7 @@ GEM opentelemetry-registry (~> 0.1) opentelemetry-instrumentation-concurrent_ruby (0.23.1) opentelemetry-instrumentation-base (~> 0.24) - opentelemetry-instrumentation-excon (0.25.1) + opentelemetry-instrumentation-excon (0.25.2) opentelemetry-instrumentation-base (~> 0.24) opentelemetry-instrumentation-faraday (0.29.1) opentelemetry-instrumentation-base (~> 0.24) From 8d09e4ef235a0767dcecfe9758a6d4ec1b796196 Mon Sep 17 00:00:00 2001 From: Emelia Smith Date: Mon, 13 Oct 2025 14:19:14 +0200 Subject: [PATCH 145/853] Merge commit from fork * Streaming: Ensure disabled users cannot connect to streaming * Streaming: Disconnect when the user is disabled --- app/models/user.rb | 4 ++++ spec/models/user_spec.rb | 9 ++++++--- spec/system/streaming/streaming_spec.rb | 24 ++++++++++++++++++++++++ streaming/index.js | 2 +- 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index 8e0785e7fdd62d..fb6baec5e9315a 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -180,6 +180,10 @@ def valid_invitation? def disable! update!(disabled: true) + + # This terminates all connections for the given account with the streaming + # server: + redis.publish("timeline:system:#{account.id}", Oj.dump(event: :kill)) end def enable! diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index a9ab15a956ed6c..7088266b34eb38 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -382,12 +382,15 @@ let(:current_sign_in_at) { Time.zone.now } - before do + it 'disables user' do + allow(redis).to receive(:publish) + user.disable! - end - it 'disables user' do expect(user).to have_attributes(disabled: true) + + expect(redis) + .to have_received(:publish).with("timeline:system:#{user.account.id}", Oj.dump(event: :kill)).once end end diff --git a/spec/system/streaming/streaming_spec.rb b/spec/system/streaming/streaming_spec.rb index c12bd1b18fed77..7370033890b517 100644 --- a/spec/system/streaming/streaming_spec.rb +++ b/spec/system/streaming/streaming_spec.rb @@ -74,4 +74,28 @@ expect(streaming_client.open?).to be(false) end end + + context 'with a disabled user account' do + before do + user.disable! + end + + it 'receives an 401 unauthorized error when trying to connect' do + streaming_client.connect + + expect(streaming_client.status).to eq(401) + expect(streaming_client.open?).to be(false) + end + end + + context 'when the user account is disabled whilst connected' do + it 'terminates the connection for the user' do + streaming_client.connect + + user.disable! + + expect(streaming_client.wait_for(:closed).code).to be(1000) + expect(streaming_client.open?).to be(false) + end + end end diff --git a/streaming/index.js b/streaming/index.js index da8aa657e81b16..84806acd119522 100644 --- a/streaming/index.js +++ b/streaming/index.js @@ -355,7 +355,7 @@ const startServer = async () => { * @returns {Promise} */ const accountFromToken = async (token, req) => { - const result = await pgPool.query('SELECT oauth_access_tokens.id, oauth_access_tokens.resource_owner_id, users.account_id, users.chosen_languages, oauth_access_tokens.scopes FROM oauth_access_tokens INNER JOIN users ON oauth_access_tokens.resource_owner_id = users.id WHERE oauth_access_tokens.token = $1 AND oauth_access_tokens.revoked_at IS NULL LIMIT 1', [token]); + const result = await pgPool.query('SELECT oauth_access_tokens.id, oauth_access_tokens.resource_owner_id, users.account_id, users.chosen_languages, oauth_access_tokens.scopes FROM oauth_access_tokens INNER JOIN users ON oauth_access_tokens.resource_owner_id = users.id WHERE oauth_access_tokens.token = $1 AND oauth_access_tokens.revoked_at IS NULL AND users.disabled IS FALSE LIMIT 1', [token]); if (result.rows.length === 0) { throw new AuthenticationError('Invalid access token'); From 24dcb18013dfc94d751e002a0a3fe047a7eb4270 Mon Sep 17 00:00:00 2001 From: Emelia Smith Date: Mon, 13 Oct 2025 14:20:23 +0200 Subject: [PATCH 146/853] Merge commit from fork * Ensure tootctl revokes sessions, access tokens and web push subscriptions * Fix test coverage --- app/models/user.rb | 13 +++++++++---- lib/mastodon/cli/accounts.rb | 7 +++++-- spec/lib/mastodon/cli/accounts_spec.rb | 13 +++++++++++-- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index fb6baec5e9315a..ccd96bdc92aaa9 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -361,17 +361,22 @@ def revoke_access! end def reset_password! + # First, change password to something random, this revokes sessions and on-going access: + change_password!(SecureRandom.hex) + + # Finally, send a reset password prompt to the user + send_reset_password_instructions + end + + def change_password!(new_password) # First, change password to something random and deactivate all sessions transaction do - update(password: SecureRandom.hex) + update(password: new_password) session_activations.destroy_all end # Then, remove all authorized applications and connected push subscriptions revoke_access! - - # Finally, send a reset password prompt to the user - send_reset_password_instructions end protected diff --git a/lib/mastodon/cli/accounts.rb b/lib/mastodon/cli/accounts.rb index 1b33f56055a901..25e966bd8eabc9 100644 --- a/lib/mastodon/cli/accounts.rb +++ b/lib/mastodon/cli/accounts.rb @@ -165,14 +165,17 @@ def modify(username) user.role_id = nil end - password = SecureRandom.hex if options[:reset_password] - user.password = password if options[:reset_password] user.email = options[:email] if options[:email] user.disabled = false if options[:enable] user.disabled = true if options[:disable] user.approved = true if options[:approve] user.disable_two_factor! if options[:disable_2fa] + # Password changes are a little different, as we also need to ensure + # sessions, subscriptions, and access tokens are revoked after changing: + password = SecureRandom.hex if options[:reset_password] + user.change_password!(password) if options[:reset_password] + if user.save user.confirm if options[:confirm] diff --git a/spec/lib/mastodon/cli/accounts_spec.rb b/spec/lib/mastodon/cli/accounts_spec.rb index 111703a18bbe6b..927c6ca8debed8 100644 --- a/spec/lib/mastodon/cli/accounts_spec.rb +++ b/spec/lib/mastodon/cli/accounts_spec.rb @@ -361,11 +361,20 @@ def account_from_options context 'with --reset-password option' do let(:options) { { reset_password: true } } + let(:user) { Fabricate(:user, password: original_password) } + let(:original_password) { 'foobar12345' } + let(:new_password) { 'new_password12345' } + it 'returns a new password for the user' do - allow(SecureRandom).to receive(:hex).and_return('new_password') + allow(SecureRandom).to receive(:hex).and_return(new_password) + allow(Account).to receive(:find_local).and_return(user.account) + allow(user).to receive(:change_password!).and_call_original expect { subject } - .to output_results('new_password') + .to output_results(new_password) + + expect(user).to have_received(:change_password!).with(new_password) + expect(user.reload).to_not be_external_or_valid_password(original_password) end end From 7e98fa9b476fdaed235519f1d527eb956004ba0c Mon Sep 17 00:00:00 2001 From: Emelia Smith Date: Mon, 13 Oct 2025 14:20:57 +0200 Subject: [PATCH 147/853] Merge commit from fork * Require read, read:statuses or read:notifications scope to access streaming APIs * Add additional tests for scope-based channel access We were missing tests in the affirmative for subscribing to the user:notification channel, this adds them --- .../streaming/channel_subscriptions_spec.rb | 86 ++++++++++++++++++- streaming/index.js | 26 ++---- 2 files changed, 92 insertions(+), 20 deletions(-) diff --git a/spec/system/streaming/channel_subscriptions_spec.rb b/spec/system/streaming/channel_subscriptions_spec.rb index 54e125c293dfa0..447ea64f22f35f 100644 --- a/spec/system/streaming/channel_subscriptions_spec.rb +++ b/spec/system/streaming/channel_subscriptions_spec.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true require 'rails_helper' -require 'debug' RSpec.describe 'Channel Subscriptions', :inline_jobs, :streaming do let(:application) { Fabricate(:application, confidential: false) } @@ -15,6 +14,25 @@ streaming_client.close end + context 'when the access token has insufficient scope to read statuses' do + let(:scopes) { 'profile' } + + it 'cannot subscribe to the public:local channel' do + streaming_client.authenticate(access_token.token) + + streaming_client.connect + streaming_client.subscribe('public:local') + + # Receive the error back from the subscription attempt: + message = streaming_client.wait_for_message + + expect(message).to include( + error: 'Access token does not have the required scopes', + status: 401 + ) + end + end + context 'when the access token has read scope' do let(:scopes) { 'read' } @@ -39,11 +57,52 @@ ) ) end + + it 'can subscribing to the user:notifications channel' do + streaming_client.authenticate(access_token.token) + + streaming_client.connect + streaming_client.subscribe('user:notification') + + # We need to perform an action that triggers a notification as there is + # no positive acknowledgement of subscriptions: + first_status = PostStatusService.new.call(user_account, text: 'Test') + ReblogService.new.call(bob_account, first_status) + + message = streaming_client.wait_for_message + + expect(message).to include( + event: 'notification', + stream: ['user:notification'] + ) + end end - context 'when the access token cannot read notifications' do + context 'when the access token has read:statuses scope' do let(:scopes) { 'read:statuses' } + it 'can subscribing to the public:local channel' do + streaming_client.authenticate(access_token.token) + + streaming_client.connect + streaming_client.subscribe('public:local') + + # We need to publish a status as there is no positive acknowledgement of + # subscriptions: + status = PostStatusService.new.call(bob_account, text: 'Hello @alice') + + # And then we want to receive that status: + message = streaming_client.wait_for_message + + expect(message).to include( + stream: be_an(Array).and(contain_exactly('public:local')), + event: 'update', + payload: include( + id: status.id.to_s + ) + ) + end + it 'cannot subscribing to the user:notifications channel' do streaming_client.authenticate(access_token.token) @@ -59,4 +118,27 @@ ) end end + + context 'when the access token has read:notifications scope' do + let(:scopes) { 'read:notifications' } + + it 'can subscribing to the user:notifications channel' do + streaming_client.authenticate(access_token.token) + + streaming_client.connect + streaming_client.subscribe('user:notification') + + # We need to perform an action that triggers a notification as there is + # no positive acknowledgement of subscriptions: + first_status = PostStatusService.new.call(user_account, text: 'Test') + ReblogService.new.call(bob_account, first_status) + + message = streaming_client.wait_for_message + + expect(message).to include( + event: 'notification', + stream: ['user:notification'] + ) + end + end end diff --git a/streaming/index.js b/streaming/index.js index 84806acd119522..e618e3e5301364 100644 --- a/streaming/index.js +++ b/streaming/index.js @@ -78,17 +78,6 @@ const parseJSON = (json, req) => { } }; -const PUBLIC_CHANNELS = [ - 'public', - 'public:media', - 'public:local', - 'public:local:media', - 'public:remote', - 'public:remote:media', - 'hashtag', - 'hashtag:local', -]; - // Used for priming the counters/gauges for the various metrics that are // per-channel const CHANNEL_NAMES = [ @@ -97,7 +86,14 @@ const CHANNEL_NAMES = [ 'user:notification', 'list', 'direct', - ...PUBLIC_CHANNELS + 'public', + 'public:media', + 'public:local', + 'public:local:media', + 'public:remote', + 'public:remote:media', + 'hashtag', + 'hashtag:local', ]; const startServer = async () => { @@ -434,12 +430,6 @@ const startServer = async () => { const checkScopes = (req, logger, channelName) => new Promise((resolve, reject) => { logger.debug(`Checking OAuth scopes for ${channelName}`); - // When accessing public channels, no scopes are needed - if (channelName && PUBLIC_CHANNELS.includes(channelName)) { - resolve(); - return; - } - // The `read` scope has the highest priority, if the token has it // then it can access all streams const requiredScopes = ['read']; From 2971ac9863b91372e68ac152caf6f4dbff511d17 Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 13 Oct 2025 15:35:44 +0200 Subject: [PATCH 148/853] Fix streaming still being authorized for suspended accounts (#36448) --- app/models/concerns/account/suspensions.rb | 4 ++++ spec/system/streaming/streaming_spec.rb | 24 ++++++++++++++++++++++ streaming/index.js | 2 +- 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/app/models/concerns/account/suspensions.rb b/app/models/concerns/account/suspensions.rb index c981fb5a2954cf..4c9ca593ad036d 100644 --- a/app/models/concerns/account/suspensions.rb +++ b/app/models/concerns/account/suspensions.rb @@ -32,6 +32,10 @@ def suspend!(date: Time.now.utc, origin: :local, block_email: true) update!(suspended_at: date, suspension_origin: origin) create_canonical_email_block! if block_email end + + # This terminates all connections for the given account with the streaming + # server: + redis.publish("timeline:system:#{id}", Oj.dump(event: :kill)) if local? end def unsuspend! diff --git a/spec/system/streaming/streaming_spec.rb b/spec/system/streaming/streaming_spec.rb index 7370033890b517..f5d3ba114265ae 100644 --- a/spec/system/streaming/streaming_spec.rb +++ b/spec/system/streaming/streaming_spec.rb @@ -98,4 +98,28 @@ expect(streaming_client.open?).to be(false) end end + + context 'with a suspended user account' do + before do + user.account.suspend! + end + + it 'receives an 401 unauthorized error when trying to connect' do + streaming_client.connect + + expect(streaming_client.status).to eq(401) + expect(streaming_client.open?).to be(false) + end + end + + context 'when the user account is suspended whilst connected' do + it 'terminates the connection for the user' do + streaming_client.connect + + user.account.suspend! + + expect(streaming_client.wait_for(:closed).code).to be(1000) + expect(streaming_client.open?).to be(false) + end + end end diff --git a/streaming/index.js b/streaming/index.js index e618e3e5301364..952b4584ab921d 100644 --- a/streaming/index.js +++ b/streaming/index.js @@ -351,7 +351,7 @@ const startServer = async () => { * @returns {Promise} */ const accountFromToken = async (token, req) => { - const result = await pgPool.query('SELECT oauth_access_tokens.id, oauth_access_tokens.resource_owner_id, users.account_id, users.chosen_languages, oauth_access_tokens.scopes FROM oauth_access_tokens INNER JOIN users ON oauth_access_tokens.resource_owner_id = users.id WHERE oauth_access_tokens.token = $1 AND oauth_access_tokens.revoked_at IS NULL AND users.disabled IS FALSE LIMIT 1', [token]); + const result = await pgPool.query('SELECT oauth_access_tokens.id, oauth_access_tokens.resource_owner_id, users.account_id, users.chosen_languages, oauth_access_tokens.scopes FROM oauth_access_tokens INNER JOIN users ON oauth_access_tokens.resource_owner_id = users.id INNER JOIN accounts ON accounts.id = users.account_id WHERE oauth_access_tokens.token = $1 AND oauth_access_tokens.revoked_at IS NULL AND users.disabled IS FALSE AND accounts.suspended_at IS NULL LIMIT 1', [token]); if (result.rows.length === 0) { throw new AuthenticationError('Invalid access token'); From 254fff93ca3604438a94a453bedfe6f499e2cd66 Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 13 Oct 2025 16:31:12 +0200 Subject: [PATCH 149/853] Bump version to v4.4.6 (#36447) --- CHANGELOG.md | 42 +++++++++++++++++++++++++++++++++++++++++ docker-compose.yml | 6 +++--- lib/mastodon/version.rb | 2 +- 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ad88c51070c5a..249596dc055f5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,48 @@ All notable changes to this project will be documented in this file. +## [4.4.6] - 2025-10-13 + +### Security + +- Update dependencies `rack` and `uri` +- Fix streaming server connection not being closed on user suspension (by @ThisIsMissEm, [GHSA-r2fh-jr9c-9pxh](https://github.com/mastodon/mastodon/security/advisories/GHSA-r2fh-jr9c-9pxh)) +- Fix password change through admin CLI not invalidating existing sessions and access tokens (by @ThisIsMissEm, [GHSA-f3q3-rmf7-9655](https://github.com/mastodon/mastodon/security/advisories/GHSA-f3q3-rmf7-9655)) +- Fix streaming server allowing access to public timelines even without the `read` or `read:statuses` OAuth scopes (by @ThisIsMissEm, [GHSA-7gwh-mw97-qjgp](https://github.com/mastodon/mastodon/security/advisories/GHSA-7gwh-mw97-qjgp)) + +### Added + +- Add support for processing quotes of deleted posts signaled through a `Tombstone` (#36381 by @ClearlyClaire) + +### Fixed + +- Fix quote post state sometimes not being updated through streaming server (#36408 by @ClearlyClaire) +- Fix inconsistent “pending tags” count on admin dashboard (#36404 by @mjankowski) +- Fix JSON payload being potentially mutated when processing interaction policies (#36392 by @ClearlyClaire) +- Fix quotes not being displayed in email notifications (#36379 by @diondiondion) +- Fix redirect to external object when URL is missing or malformed (#36347 by @ClearlyClaire) +- Fix quotes not being displayed in the featured carousel (#36335 by @diondiondion) + +## [4.4.5] - 2025-09-23 + +### Security + +- Update dependencies + +### Added + +- Add support for `has:quote` in search (#36217 by @ClearlyClaire) + +### Changed + +- Change quoted posts from silenced accounts to use a click-through rather than being hidden (#36166 and #36167 by @ClearlyClaire) + +### Fixed + +- Fix processing of out-of-order `Update` as implicit updates (#36190 by @ClearlyClaire) +- Fix getting `Create` and `Update` out of order (#36176 by @ClearlyClaire) +- Fix quotes with Content Warnings but no text being shown without Content Warnings (#36150 by @ClearlyClaire) + ## [4.4.4] - 2025-09-16 ### Security diff --git a/docker-compose.yml b/docker-compose.yml index e0159beae7035b..38c7fd836095af 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -59,7 +59,7 @@ services: web: # You can uncomment the following line if you want to not use the prebuilt image, for example if you have local code changes # build: . - image: ghcr.io/mastodon/mastodon:v4.4.4 + image: ghcr.io/mastodon/mastodon:v4.4.6 restart: always env_file: .env.production command: bundle exec puma -C config/puma.rb @@ -83,7 +83,7 @@ services: # build: # dockerfile: ./streaming/Dockerfile # context: . - image: ghcr.io/mastodon/mastodon-streaming:v4.4.4 + image: ghcr.io/mastodon/mastodon-streaming:v4.4.6 restart: always env_file: .env.production command: node ./streaming/index.js @@ -102,7 +102,7 @@ services: sidekiq: # You can uncomment the following line if you want to not use the prebuilt image, for example if you have local code changes # build: . - image: ghcr.io/mastodon/mastodon:v4.4.4 + image: ghcr.io/mastodon/mastodon:v4.4.6 restart: always env_file: .env.production command: bundle exec sidekiq diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb index 043f22b28e5333..7fca8e8c8211fe 100644 --- a/lib/mastodon/version.rb +++ b/lib/mastodon/version.rb @@ -17,7 +17,7 @@ def patch end def default_prerelease - 'alpha.2' + 'alpha.3' end def prerelease From 33f739da44d81628d24a0c532a2f90953e935d18 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 13 Oct 2025 17:18:01 +0200 Subject: [PATCH 150/853] Fix permalink redirects continuing to work for suspended accounts (#36453) --- app/lib/permalink_redirector.rb | 6 +- spec/lib/permalink_redirector_spec.rb | 88 +++++++++++++++++++-------- 2 files changed, 66 insertions(+), 28 deletions(-) diff --git a/app/lib/permalink_redirector.rb b/app/lib/permalink_redirector.rb index 301a588686ab48..19fb3f401c9b6c 100644 --- a/app/lib/permalink_redirector.rb +++ b/app/lib/permalink_redirector.rb @@ -12,15 +12,15 @@ def object @object ||= begin if at_username_status_request? || statuses_status_request? status = Status.find_by(id: second_segment) - status if status&.distributable? && !status&.local? + status if status&.distributable? && !status&.local? && !status&.account&.suspended? elsif at_username_request? username, domain = first_segment.delete_prefix('@').split('@') domain = nil if TagManager.instance.local_domain?(domain) account = Account.find_remote(username, domain) - account unless account&.local? + account if !account&.local? && !account&.suspended? elsif accounts_request? && record_integer_id_request? account = Account.find_by(id: second_segment) - account unless account&.local? + account if !account&.local? && !account&.suspended? end end end diff --git a/spec/lib/permalink_redirector_spec.rb b/spec/lib/permalink_redirector_spec.rb index 5a544c3d38e136..81fa05449e96d0 100644 --- a/spec/lib/permalink_redirector_spec.rb +++ b/spec/lib/permalink_redirector_spec.rb @@ -10,39 +10,77 @@ Fabricate(:status, account: remote_account, id: 123, url: 'https://example.com/status-123') end - it 'returns path for legacy account links' do - redirector = described_class.new('accounts/2') - expect(redirector.redirect_path).to eq 'https://example.com/@alice' + it 'returns path for deck URLs with query params' do + redirector = described_class.new('/deck/directory?local=true') + expect(redirector.redirect_path).to eq '/directory?local=true' end - it 'returns path for legacy status links' do - redirector = described_class.new('statuses/123') - expect(redirector.redirect_path).to eq 'https://example.com/status-123' - end + context 'when account is not suspended' do + it 'returns path for legacy account links' do + redirector = described_class.new('accounts/2') + expect(redirector.redirect_path).to eq 'https://example.com/@alice' + end - it 'returns path for pretty account links' do - redirector = described_class.new('@alice@example.com') - expect(redirector.redirect_path).to eq 'https://example.com/@alice' - end + it 'returns path for legacy status links' do + redirector = described_class.new('statuses/123') + expect(redirector.redirect_path).to eq 'https://example.com/status-123' + end - it 'returns path for pretty status links' do - redirector = described_class.new('@alice/123') - expect(redirector.redirect_path).to eq 'https://example.com/status-123' - end + it 'returns path for pretty account links' do + redirector = described_class.new('@alice@example.com') + expect(redirector.redirect_path).to eq 'https://example.com/@alice' + end - it 'returns path for legacy status links with a query param' do - redirector = described_class.new('statuses/123?foo=bar') - expect(redirector.redirect_path).to eq 'https://example.com/status-123' - end + it 'returns path for pretty status links' do + redirector = described_class.new('@alice/123') + expect(redirector.redirect_path).to eq 'https://example.com/status-123' + end - it 'returns path for pretty status links with a query param' do - redirector = described_class.new('@alice/123?foo=bar') - expect(redirector.redirect_path).to eq 'https://example.com/status-123' + it 'returns path for legacy status links with a query param' do + redirector = described_class.new('statuses/123?foo=bar') + expect(redirector.redirect_path).to eq 'https://example.com/status-123' + end + + it 'returns path for pretty status links with a query param' do + redirector = described_class.new('@alice/123?foo=bar') + expect(redirector.redirect_path).to eq 'https://example.com/status-123' + end end - it 'returns path for deck URLs with query params' do - redirector = described_class.new('/deck/directory?local=true') - expect(redirector.redirect_path).to eq '/directory?local=true' + context 'when account is suspended' do + before do + remote_account.suspend! + end + + it 'returns nil for legacy account links' do + redirector = described_class.new('accounts/2') + expect(redirector.redirect_path).to be_nil + end + + it 'returns nil for legacy status links' do + redirector = described_class.new('statuses/123') + expect(redirector.redirect_path).to be_nil + end + + it 'returns nil for pretty account links' do + redirector = described_class.new('@alice@example.com') + expect(redirector.redirect_path).to be_nil + end + + it 'returns nil for pretty status links' do + redirector = described_class.new('@alice/123') + expect(redirector.redirect_path).to be_nil + end + + it 'returns nil for legacy status links with a query param' do + redirector = described_class.new('statuses/123?foo=bar') + expect(redirector.redirect_path).to be_nil + end + + it 'returns nil for pretty status links with a query param' do + redirector = described_class.new('@alice/123?foo=bar') + expect(redirector.redirect_path).to be_nil + end end end end From edd7fd98722a0d49ea486aa790a186735e491f35 Mon Sep 17 00:00:00 2001 From: Echo Date: Mon, 13 Oct 2025 17:29:39 +0200 Subject: [PATCH 151/853] Emoji: Picker native rendering (#36454) --- .../mastodon/features/emoji/emoji_picker.tsx | 7 +++++++ app/javascript/mastodon/features/emoji/hooks.ts | 11 +++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/app/javascript/mastodon/features/emoji/emoji_picker.tsx b/app/javascript/mastodon/features/emoji/emoji_picker.tsx index f5300c9fecef6f..6dcfe37ac86fc2 100644 --- a/app/javascript/mastodon/features/emoji/emoji_picker.tsx +++ b/app/javascript/mastodon/features/emoji/emoji_picker.tsx @@ -2,9 +2,12 @@ import type { EmojiProps, PickerProps } from 'emoji-mart'; import EmojiRaw from 'emoji-mart/dist-es/components/emoji/nimble-emoji'; import PickerRaw from 'emoji-mart/dist-es/components/picker/nimble-picker'; +import { isModernEmojiEnabled } from '@/mastodon/utils/environment'; import { assetHost } from 'mastodon/utils/config'; +import { EMOJI_MODE_NATIVE } from './constants'; import EmojiData from './emoji_data.json'; +import { useEmojiAppState } from './hooks'; const backgroundImageFnDefault = () => `${assetHost}/emoji/sheet_15_1.png`; @@ -16,6 +19,7 @@ const Emoji = ({ backgroundImageFn = backgroundImageFnDefault, ...props }: EmojiProps) => { + const { mode } = useEmojiAppState(); return ( @@ -37,6 +42,7 @@ const Picker = ({ backgroundImageFn = backgroundImageFnDefault, ...props }: PickerProps) => { + const { mode } = useEmojiAppState(); return ( ); diff --git a/app/javascript/mastodon/features/emoji/hooks.ts b/app/javascript/mastodon/features/emoji/hooks.ts index b3b27d274a63a5..dbd20d3044fa6e 100644 --- a/app/javascript/mastodon/features/emoji/hooks.ts +++ b/app/javascript/mastodon/features/emoji/hooks.ts @@ -1,6 +1,6 @@ import { useCallback, useLayoutEffect, useMemo, useState } from 'react'; -import { useAppSelector } from '@/mastodon/store'; +import { createAppSelector, useAppSelector } from '@/mastodon/store'; import { isModernEmojiEnabled } from '@/mastodon/utils/environment'; import { toSupportedLocale } from './locale'; @@ -58,13 +58,16 @@ export function useEmojify({ return emojifiedText; } +const modeSelector = createAppSelector( + [(state) => state.meta.get('emoji_style') as string], + (emoji_style) => determineEmojiMode(emoji_style), +); + export function useEmojiAppState(): EmojiAppState { const locale = useAppSelector((state) => toSupportedLocale(state.meta.get('locale') as string), ); - const mode = useAppSelector((state) => - determineEmojiMode(state.meta.get('emoji_style') as string), - ); + const mode = useAppSelector(modeSelector); return { currentLocale: locale, From ed456a6446e9bfcc9c3b1eeeb99360040075aa00 Mon Sep 17 00:00:00 2001 From: Echo Date: Mon, 13 Oct 2025 17:29:39 +0200 Subject: [PATCH 152/853] [Glitch] Emoji: Picker native rendering Port edd7fd98722a0d49ea486aa790a186735e491f35 to glitch-soc Signed-off-by: Claire --- .../flavours/glitch/features/emoji/emoji_picker.tsx | 7 +++++++ .../flavours/glitch/features/emoji/hooks.ts | 11 +++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/app/javascript/flavours/glitch/features/emoji/emoji_picker.tsx b/app/javascript/flavours/glitch/features/emoji/emoji_picker.tsx index 8ae001e148d284..4677d6115f4d0b 100644 --- a/app/javascript/flavours/glitch/features/emoji/emoji_picker.tsx +++ b/app/javascript/flavours/glitch/features/emoji/emoji_picker.tsx @@ -2,9 +2,12 @@ import type { EmojiProps, PickerProps } from 'emoji-mart'; import EmojiRaw from 'emoji-mart/dist-es/components/emoji/nimble-emoji'; import PickerRaw from 'emoji-mart/dist-es/components/picker/nimble-picker'; +import { isModernEmojiEnabled } from '@/flavours/glitch/utils/environment'; import { assetHost } from 'flavours/glitch/utils/config'; +import { EMOJI_MODE_NATIVE } from './constants'; import EmojiData from './emoji_data.json'; +import { useEmojiAppState } from './hooks'; const backgroundImageFnDefault = () => `${assetHost}/emoji/sheet_15_1.png`; @@ -16,6 +19,7 @@ const Emoji = ({ backgroundImageFn = backgroundImageFnDefault, ...props }: EmojiProps) => { + const { mode } = useEmojiAppState(); return ( @@ -37,6 +42,7 @@ const Picker = ({ backgroundImageFn = backgroundImageFnDefault, ...props }: PickerProps) => { + const { mode } = useEmojiAppState(); return ( ); diff --git a/app/javascript/flavours/glitch/features/emoji/hooks.ts b/app/javascript/flavours/glitch/features/emoji/hooks.ts index 47baacef4d5852..067fb1d48b9204 100644 --- a/app/javascript/flavours/glitch/features/emoji/hooks.ts +++ b/app/javascript/flavours/glitch/features/emoji/hooks.ts @@ -1,6 +1,6 @@ import { useCallback, useLayoutEffect, useMemo, useState } from 'react'; -import { useAppSelector } from '@/flavours/glitch/store'; +import { createAppSelector, useAppSelector } from '@/flavours/glitch/store'; import { isModernEmojiEnabled } from '@/flavours/glitch/utils/environment'; import { toSupportedLocale } from './locale'; @@ -58,13 +58,16 @@ export function useEmojify({ return emojifiedText; } +const modeSelector = createAppSelector( + [(state) => state.meta.get('emoji_style') as string], + (emoji_style) => determineEmojiMode(emoji_style), +); + export function useEmojiAppState(): EmojiAppState { const locale = useAppSelector((state) => toSupportedLocale(state.meta.get('locale') as string), ); - const mode = useAppSelector((state) => - determineEmojiMode(state.meta.get('emoji_style') as string), - ); + const mode = useAppSelector(modeSelector); return { currentLocale: locale, From 9a001e7839223ba896b30d8ee71c5e5d720ca8fb Mon Sep 17 00:00:00 2001 From: diondiondion Date: Tue, 14 Oct 2025 10:58:03 +0200 Subject: [PATCH 153/853] Fix videos not being indented properly in thread view (#36459) --- app/javascript/styles/mastodon/components.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 7e677b8ef44352..ee54cd71ad58b6 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -1528,7 +1528,7 @@ & > .status__content, & > .status__action-bar, & > .media-gallery, - & > .video-player, + & > div > .video-player, & > .audio-player, & > .attachment-list, & > .picture-in-picture-placeholder, From 0c64e7f75e1855b5375444aa19b8676ef4b3ca0d Mon Sep 17 00:00:00 2001 From: Echo Date: Tue, 14 Oct 2025 11:36:25 +0200 Subject: [PATCH 154/853] Emoji: Cleanup new code (#36402) --- .storybook/preview.tsx | 8 +- .../components/emoji/emoji.stories.tsx | 56 +++ .../mastodon/components/emoji/html.tsx | 2 +- .../mastodon/components/emoji/index.tsx | 2 +- .../html_block/html_block.stories.tsx | 38 +- .../mastodon/components/html_block/index.tsx | 78 ++-- .../mastodon/features/emoji/emoji_picker.tsx | 2 +- .../mastodon/features/emoji/hooks.ts | 78 ---- .../mastodon/features/emoji/index.ts | 4 +- .../mastodon/features/emoji/mode.ts | 23 +- .../mastodon/features/emoji/render.test.ts | 198 +++++---- .../mastodon/features/emoji/render.ts | 403 +++--------------- .../mastodon/features/emoji/types.ts | 10 +- .../mastodon/features/emoji/utils.test.ts | 80 ++-- .../mastodon/features/emoji/utils.ts | 16 +- app/javascript/testing/api.ts | 23 +- 16 files changed, 359 insertions(+), 662 deletions(-) create mode 100644 app/javascript/mastodon/components/emoji/emoji.stories.tsx delete mode 100644 app/javascript/mastodon/features/emoji/hooks.ts diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index fcba9230308dd7..d66f0fb11a84d3 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -50,9 +50,13 @@ const preview: Preview = { locale: 'en', }, decorators: [ - (Story, { parameters, globals }) => { + (Story, { parameters, globals, args }) => { + // Get the locale from the global toolbar + // and merge it with any parameters or args state. const { locale } = globals as { locale: string }; const { state = {} } = parameters; + const { state: argsState = {} } = args; + const reducer = reducerWithInitialState( { meta: { @@ -60,7 +64,9 @@ const preview: Preview = { }, }, state as Record, + argsState as Record, ); + const store = configureStore({ reducer, middleware(getDefaultMiddleware) { diff --git a/app/javascript/mastodon/components/emoji/emoji.stories.tsx b/app/javascript/mastodon/components/emoji/emoji.stories.tsx new file mode 100644 index 00000000000000..a5e283158d6121 --- /dev/null +++ b/app/javascript/mastodon/components/emoji/emoji.stories.tsx @@ -0,0 +1,56 @@ +import type { ComponentProps } from 'react'; + +import type { Meta, StoryObj } from '@storybook/react-vite'; + +import { importCustomEmojiData } from '@/mastodon/features/emoji/loader'; + +import { Emoji } from './index'; + +type EmojiProps = ComponentProps & { state: string }; + +const meta = { + title: 'Components/Emoji', + component: Emoji, + args: { + code: '🖤', + state: 'auto', + }, + argTypes: { + code: { + name: 'Emoji', + }, + state: { + control: { + type: 'select', + labels: { + auto: 'Auto', + native: 'Native', + twemoji: 'Twemoji', + }, + }, + options: ['auto', 'native', 'twemoji'], + name: 'Emoji Style', + mapping: { + auto: { meta: { emoji_style: 'auto' } }, + native: { meta: { emoji_style: 'native' } }, + twemoji: { meta: { emoji_style: 'twemoji' } }, + }, + }, + }, + render(args) { + void importCustomEmojiData(); + return ; + }, +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = {}; + +export const CustomEmoji: Story = { + args: { + code: ':custom:', + }, +}; diff --git a/app/javascript/mastodon/components/emoji/html.tsx b/app/javascript/mastodon/components/emoji/html.tsx index b462a2ee6f8c2e..628385f64934fc 100644 --- a/app/javascript/mastodon/components/emoji/html.tsx +++ b/app/javascript/mastodon/components/emoji/html.tsx @@ -14,7 +14,7 @@ import { polymorphicForwardRef } from '@/types/polymorphic'; import { AnimateEmojiProvider, CustomEmojiProvider } from './context'; import { textToEmojis } from './index'; -interface EmojiHTMLProps { +export interface EmojiHTMLProps { htmlString: string; extraEmojis?: CustomEmojiMapArg; className?: string; diff --git a/app/javascript/mastodon/components/emoji/index.tsx b/app/javascript/mastodon/components/emoji/index.tsx index e070eb30dd800e..0dff8314ffc5ff 100644 --- a/app/javascript/mastodon/components/emoji/index.tsx +++ b/app/javascript/mastodon/components/emoji/index.tsx @@ -2,7 +2,7 @@ import type { FC } from 'react'; import { useContext, useEffect, useState } from 'react'; import { EMOJI_TYPE_CUSTOM } from '@/mastodon/features/emoji/constants'; -import { useEmojiAppState } from '@/mastodon/features/emoji/hooks'; +import { useEmojiAppState } from '@/mastodon/features/emoji/mode'; import { unicodeHexToUrl } from '@/mastodon/features/emoji/normalize'; import { isStateLoaded, diff --git a/app/javascript/mastodon/components/html_block/html_block.stories.tsx b/app/javascript/mastodon/components/html_block/html_block.stories.tsx index 9c104ba45cb68e..6fb3206df0e8c1 100644 --- a/app/javascript/mastodon/components/html_block/html_block.stories.tsx +++ b/app/javascript/mastodon/components/html_block/html_block.stories.tsx @@ -7,23 +7,49 @@ const meta = { title: 'Components/HTMLBlock', component: HTMLBlock, args: { - contents: - '

Hello, world!

\n

A link

\n

This should be filtered out:

', + htmlString: `

Hello, world!

+

A link

+

This should be filtered out:

+

This also has emoji: 🖤

`, + }, + argTypes: { + extraEmojis: { + table: { + disable: true, + }, + }, + onElement: { + table: { + disable: true, + }, + }, + onAttribute: { + table: { + disable: true, + }, + }, }, render(args) { return ( // Just for visual clarity in Storybook. -
- -
+ /> ); }, + // Force Twemoji to demonstrate emoji rendering. + parameters: { + state: { + meta: { + emoji_style: 'twemoji', + }, + }, + }, } satisfies Meta; export default meta; diff --git a/app/javascript/mastodon/components/html_block/index.tsx b/app/javascript/mastodon/components/html_block/index.tsx index 51baea614d74b1..69fa1d9bf55708 100644 --- a/app/javascript/mastodon/components/html_block/index.tsx +++ b/app/javascript/mastodon/components/html_block/index.tsx @@ -1,50 +1,30 @@ -import type { FC, ReactNode } from 'react'; -import { useMemo } from 'react'; - -import { cleanExtraEmojis } from '@/mastodon/features/emoji/normalize'; -import type { CustomEmojiMapArg } from '@/mastodon/features/emoji/types'; -import { createLimitedCache } from '@/mastodon/utils/cache'; - -import { htmlStringToComponents } from '../../utils/html'; - -// Use a module-level cache to avoid re-rendering the same HTML multiple times. -const cache = createLimitedCache({ maxSize: 1000 }); - -interface HTMLBlockProps { - contents: string; - extraEmojis?: CustomEmojiMapArg; -} - -export const HTMLBlock: FC = ({ - contents: raw, - extraEmojis, -}) => { - const customEmojis = useMemo( - () => cleanExtraEmojis(extraEmojis), - [extraEmojis], - ); - const contents = useMemo(() => { - const key = JSON.stringify({ raw, customEmojis }); - if (cache.has(key)) { - return cache.get(key); - } - - const rendered = htmlStringToComponents(raw, { - onText, - extraArgs: { customEmojis }, +import { useCallback } from 'react'; + +import type { OnElementHandler } from '@/mastodon/utils/html'; +import { polymorphicForwardRef } from '@/types/polymorphic'; + +import type { EmojiHTMLProps } from '../emoji/html'; +import { ModernEmojiHTML } from '../emoji/html'; +import { useElementHandledLink } from '../status/handled_link'; + +export const HTMLBlock = polymorphicForwardRef< + 'div', + EmojiHTMLProps & Parameters[0] +>( + ({ + onElement: onParentElement, + hrefToMention, + hashtagAccountId, + ...props + }) => { + const { onElement: onLinkElement } = useElementHandledLink({ + hrefToMention, + hashtagAccountId, }); - - cache.set(key, rendered); - return rendered; - }, [raw, customEmojis]); - - return contents; -}; - -function onText( - text: string, - // eslint-disable-next-line @typescript-eslint/no-unused-vars -- Doesn't do anything, just showing how typing would work. - { customEmojis }: { customEmojis: CustomEmojiMapArg | null }, -) { - return text; -} + const onElement: OnElementHandler = useCallback( + (...args) => onParentElement?.(...args) ?? onLinkElement(...args), + [onLinkElement, onParentElement], + ); + return ; + }, +); diff --git a/app/javascript/mastodon/features/emoji/emoji_picker.tsx b/app/javascript/mastodon/features/emoji/emoji_picker.tsx index 6dcfe37ac86fc2..f9367c775ccdf8 100644 --- a/app/javascript/mastodon/features/emoji/emoji_picker.tsx +++ b/app/javascript/mastodon/features/emoji/emoji_picker.tsx @@ -7,7 +7,7 @@ import { assetHost } from 'mastodon/utils/config'; import { EMOJI_MODE_NATIVE } from './constants'; import EmojiData from './emoji_data.json'; -import { useEmojiAppState } from './hooks'; +import { useEmojiAppState } from './mode'; const backgroundImageFnDefault = () => `${assetHost}/emoji/sheet_15_1.png`; diff --git a/app/javascript/mastodon/features/emoji/hooks.ts b/app/javascript/mastodon/features/emoji/hooks.ts deleted file mode 100644 index dbd20d3044fa6e..00000000000000 --- a/app/javascript/mastodon/features/emoji/hooks.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { useCallback, useLayoutEffect, useMemo, useState } from 'react'; - -import { createAppSelector, useAppSelector } from '@/mastodon/store'; -import { isModernEmojiEnabled } from '@/mastodon/utils/environment'; - -import { toSupportedLocale } from './locale'; -import { determineEmojiMode } from './mode'; -import { cleanExtraEmojis } from './normalize'; -import { emojifyElement, emojifyText } from './render'; -import type { CustomEmojiMapArg, EmojiAppState } from './types'; -import { stringHasAnyEmoji } from './utils'; - -interface UseEmojifyOptions { - text: string; - extraEmojis?: CustomEmojiMapArg; - deep?: boolean; -} - -export function useEmojify({ - text, - extraEmojis, - deep = true, -}: UseEmojifyOptions) { - const [emojifiedText, setEmojifiedText] = useState(null); - - const appState = useEmojiAppState(); - const extra = useMemo(() => cleanExtraEmojis(extraEmojis), [extraEmojis]); - - const emojify = useCallback( - async (input: string) => { - let result: string | null = null; - if (deep) { - const wrapper = document.createElement('div'); - wrapper.innerHTML = input; - if (await emojifyElement(wrapper, appState, extra ?? {})) { - result = wrapper.innerHTML; - } - } else { - result = await emojifyText(text, appState, extra ?? {}); - } - if (result) { - setEmojifiedText(result); - } else { - setEmojifiedText(input); - } - }, - [appState, deep, extra, text], - ); - useLayoutEffect(() => { - if (isModernEmojiEnabled() && !!text.trim() && stringHasAnyEmoji(text)) { - void emojify(text); - } else { - // If no emoji or we don't want to render, fall back. - setEmojifiedText(text); - } - }, [emojify, text]); - - return emojifiedText; -} - -const modeSelector = createAppSelector( - [(state) => state.meta.get('emoji_style') as string], - (emoji_style) => determineEmojiMode(emoji_style), -); - -export function useEmojiAppState(): EmojiAppState { - const locale = useAppSelector((state) => - toSupportedLocale(state.meta.get('locale') as string), - ); - const mode = useAppSelector(modeSelector); - - return { - currentLocale: locale, - locales: [locale], - mode, - darkTheme: document.body.classList.contains('theme-default'), - }; -} diff --git a/app/javascript/mastodon/features/emoji/index.ts b/app/javascript/mastodon/features/emoji/index.ts index d128da6b5362a1..3701ad67679ccc 100644 --- a/app/javascript/mastodon/features/emoji/index.ts +++ b/app/javascript/mastodon/features/emoji/index.ts @@ -10,6 +10,8 @@ let worker: Worker | null = null; const log = emojiLogger('index'); +const WORKER_TIMEOUT = 1_000; // 1 second + export function initializeEmoji() { log('initializing emojis'); if (!worker && 'Worker' in window) { @@ -29,7 +31,7 @@ export function initializeEmoji() { log('worker is not ready after timeout'); worker = null; void fallbackLoad(); - }, 500); + }, WORKER_TIMEOUT); thisWorker.addEventListener('message', (event: MessageEvent) => { const { data: message } = event; if (message === 'ready') { diff --git a/app/javascript/mastodon/features/emoji/mode.ts b/app/javascript/mastodon/features/emoji/mode.ts index 0f581d8b504b92..afb8a78ebccc62 100644 --- a/app/javascript/mastodon/features/emoji/mode.ts +++ b/app/javascript/mastodon/features/emoji/mode.ts @@ -1,6 +1,7 @@ // Credit to Nolan Lawson for the original implementation. // See: https://github.com/nolanlawson/emoji-picker-element/blob/master/src/picker/utils/testColorEmojiSupported.js +import { createAppSelector, useAppSelector } from '@/mastodon/store'; import { isDevelopment } from '@/mastodon/utils/environment'; import { @@ -8,7 +9,27 @@ import { EMOJI_MODE_NATIVE_WITH_FLAGS, EMOJI_MODE_TWEMOJI, } from './constants'; -import type { EmojiMode } from './types'; +import { toSupportedLocale } from './locale'; +import type { EmojiAppState, EmojiMode } from './types'; + +const modeSelector = createAppSelector( + [(state) => state.meta.get('emoji_style') as string], + (emoji_style) => determineEmojiMode(emoji_style), +); + +export function useEmojiAppState(): EmojiAppState { + const locale = useAppSelector((state) => + toSupportedLocale(state.meta.get('locale') as string), + ); + const mode = useAppSelector(modeSelector); + + return { + currentLocale: locale, + locales: [locale], + mode, + darkTheme: document.body.classList.contains('theme-default'), + }; +} type Feature = Uint8ClampedArray; diff --git a/app/javascript/mastodon/features/emoji/render.test.ts b/app/javascript/mastodon/features/emoji/render.test.ts index 108cf747504048..05dbc388c458d5 100644 --- a/app/javascript/mastodon/features/emoji/render.test.ts +++ b/app/javascript/mastodon/features/emoji/render.test.ts @@ -1,101 +1,12 @@ import { customEmojiFactory, unicodeEmojiFactory } from '@/testing/factories'; -import { EMOJI_MODE_TWEMOJI } from './constants'; import * as db from './database'; +import * as loader from './loader'; import { - emojifyElement, - emojifyText, - testCacheClear, + loadEmojiDataToState, + stringToEmojiState, tokenizeText, } from './render'; -import type { EmojiAppState } from './types'; - -function mockDatabase() { - return { - searchCustomEmojisByShortcodes: vi - .spyOn(db, 'searchCustomEmojisByShortcodes') - .mockResolvedValue([customEmojiFactory()]), - searchEmojisByHexcodes: vi - .spyOn(db, 'searchEmojisByHexcodes') - .mockResolvedValue([ - unicodeEmojiFactory({ - hexcode: '1F60A', - label: 'smiling face with smiling eyes', - unicode: '😊', - }), - unicodeEmojiFactory({ - hexcode: '1F1EA-1F1FA', - label: 'flag-eu', - unicode: '🇪🇺', - }), - ]), - }; -} - -const expectedSmileImage = - '😊'; -const expectedFlagImage = - '🇪🇺'; - -function testAppState(state: Partial = {}) { - return { - locales: ['en'], - mode: EMOJI_MODE_TWEMOJI, - currentLocale: 'en', - darkTheme: false, - ...state, - } satisfies EmojiAppState; -} - -describe('emojifyElement', () => { - function testElement(text = '

Hello 😊🇪🇺!

:custom:

') { - const testElement = document.createElement('div'); - testElement.innerHTML = text; - return testElement; - } - - afterEach(() => { - testCacheClear(); - vi.restoreAllMocks(); - }); - - test('caches element rendering results', async () => { - const { searchCustomEmojisByShortcodes, searchEmojisByHexcodes } = - mockDatabase(); - await emojifyElement(testElement(), testAppState()); - await emojifyElement(testElement(), testAppState()); - await emojifyElement(testElement(), testAppState()); - expect(searchEmojisByHexcodes).toHaveBeenCalledExactlyOnceWith( - ['1F1EA-1F1FA', '1F60A'], - 'en', - ); - expect(searchCustomEmojisByShortcodes).toHaveBeenCalledExactlyOnceWith([ - ':custom:', - ]); - }); - - test('returns null when no emoji are found', async () => { - mockDatabase(); - const actual = await emojifyElement( - testElement('

here is just text :)

'), - testAppState(), - ); - expect(actual).toBeNull(); - }); -}); - -describe('emojifyText', () => { - test('returns original input when no emoji are in string', async () => { - const actual = await emojifyText('nothing here', testAppState()); - expect(actual).toBe('nothing here'); - }); - - test('renders Unicode emojis to twemojis', async () => { - mockDatabase(); - const actual = await emojifyText('Hello 😊🇪🇺!', testAppState()); - expect(actual).toBe(`Hello ${expectedSmileImage}${expectedFlagImage}!`); - }); -}); describe('tokenizeText', () => { test('returns an array of text to be a single token', () => { @@ -162,3 +73,106 @@ describe('tokenizeText', () => { ]); }); }); + +describe('stringToEmojiState', () => { + test('returns unicode emoji state for valid unicode emoji', () => { + expect(stringToEmojiState('😊')).toEqual({ + type: 'unicode', + code: '1F60A', + }); + }); + + test('returns custom emoji state for valid custom emoji', () => { + expect(stringToEmojiState(':smile:')).toEqual({ + type: 'custom', + code: 'smile', + data: undefined, + }); + }); + + test('returns custom emoji state with data when provided', () => { + const customEmoji = { + smile: customEmojiFactory({ + shortcode: 'smile', + url: 'https://example.com/smile.png', + static_url: 'https://example.com/smile_static.png', + }), + }; + expect(stringToEmojiState(':smile:', customEmoji)).toEqual({ + type: 'custom', + code: 'smile', + data: customEmoji.smile, + }); + }); + + test('returns null for invalid emoji strings', () => { + expect(stringToEmojiState('notanemoji')).toBeNull(); + expect(stringToEmojiState(':invalid-emoji:')).toBeNull(); + }); +}); + +describe('loadEmojiDataToState', () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + test('loads unicode data into state', async () => { + const dbCall = vi + .spyOn(db, 'loadEmojiByHexcode') + .mockResolvedValue(unicodeEmojiFactory()); + const unicodeState = { type: 'unicode', code: '1F60A' } as const; + const result = await loadEmojiDataToState(unicodeState, 'en'); + expect(dbCall).toHaveBeenCalledWith('1F60A', 'en'); + expect(result).toEqual({ + type: 'unicode', + code: '1F60A', + data: unicodeEmojiFactory(), + }); + }); + + test('loads custom emoji data into state', async () => { + const dbCall = vi + .spyOn(db, 'loadCustomEmojiByShortcode') + .mockResolvedValueOnce(customEmojiFactory()); + const customState = { type: 'custom', code: 'smile' } as const; + const result = await loadEmojiDataToState(customState, 'en'); + expect(dbCall).toHaveBeenCalledWith('smile'); + expect(result).toEqual({ + type: 'custom', + code: 'smile', + data: customEmojiFactory(), + }); + }); + + test('returns null if unicode emoji not found in database', async () => { + vi.spyOn(db, 'loadEmojiByHexcode').mockResolvedValueOnce(undefined); + const unicodeState = { type: 'unicode', code: '1F60A' } as const; + const result = await loadEmojiDataToState(unicodeState, 'en'); + expect(result).toBeNull(); + }); + + test('returns null if custom emoji not found in database', async () => { + vi.spyOn(db, 'loadCustomEmojiByShortcode').mockResolvedValueOnce(undefined); + const customState = { type: 'custom', code: 'smile' } as const; + const result = await loadEmojiDataToState(customState, 'en'); + expect(result).toBeNull(); + }); + + test('retries loading emoji data once if initial load fails', async () => { + const dbCall = vi + .spyOn(db, 'loadEmojiByHexcode') + .mockRejectedValue(new db.LocaleNotLoadedError('en')); + vi.spyOn(loader, 'importEmojiData').mockResolvedValueOnce(); + const consoleCall = vi + .spyOn(console, 'warn') + .mockImplementationOnce(() => null); + + const unicodeState = { type: 'unicode', code: '1F60A' } as const; + const result = await loadEmojiDataToState(unicodeState, 'en'); + + expect(dbCall).toHaveBeenCalledTimes(2); + expect(loader.importEmojiData).toHaveBeenCalledWith('en'); + expect(consoleCall).toHaveBeenCalled(); + expect(result).toBeNull(); + }); +}); diff --git a/app/javascript/mastodon/features/emoji/render.ts b/app/javascript/mastodon/features/emoji/render.ts index e0c8fd8dce51e0..574d5ef59b2484 100644 --- a/app/javascript/mastodon/features/emoji/render.ts +++ b/app/javascript/mastodon/features/emoji/render.ts @@ -1,7 +1,3 @@ -import { autoPlayGif } from '@/mastodon/initial_state'; -import { createLimitedCache } from '@/mastodon/utils/cache'; -import * as perf from '@/mastodon/utils/performance'; - import { EMOJI_MODE_NATIVE, EMOJI_MODE_NATIVE_WITH_FLAGS, @@ -12,33 +8,69 @@ import { loadCustomEmojiByShortcode, loadEmojiByHexcode, LocaleNotLoadedError, - searchCustomEmojisByShortcodes, - searchEmojisByHexcodes, } from './database'; import { importEmojiData } from './loader'; -import { emojiToUnicodeHex, unicodeHexToUrl } from './normalize'; +import { emojiToUnicodeHex } from './normalize'; import type { - EmojiAppState, EmojiLoadedState, EmojiMode, EmojiState, EmojiStateCustom, - EmojiStateMap, EmojiStateUnicode, ExtraCustomEmojiMap, - LocaleOrCustom, } from './types'; import { anyEmojiRegex, emojiLogger, isCustomEmoji, isUnicodeEmoji, - stringHasAnyEmoji, stringHasUnicodeFlags, } from './utils'; const log = emojiLogger('render'); +type TokenizedText = (string | EmojiState)[]; + +/** + * Tokenizes text into strings and emoji states. + * @param text Text to tokenize. + * @returns Array of strings and emoji states. + */ +export function tokenizeText(text: string): TokenizedText { + if (!text.trim()) { + return [text]; + } + + const tokens = []; + let lastIndex = 0; + for (const match of text.matchAll(anyEmojiRegex())) { + if (match.index > lastIndex) { + tokens.push(text.slice(lastIndex, match.index)); + } + + const code = match[0]; + + if (code.startsWith(':') && code.endsWith(':')) { + // Custom emoji + tokens.push({ + type: EMOJI_TYPE_CUSTOM, + code, + } satisfies EmojiStateCustom); + } else { + // Unicode emoji + tokens.push({ + type: EMOJI_TYPE_UNICODE, + code: code, + } satisfies EmojiStateUnicode); + } + lastIndex = match.index + code.length; + } + if (lastIndex < text.length) { + tokens.push(text.slice(lastIndex)); + } + return tokens; +} + /** * Parses emoji string to extract emoji state. * @param code Hex code or custom shortcode. @@ -132,305 +164,19 @@ export function isStateLoaded(state: EmojiState): state is EmojiLoadedState { } /** - * Emojifies an element. This modifies the element in place, replacing text nodes with emojified versions. + * Determines if the given token should be rendered as an image based on the emoji mode. + * @param state Emoji state to parse. + * @param mode Rendering mode. + * @returns Whether to render as an image. */ -export async function emojifyElement( - element: Element, - appState: EmojiAppState, - extraEmojis: ExtraCustomEmojiMap = {}, -): Promise { - const cacheKey = createCacheKey(element, appState, extraEmojis); - const cached = getCached(cacheKey); - if (cached !== undefined) { - log('Cache hit on %s', element.outerHTML); - if (cached === null) { - return null; - } - element.innerHTML = cached; - return element; - } - if (!stringHasAnyEmoji(element.innerHTML)) { - updateCache(cacheKey, null); - return null; - } - perf.start('emojifyElement()'); - const queue: (HTMLElement | Text)[] = [element]; - while (queue.length > 0) { - const current = queue.shift(); - if ( - !current || - current instanceof HTMLScriptElement || - current instanceof HTMLStyleElement - ) { - continue; - } - - if ( - current.textContent && - (current instanceof Text || !current.hasChildNodes()) - ) { - const renderedContent = await textToElementArray( - current.textContent, - appState, - extraEmojis, - ); - if (renderedContent) { - if (!(current instanceof Text)) { - current.textContent = null; // Clear the text content if it's not a Text node. - } - current.replaceWith(renderedToHTML(renderedContent)); - } - continue; - } - - for (const child of current.childNodes) { - if (child instanceof HTMLElement || child instanceof Text) { - queue.push(child); - } - } - } - updateCache(cacheKey, element.innerHTML); - perf.stop('emojifyElement()'); - return element; -} - -export async function emojifyText( - text: string, - appState: EmojiAppState, - extraEmojis: ExtraCustomEmojiMap = {}, -): Promise { - const cacheKey = createCacheKey(text, appState, extraEmojis); - const cached = getCached(cacheKey); - if (cached !== undefined) { - log('Cache hit on %s', text); - return cached ?? text; - } - if (!stringHasAnyEmoji(text)) { - updateCache(cacheKey, null); - return text; - } - const eleArray = await textToElementArray(text, appState, extraEmojis); - if (!eleArray) { - updateCache(cacheKey, null); - return text; - } - const rendered = renderedToHTML(eleArray, document.createElement('div')); - updateCache(cacheKey, rendered.innerHTML); - return rendered.innerHTML; -} - -// Private functions - -const { - set: updateCache, - get: getCached, - clear: cacheClear, -} = createLimitedCache({ log: log.extend('cache') }); - -function createCacheKey( - input: HTMLElement | string, - appState: EmojiAppState, - extraEmojis: ExtraCustomEmojiMap, -) { - return JSON.stringify([ - input instanceof HTMLElement ? input.outerHTML : input, - appState, - extraEmojis, - ]); -} - -type EmojifiedTextArray = (string | HTMLImageElement)[]; - -async function textToElementArray( - text: string, - appState: EmojiAppState, - extraEmojis: ExtraCustomEmojiMap = {}, -): Promise { - // Exit if no text to convert. - if (!text.trim()) { - return null; - } - - const tokens = tokenizeText(text); - - // If only one token and it's a string, exit early. - if (tokens.length === 1 && typeof tokens[0] === 'string') { - return null; - } - - // Get all emoji from the state map, loading any missing ones. - await loadMissingEmojiIntoCache(tokens, appState, extraEmojis); - - const renderedFragments: EmojifiedTextArray = []; - for (const token of tokens) { - if (typeof token !== 'string' && shouldRenderImage(token, appState.mode)) { - let state: EmojiState | undefined; - if (token.type === EMOJI_TYPE_CUSTOM) { - const extraEmojiData = extraEmojis[token.code]; - if (extraEmojiData) { - state = { - type: EMOJI_TYPE_CUSTOM, - data: extraEmojiData, - code: token.code, - }; - } else { - state = emojiForLocale(token.code, EMOJI_TYPE_CUSTOM); - } - } else { - state = emojiForLocale( - emojiToUnicodeHex(token.code), - appState.currentLocale, - ); - } - - // If the state is valid, create an image element. Otherwise, just append as text. - if (state && typeof state !== 'string' && isStateLoaded(state)) { - const image = stateToImage(state, appState); - renderedFragments.push(image); - continue; - } - } - const text = typeof token === 'string' ? token : token.code; - renderedFragments.push(text); - } - - return renderedFragments; -} - -type TokenizedText = (string | EmojiState)[]; - -export function tokenizeText(text: string): TokenizedText { - if (!text.trim()) { - return [text]; - } - - const tokens = []; - let lastIndex = 0; - for (const match of text.matchAll(anyEmojiRegex())) { - if (match.index > lastIndex) { - tokens.push(text.slice(lastIndex, match.index)); - } - - const code = match[0]; - - if (code.startsWith(':') && code.endsWith(':')) { - // Custom emoji - tokens.push({ - type: EMOJI_TYPE_CUSTOM, - code, - } satisfies EmojiStateCustom); - } else { - // Unicode emoji - tokens.push({ - type: EMOJI_TYPE_UNICODE, - code: code, - } satisfies EmojiStateUnicode); - } - lastIndex = match.index + code.length; - } - if (lastIndex < text.length) { - tokens.push(text.slice(lastIndex)); - } - return tokens; -} - -const localeCacheMap = new Map([ - [ - EMOJI_TYPE_CUSTOM, - createLimitedCache({ log: log.extend('custom') }), - ], -]); - -function cacheForLocale(locale: LocaleOrCustom): EmojiStateMap { - return ( - localeCacheMap.get(locale) ?? - createLimitedCache({ log: log.extend(locale) }) - ); -} - -function emojiForLocale( - code: string, - locale: LocaleOrCustom, -): EmojiState | undefined { - const cache = cacheForLocale(locale); - return cache.get(code); -} - -async function loadMissingEmojiIntoCache( - tokens: TokenizedText, - { mode, currentLocale }: EmojiAppState, - extraEmojis: ExtraCustomEmojiMap, -) { - const missingUnicodeEmoji = new Set(); - const missingCustomEmoji = new Set(); - - // Iterate over tokens and check if they are in the cache already. - for (const token of tokens) { - if (typeof token === 'string') { - continue; // Skip plain strings. - } - - // If this is a custom emoji, check it separately. - if (token.type === EMOJI_TYPE_CUSTOM) { - const code = token.code; - if (code in extraEmojis) { - continue; // We don't care about extra emoji. - } - const emojiState = emojiForLocale(code, EMOJI_TYPE_CUSTOM); - if (!emojiState) { - missingCustomEmoji.add(code); - } - // Otherwise this is a unicode emoji, so check it against all locales. - } else if (shouldRenderImage(token, mode)) { - const code = emojiToUnicodeHex(token.code); - if (missingUnicodeEmoji.has(code)) { - continue; // Already marked as missing. - } - const emojiState = emojiForLocale(code, currentLocale); - if (!emojiState) { - // If it's missing in one locale, we consider it missing for all. - missingUnicodeEmoji.add(code); - } - } - } - - if (missingUnicodeEmoji.size > 0) { - const missingEmojis = Array.from(missingUnicodeEmoji).toSorted(); - const emojis = await searchEmojisByHexcodes(missingEmojis, currentLocale); - const cache = cacheForLocale(currentLocale); - for (const emoji of emojis) { - cache.set(emoji.hexcode, { - type: EMOJI_TYPE_UNICODE, - data: emoji, - code: emoji.hexcode, - }); - } - localeCacheMap.set(currentLocale, cache); - } - - if (missingCustomEmoji.size > 0) { - const missingEmojis = Array.from(missingCustomEmoji).toSorted(); - const emojis = await searchCustomEmojisByShortcodes(missingEmojis); - const cache = cacheForLocale(EMOJI_TYPE_CUSTOM); - for (const emoji of emojis) { - cache.set(emoji.shortcode, { - type: EMOJI_TYPE_CUSTOM, - data: emoji, - code: emoji.shortcode, - }); - } - localeCacheMap.set(EMOJI_TYPE_CUSTOM, cache); - } -} - -export function shouldRenderImage(token: EmojiState, mode: EmojiMode): boolean { - if (token.type === EMOJI_TYPE_UNICODE) { +export function shouldRenderImage(state: EmojiState, mode: EmojiMode): boolean { + if (state.type === EMOJI_TYPE_UNICODE) { // If the mode is native or native with flags for non-flag emoji // we can just append the text node directly. if ( mode === EMOJI_MODE_NATIVE || (mode === EMOJI_MODE_NATIVE_WITH_FLAGS && - !stringHasUnicodeFlags(token.code)) + !stringHasUnicodeFlags(state.code)) ) { return false; } @@ -438,52 +184,3 @@ export function shouldRenderImage(token: EmojiState, mode: EmojiMode): boolean { return true; } - -function stateToImage(state: EmojiLoadedState, appState: EmojiAppState) { - const image = document.createElement('img'); - image.draggable = false; - image.classList.add('emojione'); - - if (state.type === EMOJI_TYPE_UNICODE) { - image.alt = state.data.unicode; - image.title = state.data.label; - image.src = unicodeHexToUrl(state.data.hexcode, appState.darkTheme); - } else { - // Custom emoji - const shortCode = `:${state.data.shortcode}:`; - image.classList.add('custom-emoji'); - image.alt = shortCode; - image.title = shortCode; - image.src = autoPlayGif ? state.data.url : state.data.static_url; - image.dataset.original = state.data.url; - image.dataset.static = state.data.static_url; - } - - return image; -} - -function renderedToHTML(renderedArray: EmojifiedTextArray): DocumentFragment; -function renderedToHTML( - renderedArray: EmojifiedTextArray, - parent: ParentType, -): ParentType; -function renderedToHTML( - renderedArray: EmojifiedTextArray, - parent: ParentNode | null = null, -) { - const fragment = parent ?? document.createDocumentFragment(); - for (const fragmentItem of renderedArray) { - if (typeof fragmentItem === 'string') { - fragment.appendChild(document.createTextNode(fragmentItem)); - } else if (fragmentItem instanceof HTMLImageElement) { - fragment.appendChild(fragmentItem); - } - } - return fragment; -} - -// Testing helpers -export const testCacheClear = () => { - cacheClear(); - localeCacheMap.clear(); -}; diff --git a/app/javascript/mastodon/features/emoji/types.ts b/app/javascript/mastodon/features/emoji/types.ts index b55cefb0a5e218..8cd0902aa4a138 100644 --- a/app/javascript/mastodon/features/emoji/types.ts +++ b/app/javascript/mastodon/features/emoji/types.ts @@ -4,7 +4,6 @@ import type { FlatCompactEmoji, Locale } from 'emojibase'; import type { ApiCustomEmojiJSON } from '@/mastodon/api_types/custom_emoji'; import type { CustomEmoji } from '@/mastodon/models/custom_emoji'; -import type { LimitedCache } from '@/mastodon/utils/cache'; import type { EMOJI_MODE_NATIVE, @@ -48,12 +47,11 @@ export interface EmojiStateCustom { data?: CustomEmojiRenderFields; } export type EmojiState = EmojiStateUnicode | EmojiStateCustom; + export type EmojiLoadedState = | Required | Required; -export type EmojiStateMap = LimitedCache; - export type CustomEmojiMapArg = | ExtraCustomEmojiMap | ImmutableList @@ -64,9 +62,3 @@ export type ExtraCustomEmojiMap = Record< string, Pick >; - -export interface TwemojiBorderInfo { - hexCode: string; - hasLightBorder: boolean; - hasDarkBorder: boolean; -} diff --git a/app/javascript/mastodon/features/emoji/utils.test.ts b/app/javascript/mastodon/features/emoji/utils.test.ts index b9062294c47b14..3844c814a10166 100644 --- a/app/javascript/mastodon/features/emoji/utils.test.ts +++ b/app/javascript/mastodon/features/emoji/utils.test.ts @@ -1,35 +1,31 @@ -import { - stringHasAnyEmoji, - stringHasCustomEmoji, - stringHasUnicodeEmoji, - stringHasUnicodeFlags, -} from './utils'; +import { isCustomEmoji, isUnicodeEmoji, stringHasUnicodeFlags } from './utils'; -describe('stringHasUnicodeEmoji', () => { +describe('isUnicodeEmoji', () => { test.concurrent.for([ - ['only text', false], - ['text with non-emoji symbols ™©', false], - ['text with emoji 😀', true], - ['multiple emojis 😀😃😄', true], - ['emoji with skin tone 👍🏽', true], - ['emoji with ZWJ 👩‍❤️‍👨', true], - ['emoji with variation selector ✊️', true], - ['emoji with keycap 1️⃣', true], - ['emoji with flags 🇺🇸', true], - ['emoji with regional indicators 🇦🇺', true], - ['emoji with gender 👩‍⚕️', true], - ['emoji with family 👨‍👩‍👧‍👦', true], - ['emoji with zero width joiner 👩‍🔬', true], - ['emoji with non-BMP codepoint 🧑‍🚀', true], - ['emoji with combining marks 👨‍👩‍👧‍👦', true], - ['emoji with enclosing keycap #️⃣', true], - ['emoji with no visible glyph \u200D', false], - ] as const)( - 'stringHasUnicodeEmoji has emojis in "%s": %o', - ([text, expected], { expect }) => { - expect(stringHasUnicodeEmoji(text)).toBe(expected); - }, - ); + ['😊', true], + ['🇿🇼', true], + ['🏴‍☠️', true], + ['🏳️‍🌈', true], + ['foo', false], + [':smile:', false], + ['😊foo', false], + ] as const)('isUnicodeEmoji("%s") is %o', ([input, expected], { expect }) => { + expect(isUnicodeEmoji(input)).toBe(expected); + }); +}); + +describe('isCustomEmoji', () => { + test.concurrent.for([ + [':smile:', true], + [':smile_123:', true], + [':SMILE:', true], + ['😊', false], + ['foo', false], + [':smile', false], + ['smile:', false], + ] as const)('isCustomEmoji("%s") is %o', ([input, expected], { expect }) => { + expect(isCustomEmoji(input)).toBe(expected); + }); }); describe('stringHasUnicodeFlags', () => { @@ -51,27 +47,3 @@ describe('stringHasUnicodeFlags', () => { }, ); }); - -describe('stringHasCustomEmoji', () => { - test('string with custom emoji returns true', () => { - expect(stringHasCustomEmoji(':custom: :test:')).toBeTruthy(); - }); - test('string without custom emoji returns false', () => { - expect(stringHasCustomEmoji('🏳️‍🌈 :🏳️‍🌈: text ™')).toBeFalsy(); - }); -}); - -describe('stringHasAnyEmoji', () => { - test('string without any emoji or characters', () => { - expect(stringHasAnyEmoji('normal text. 12356?!')).toBeFalsy(); - }); - test('string with non-emoji characters', () => { - expect(stringHasAnyEmoji('™©')).toBeFalsy(); - }); - test('has unicode emoji', () => { - expect(stringHasAnyEmoji('🏳️‍🌈🔥🇸🇹 👩‍🔬')).toBeTruthy(); - }); - test('has custom emoji', () => { - expect(stringHasAnyEmoji(':test: :custom:')).toBeTruthy(); - }); -}); diff --git a/app/javascript/mastodon/features/emoji/utils.ts b/app/javascript/mastodon/features/emoji/utils.ts index e811565c2717f1..c567afc2cccd5c 100644 --- a/app/javascript/mastodon/features/emoji/utils.ts +++ b/app/javascript/mastodon/features/emoji/utils.ts @@ -6,10 +6,6 @@ export function emojiLogger(segment: string) { return debug(`emojis:${segment}`); } -export function stringHasUnicodeEmoji(input: string): boolean { - return new RegExp(EMOJI_REGEX, supportedFlags()).test(input); -} - export function isUnicodeEmoji(input: string): boolean { return ( input.length > 0 && @@ -34,19 +30,13 @@ export function stringHasUnicodeFlags(input: string): boolean { // Constant as this is supported by all browsers. const CUSTOM_EMOJI_REGEX = /:([a-z0-9_]+):/i; +// Use the polyfill regex or the Unicode property escapes if supported. +const EMOJI_REGEX = emojiRegexPolyfill?.source ?? '\\p{RGI_Emoji}'; export function isCustomEmoji(input: string): boolean { return new RegExp(`^${CUSTOM_EMOJI_REGEX.source}$`, 'i').test(input); } -export function stringHasCustomEmoji(input: string) { - return CUSTOM_EMOJI_REGEX.test(input); -} - -export function stringHasAnyEmoji(input: string) { - return stringHasUnicodeEmoji(input) || stringHasCustomEmoji(input); -} - export function anyEmojiRegex() { return new RegExp( `${EMOJI_REGEX}|${CUSTOM_EMOJI_REGEX.source}`, @@ -64,5 +54,3 @@ function supportedFlags(flags = '') { } return flags; } - -const EMOJI_REGEX = emojiRegexPolyfill?.source ?? '\\p{RGI_Emoji}'; diff --git a/app/javascript/testing/api.ts b/app/javascript/testing/api.ts index 4948d719974ed0..dd45b7e7b6b90a 100644 --- a/app/javascript/testing/api.ts +++ b/app/javascript/testing/api.ts @@ -1,7 +1,10 @@ +import type { CompactEmoji } from 'emojibase'; import { http, HttpResponse } from 'msw'; import { action } from 'storybook/actions'; -import { relationshipsFactory } from './factories'; +import { toSupportedLocale } from '@/mastodon/features/emoji/locale'; + +import { customEmojiFactory, relationshipsFactory } from './factories'; export const mockHandlers = { mute: http.post<{ id: string }>('/api/v1/accounts/:id/mute', ({ params }) => { @@ -40,6 +43,24 @@ export const mockHandlers = { ); }, ), + emojiCustomData: http.get('/api/v1/custom_emojis', () => { + action('fetching custom emoji data')(); + return HttpResponse.json([customEmojiFactory()]); + }), + emojiData: http.get<{ locale: string }>( + '/packs-dev/emoji/:locale.json', + async ({ params }) => { + const locale = toSupportedLocale(params.locale); + action('fetching emoji data')(locale); + const { default: data } = (await import( + `emojibase-data/${locale}/compact.json` + )) as { + default: CompactEmoji[]; + }; + + return HttpResponse.json([data]); + }, + ), }; export const unhandledRequestHandler = ({ url }: Request) => { From 44ecc4b1e325f3c7d01d5f8295a681ec765f244d Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 14 Oct 2025 13:48:51 +0200 Subject: [PATCH 155/853] Fix moderation warning e-mails that include posts (#36462) --- app/views/notification_mailer/_nested_quote.html.haml | 2 +- app/views/notification_mailer/_status.html.haml | 4 ++-- spec/mailers/user_mailer_spec.rb | 4 +++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/views/notification_mailer/_nested_quote.html.haml b/app/views/notification_mailer/_nested_quote.html.haml index e66736399f47a8..dc0921c2ed5c8b 100644 --- a/app/views/notification_mailer/_nested_quote.html.haml +++ b/app/views/notification_mailer/_nested_quote.html.haml @@ -11,7 +11,7 @@ %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' } %tr %td.email-status-content - = render 'status_content', status: status + = render 'notification_mailer/status_content', status: status %p.email-status-footer = link_to l(status.created_at.in_time_zone(time_zone.presence), format: :with_time_zone), web_url("@#{status.account.pretty_acct}/#{status.id}") diff --git a/app/views/notification_mailer/_status.html.haml b/app/views/notification_mailer/_status.html.haml index 064709e7dac75e..c56c7ec72ca1dc 100644 --- a/app/views/notification_mailer/_status.html.haml +++ b/app/views/notification_mailer/_status.html.haml @@ -11,12 +11,12 @@ %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' } %tr %td.email-status-content - = render 'status_content', status: status + = render 'notification_mailer/status_content', status: status - if status.local? && status.quote %table.email-inner-card-table{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' } %tr %td.email-inner-nested-card-td - = render 'nested_quote', status: status.quote.quoted_status, time_zone: time_zone + = render 'notification_mailer/nested_quote', status: status.quote.quoted_status, time_zone: time_zone %p.email-status-footer = link_to l(status.created_at.in_time_zone(time_zone.presence), format: :with_time_zone), web_url("@#{status.account.pretty_acct}/#{status.id}") diff --git a/spec/mailers/user_mailer_spec.rb b/spec/mailers/user_mailer_spec.rb index 88f9d12cac8cd3..82021cd3d02d7f 100644 --- a/spec/mailers/user_mailer_spec.rb +++ b/spec/mailers/user_mailer_spec.rb @@ -141,7 +141,9 @@ end describe '#warning' do - let(:strike) { Fabricate(:account_warning, target_account: receiver.account, text: 'dont worry its just the testsuite', action: 'suspend') } + let(:status) { Fabricate(:status, account: receiver.account) } + let(:quote) { Fabricate(:quote, state: :accepted, status: status) } + let(:strike) { Fabricate(:account_warning, target_account: receiver.account, text: 'dont worry its just the testsuite', action: 'suspend', status_ids: [quote.status_id]) } let(:mail) { described_class.warning(receiver, strike) } it 'renders warning notification' do From f2f711deeb9b4552af8f7352e0b5183d5d7c0748 Mon Sep 17 00:00:00 2001 From: Jonathan de Jong Date: Tue, 14 Oct 2025 14:07:15 +0200 Subject: [PATCH 156/853] Fix allow_referrer_origin typo (#36460) --- config/settings.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/settings.yml b/config/settings.yml index 9dfab1bbe797c8..c6478e57d46204 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -32,7 +32,7 @@ defaults: &defaults require_invite_text: false backups_retention_period: 7 captcha_enabled: false - allow_referer_origin: false + allow_referrer_origin: false development: <<: *defaults From ad858ebe811728c1ba49b202e93cb02b742690bd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 14 Oct 2025 14:17:40 +0200 Subject: [PATCH 157/853] Update dependency strong_migrations to v2.5.1 (#36458) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index ee5f481e34a7eb..1d63e0d955cf2c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -837,7 +837,7 @@ GEM stoplight (5.3.8) zeitwerk stringio (3.1.7) - strong_migrations (2.5.0) + strong_migrations (2.5.1) activerecord (>= 7.1) swd (2.0.3) activesupport (>= 3) From 156f031ed046244b26016df92dbf2c72d3b23c3d Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 14 Oct 2025 14:21:13 +0200 Subject: [PATCH 158/853] Fix WebUI mistakenly allowing to attach quotes when editing (#36464) --- app/javascript/mastodon/actions/compose_typed.ts | 11 +++++++++-- app/javascript/mastodon/locales/en.json | 1 + 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/app/javascript/mastodon/actions/compose_typed.ts b/app/javascript/mastodon/actions/compose_typed.ts index ed925914f9d094..0f9bf5cfb3c427 100644 --- a/app/javascript/mastodon/actions/compose_typed.ts +++ b/app/javascript/mastodon/actions/compose_typed.ts @@ -21,6 +21,10 @@ import { importFetchedStatuses } from './importer'; import { openModal } from './modal'; const messages = defineMessages({ + quoteErrorEdit: { + id: 'quote_error.edit', + defaultMessage: 'Quotes cannot be added when editing a post.', + }, quoteErrorUpload: { id: 'quote_error.upload', defaultMessage: 'Quoting is not allowed with media attachments.', @@ -124,7 +128,9 @@ export const quoteComposeByStatus = createAppThunk( false, ); - if (composeState.get('poll')) { + if (composeState.get('id')) { + dispatch(showAlert({ message: messages.quoteErrorEdit })); + } else if (composeState.get('poll')) { dispatch(showAlert({ message: messages.quoteErrorPoll })); } else if ( composeState.get('is_uploading') || @@ -184,7 +190,8 @@ export const pasteLinkCompose = createDataLoadingThunk( composeState.get('quoted_status_id') || composeState.get('is_submitting') || composeState.get('poll') || - composeState.get('is_uploading') + composeState.get('is_uploading') || + composeState.get('id') ) return; diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index fd9f35629bd140..5ecf32ff6d6822 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -753,6 +753,7 @@ "privacy.unlisted.short": "Quiet public", "privacy_policy.last_updated": "Last updated {date}", "privacy_policy.title": "Privacy Policy", + "quote_error.edit": "Quotes cannot be added when editing a post.", "quote_error.poll": "Quoting is not allowed with polls.", "quote_error.quote": "Only one quote at a time is allowed.", "quote_error.unauthorized": "You are not authorized to quote this post.", From 484225895f211c99c55e196f50e73959eecf8097 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 14 Oct 2025 14:26:21 +0200 Subject: [PATCH 159/853] New Crowdin Translations (automated) (#36457) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/cy.json | 9 ++++++++- app/javascript/mastodon/locales/da.json | 6 +++--- app/javascript/mastodon/locales/es-MX.json | 2 +- app/javascript/mastodon/locales/es.json | 2 +- app/javascript/mastodon/locales/zh-TW.json | 2 +- config/locales/cy.yml | 14 ++++++++++++++ config/locales/simple_form.cy.yml | 6 +++++- config/locales/simple_form.sq.yml | 1 + 8 files changed, 34 insertions(+), 8 deletions(-) diff --git a/app/javascript/mastodon/locales/cy.json b/app/javascript/mastodon/locales/cy.json index 5378330c3a2793..7bd83922d9226d 100644 --- a/app/javascript/mastodon/locales/cy.json +++ b/app/javascript/mastodon/locales/cy.json @@ -257,7 +257,12 @@ "confirmations.revoke_quote.confirm": "Dileu'r postiad", "confirmations.revoke_quote.message": "Does dim modd dadwneud y weithred hon.", "confirmations.revoke_quote.title": "Dileu'r postiad?", + "confirmations.unblock.confirm": "Dadrwystro", + "confirmations.unblock.title": "Dadrwystro {name}?", "confirmations.unfollow.confirm": "Dad-ddilyn", + "confirmations.unfollow.title": "Dad-ddilyn {name}", + "confirmations.withdraw_request.confirm": "Tynnu'r cais yn ôl", + "confirmations.withdraw_request.title": "Tynnu nôl y cais i ddilyn {name}?", "content_warning.hide": "Cuddio'r postiad", "content_warning.show": "Dangos beth bynnag", "content_warning.show_more": "Dangos rhagor", @@ -915,8 +920,10 @@ "status.quote_policy_change": "Newid pwy all ddyfynnu", "status.quote_post_author": "Wedi dyfynnu postiad gan @{name}", "status.quote_private": "Does dim modd dyfynnu postiadau preifat", - "status.quotes": "{count, plural, zero {}one {dyfyniad} two {ddyfyniad} few {dyfyniad} many {dyfyniad} other {dyfyniad}}", + "status.quotes": "{count, plural, zero {dyfyniadau} one {dyfyniad} two {ddyfyniad} few {dyfyniad} many {dyfyniad} other {dyfyniad}}", "status.quotes.empty": "Does neb wedi dyfynnu'r postiad hwn eto. Pan fydd rhywun yn gwneud hynny, bydd yn ymddangos yma.", + "status.quotes.local_other_disclaimer": "Bydd dyfyniadau wedi'u gwrthod gan yr awdur ddim yn cael eu dangos.", + "status.quotes.remote_other_disclaimer": "Dim ond dyfyniadau o {domain} sy'n siŵr o gael eu dangos yma. Bydd dyfyniadau wedi'u gwrthod gan yr awdur ddim yn cael eu dangos.", "status.read_more": "Darllen rhagor", "status.reblog": "Hybu", "status.reblog_or_quote": "Hybu neu ddyfynnu", diff --git a/app/javascript/mastodon/locales/da.json b/app/javascript/mastodon/locales/da.json index 92dd5014db2328..255b41e871aac8 100644 --- a/app/javascript/mastodon/locales/da.json +++ b/app/javascript/mastodon/locales/da.json @@ -172,7 +172,7 @@ "column.domain_blocks": "Blokerede domæner", "column.edit_list": "Redigér liste", "column.favourites": "Favoritter", - "column.firehose": "Aktuelt", + "column.firehose": "Live feeds", "column.follow_requests": "Følgeanmodninger", "column.home": "Hjem", "column.list_members": "Håndtér listemedlemmer", @@ -574,8 +574,8 @@ "navigation_bar.follows_and_followers": "Følges og følgere", "navigation_bar.import_export": "Import og eksport", "navigation_bar.lists": "Lister", - "navigation_bar.live_feed_local": "Aktuelt (lokalt)", - "navigation_bar.live_feed_public": "Aktuelt (offentligt)", + "navigation_bar.live_feed_local": "Live feed (lokalt)", + "navigation_bar.live_feed_public": "Live feed (offentligt)", "navigation_bar.logout": "Log af", "navigation_bar.moderation": "Moderering", "navigation_bar.more": "Mere", diff --git a/app/javascript/mastodon/locales/es-MX.json b/app/javascript/mastodon/locales/es-MX.json index 8c00edc9925de2..59b0b68c88043c 100644 --- a/app/javascript/mastodon/locales/es-MX.json +++ b/app/javascript/mastodon/locales/es-MX.json @@ -923,7 +923,7 @@ "status.quotes": "{count, plural,one {cita} other {citas}}", "status.quotes.empty": "Nadie ha citado esta publicación todavía. Cuando alguien lo haga, aparecerá aquí.", "status.quotes.local_other_disclaimer": "Las citas rechazadas por el autor no se mostrarán.", - "status.quotes.remote_other_disclaimer": "Solo se muestran las citas de {domain}. Las citas rechazadas por el autor no se mostrarán.", + "status.quotes.remote_other_disclaimer": "Solo se garantiza que se muestren las citas de {domain}. Las citas rechazadas por el autor no se mostrarán.", "status.read_more": "Leer más", "status.reblog": "Impulsar", "status.reblog_or_quote": "Impulsar o citar", diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json index fc86d608488172..9985cdea1e4f85 100644 --- a/app/javascript/mastodon/locales/es.json +++ b/app/javascript/mastodon/locales/es.json @@ -923,7 +923,7 @@ "status.quotes": "{count, plural,one {cita} other {citas}}", "status.quotes.empty": "Nadie ha citado esta publicación todavía. Cuando alguien lo haga, aparecerá aquí.", "status.quotes.local_other_disclaimer": "Las citas rechazadas por el autor no se mostrarán.", - "status.quotes.remote_other_disclaimer": "Solo se muestran las citas de {domain}. Las citas rechazadas por el autor no se mostrarán.", + "status.quotes.remote_other_disclaimer": "Solo se garantiza que se muestren las citas de {domain}. Las citas rechazadas por el autor no se mostrarán.", "status.read_more": "Leer más", "status.reblog": "Impulsar", "status.reblog_or_quote": "Impulsar o citar", diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json index 35e7250f0e3ad2..20f94573d7c731 100644 --- a/app/javascript/mastodon/locales/zh-TW.json +++ b/app/javascript/mastodon/locales/zh-TW.json @@ -42,7 +42,7 @@ "account.follow": "跟隨", "account.follow_back": "跟隨回去", "account.follow_back_short": "跟隨回去", - "account.follow_request": "要求跟隨", + "account.follow_request": "跟隨", "account.follow_request_cancel": "取消跟隨請求", "account.follow_request_cancel_short": "取消", "account.follow_request_short": "跟隨請求", diff --git a/config/locales/cy.yml b/config/locales/cy.yml index 7fe0e7dd85f77a..e6dfd21b15cbd7 100644 --- a/config/locales/cy.yml +++ b/config/locales/cy.yml @@ -904,6 +904,10 @@ cy: all: I bawb disabled: I neb users: I ddefnyddwyr lleol wedi'u mewngofnodi + feed_access: + modes: + authenticated: Defnyddwyr dilys yn unig + public: Pawb registrations: moderation_recommandation: Gwnewch yn siŵr bod gennych chi dîm cymedroli digonol ac adweithiol cyn i chi agor cofrestriadau i bawb! preamble: Rheoli pwy all greu cyfrif ar eich gweinydd. @@ -1743,6 +1747,13 @@ cy: expires_at: Yn dod i ben ar uses: Defnyddiau title: Gwahodd pobl + link_preview: + author_html: Yn ôl %{name} + potentially_sensitive_content: + action: Cliciwch i ddangos + confirm_visit: Ydych chi'n siŵr eich bod chi eisiau agor y ddolen hon? + hide_button: Cuddio + label: Cynnwys a allai fod yn sensitif lists: errors: limit: Rydych chi wedi cyrraedd y nifer mwyaf o restrau @@ -2065,6 +2076,9 @@ cy: zero: "%{count} fideo" boosted_from_html: Wedi'i hybu o %{acct_link} content_warning: 'Rhybudd cynnwys: %{warning}' + content_warnings: + hide: Cuddio'r postiad + show: Dangos rhagor default_language: Yr un fath a'r iaith rhyngwyneb disallowed_hashtags: few: 'yn cynnwys yr hashnod gwaharddedig: %{tags}' diff --git a/config/locales/simple_form.cy.yml b/config/locales/simple_form.cy.yml index 354d76a65da487..1c37bcbedbe9a6 100644 --- a/config/locales/simple_form.cy.yml +++ b/config/locales/simple_form.cy.yml @@ -282,17 +282,21 @@ cy: activity_api_enabled: Cyhoeddi ystadegau cyfanredol am weithgarwch defnyddwyr yn yr API app_icon: Eicon ap backups_retention_period: Cyfnod cadw archif defnyddwyr - bootstrap_timeline_accounts: Argymhellwch y cyfrifon hyn i ddefnyddwyr newydd bob amser + bootstrap_timeline_accounts: Argymhellwch y cyfrifon hyn i ddefnyddwyr newydd bob tro closed_registrations_message: Neges bersonol pan nad yw cofrestriadau ar gael content_cache_retention_period: Cyfnod cadw cynnwys o bell custom_css: CSS cyfaddas favicon: Favicon + local_live_feed_access: Mynediad i ffrydiau byw sy'n cynnwys postiadau lleol + local_topic_feed_access: Mynediad i ffrydiau hashnod a dolenni sy'n cynnwys postiadau lleol mascot: Mascot cyfaddas (hen) media_cache_retention_period: Cyfnod cadw storfa cyfryngau min_age: Gofyniad oed ieuengaf peers_api_enabled: Cyhoeddi rhestr o weinyddion a ddarganfuwyd yn yr API profile_directory: Galluogi cyfeiriadur proffil registrations_mode: Pwy all gofrestru + remote_live_feed_access: Mynediad i ffrydiau byw sy'n cynnwys postiadau pell + remote_topic_feed_access: Mynediad i ffrydiau hashnod a dolenni sy'n cynnwys postiadau o bell require_invite_text: Gofyn am reswm i ymuno show_domain_blocks: Dangos blociau parth show_domain_blocks_rationale: Dangos pam y cafodd parthau eu rhwystro diff --git a/config/locales/simple_form.sq.yml b/config/locales/simple_form.sq.yml index a942a2d0300b5f..dee0d44a636ff8 100644 --- a/config/locales/simple_form.sq.yml +++ b/config/locales/simple_form.sq.yml @@ -142,6 +142,7 @@ sq: arbitration_address: Mund të jetë e njëjtë me adresën Fizike më sipër, ose “N/A”, nëse përdoret email. arbitration_website: Mund të jetë një formular web, ose “N/A”, nëse përdoret email. choice_of_law: Qytet, rajon, territor ose shtet, ligjet e brendshme të të cilit do të administrojnë çfarëdo dhe tërë pretendimet. + dmca_address: Për operatorë në ShBA, përdorni adresën e regjistruar te DMCA Designated Agent Directory. Regjistrimi me A P.O. Box bëhet me kërkesë të drejtpërdrejtë, përdorni DMCA Designated Agent Post Office Box Waiver Request që t’i dërgoni email Copyright Office-it dhe t’i përshkruani se jeni një moderator shtëpiak lënde që ka frikë nga hakmarrje apo ndëshkim për veprimet tuaja dhe që ka nevojë të përdor një P.O. Box për heqjen e adresës së shtëpisë tuaj nga sytë e publikut. dmca_email: Mund të jetë i njëjti email i përdorur për “Adresë email për njoftime ligjore” më sipër. domain: Identifikues unik për shërbimin internetor që po ofroni. jurisdiction: Vendosni vendin ku jeton cilido që paguan faturat. Nëse është një shoqëri apo tjetër njësi, vendosni vendin ku është regjistruar, si dhe qytetin, rajonin, territorin apo shtetin përkatës. From 3232eee358134ca468b40ec3b517a15fe69b7fe6 Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 14 Oct 2025 16:04:18 +0200 Subject: [PATCH 160/853] Fix error in logged-out hashtag view when remote posts require log-in (#36467) --- .../features/hashtag_timeline/index.jsx | 32 +++++++++++-------- app/javascript/mastodon/initial_state.ts | 4 +++ app/serializers/initial_state_serializer.rb | 2 ++ 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/app/javascript/mastodon/features/hashtag_timeline/index.jsx b/app/javascript/mastodon/features/hashtag_timeline/index.jsx index ab3c32e6a7bf63..1a7ffa6c23ffeb 100644 --- a/app/javascript/mastodon/features/hashtag_timeline/index.jsx +++ b/app/javascript/mastodon/features/hashtag_timeline/index.jsx @@ -16,15 +16,21 @@ import { expandHashtagTimeline, clearTimeline } from 'mastodon/actions/timelines import Column from 'mastodon/components/column'; import ColumnHeader from 'mastodon/components/column_header'; import { identityContextPropShape, withIdentity } from 'mastodon/identity_context'; +import { remoteTopicFeedAccess, me } from 'mastodon/initial_state'; import StatusListContainer from '../ui/containers/status_list_container'; import { HashtagHeader } from './components/hashtag_header'; import ColumnSettingsContainer from './containers/column_settings_container'; -const mapStateToProps = (state, props) => ({ - hasUnread: state.getIn(['timelines', `hashtag:${props.params.id}${props.params.local ? ':local' : ''}`, 'unread']) > 0, -}); +const mapStateToProps = (state, props) => { + const local = props.params.local || (!me && remoteTopicFeedAccess !== 'public'); + + return ({ + local, + hasUnread: state.getIn(['timelines', `hashtag:${props.params.id}${local ? ':local' : ''}`, 'unread']) > 0, + }); +}; class HashtagTimeline extends PureComponent { disconnects = []; @@ -113,16 +119,16 @@ class HashtagTimeline extends PureComponent { } _unload () { - const { dispatch } = this.props; - const { id, local } = this.props.params; + const { dispatch, local } = this.props; + const { id } = this.props.params; this._unsubscribe(); dispatch(clearTimeline(`hashtag:${id}${local ? ':local' : ''}`)); } _load() { - const { dispatch } = this.props; - const { id, tags, local } = this.props.params; + const { dispatch, local } = this.props; + const { id, tags } = this.props.params; this._subscribe(dispatch, id, tags, local); dispatch(expandHashtagTimeline(id, { tags, local })); @@ -133,8 +139,8 @@ class HashtagTimeline extends PureComponent { } componentDidUpdate (prevProps) { - const { params } = this.props; - const { id, tags, local } = prevProps.params; + const { params, local } = this.props; + const { id, tags } = prevProps.params; if (id !== params.id || !isEqual(tags, params.tags) || !isEqual(local, params.local)) { this._unload(); @@ -151,15 +157,15 @@ class HashtagTimeline extends PureComponent { }; handleLoadMore = maxId => { - const { dispatch, params } = this.props; - const { id, tags, local } = params; + const { dispatch, params, local } = this.props; + const { id, tags } = params; dispatch(expandHashtagTimeline(id, { maxId, tags, local })); }; render () { - const { hasUnread, columnId, multiColumn } = this.props; - const { id, local } = this.props.params; + const { hasUnread, columnId, multiColumn, local } = this.props; + const { id } = this.props.params; const pinned = !!columnId; return ( diff --git a/app/javascript/mastodon/initial_state.ts b/app/javascript/mastodon/initial_state.ts index 2bef1209e8678a..f28d81a10cec41 100644 --- a/app/javascript/mastodon/initial_state.ts +++ b/app/javascript/mastodon/initial_state.ts @@ -34,6 +34,8 @@ interface InitialStateMeta { streaming_api_base_url: string; local_live_feed_access: 'public' | 'authenticated'; remote_live_feed_access: 'public' | 'authenticated'; + local_topic_feed_access: 'public' | 'authenticated'; + remote_topic_feed_access: 'public' | 'authenticated'; title: string; show_trends: boolean; trends_as_landing_page: boolean; @@ -113,6 +115,8 @@ export const singleUserMode = getMeta('single_user_mode'); export const source_url = getMeta('source_url'); export const localLiveFeedAccess = getMeta('local_live_feed_access'); export const remoteLiveFeedAccess = getMeta('remote_live_feed_access'); +export const localTopicFeedAccess = getMeta('local_topic_feed_access'); +export const remoteTopicFeedAccess = getMeta('remote_topic_feed_access'); export const title = getMeta('title'); export const trendsAsLanding = getMeta('trends_as_landing_page'); export const useBlurhash = getMeta('use_blurhash'); diff --git a/app/serializers/initial_state_serializer.rb b/app/serializers/initial_state_serializer.rb index b1905117260503..93c06b7676a613 100644 --- a/app/serializers/initial_state_serializer.rb +++ b/app/serializers/initial_state_serializer.rb @@ -118,6 +118,8 @@ def default_meta_store terms_of_service_enabled: TermsOfService.current.present?, local_live_feed_access: Setting.local_live_feed_access, remote_live_feed_access: Setting.remote_live_feed_access, + local_topic_feed_access: Setting.local_topic_feed_access, + remote_topic_feed_access: Setting.remote_topic_feed_access, } end From fd516347cb453c4354531fbb3cf973268e99a18d Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 14 Oct 2025 17:15:38 +0200 Subject: [PATCH 161/853] Fix deletion of posts quoting soft-deleted local post (#36461) --- app/services/revoke_quote_service.rb | 5 +++++ spec/services/remove_status_service_spec.rb | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/app/services/revoke_quote_service.rb b/app/services/revoke_quote_service.rb index 1dd37d0555057a..346fba89709ed8 100644 --- a/app/services/revoke_quote_service.rb +++ b/app/services/revoke_quote_service.rb @@ -21,6 +21,11 @@ def distribute_update! end def distribute_stamp_deletion! + # It is possible the quoted status has been soft-deleted. + # In this case, `signed_activity_json` would fail, but we can just ignore + # that, as we have already federated deletion. + return if @quote.quoted_status.nil? + ActivityPub::DeliveryWorker.push_bulk(inboxes, limit: 1_000) do |inbox_url| [signed_activity_json, @account.id, inbox_url] end diff --git a/spec/services/remove_status_service_spec.rb b/spec/services/remove_status_service_spec.rb index f2b46f05b002ba..3cb2eceec5966a 100644 --- a/spec/services/remove_status_service_spec.rb +++ b/spec/services/remove_status_service_spec.rb @@ -129,4 +129,20 @@ def undo_activity_for(status) ) ) end + + context 'when removed status is a quote of a local user', inline_jobs: false do + let(:original_status) { Fabricate(:status, account: alice) } + let(:status) { Fabricate(:status, account: jeff) } + + before do + bill.follow!(jeff) + Fabricate(:quote, status: status, quoted_status: original_status, state: :accepted) + original_status.discard + end + + it 'sends deletion without crashing' do + expect { subject.call(status.reload) } + .to enqueue_sidekiq_job(ActivityPub::DeliveryWorker).with(/Delete/, jeff.id, bill.inbox_url) + end + end end From 50743cc35be19deae9356bd21f1143e3a9b4fbb8 Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 14 Oct 2025 17:15:45 +0200 Subject: [PATCH 162/853] Fix forwarder being called with `nil` status when quote post is soft-deleted (#36463) --- app/lib/activitypub/activity/delete.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/lib/activitypub/activity/delete.rb b/app/lib/activitypub/activity/delete.rb index ce36cfe763f510..3e77f9b95564e3 100644 --- a/app/lib/activitypub/activity/delete.rb +++ b/app/lib/activitypub/activity/delete.rb @@ -59,9 +59,11 @@ def revoke_quote @quote = Quote.find_by(approval_uri: object_uri, quoted_account: @account) return if @quote.nil? - ActivityPub::Forwarder.new(@account, @json, @quote.status).forward! + ActivityPub::Forwarder.new(@account, @json, @quote.status).forward! if @quote.status.present? + @quote.reject! - DistributionWorker.perform_async(@quote.status_id, { 'update' => true }) + + DistributionWorker.perform_async(@quote.status_id, { 'update' => true }) if @quote.status.present? end def forwarder From a7f207604a310ad2a8ffcfda5ce627a8cd92a502 Mon Sep 17 00:00:00 2001 From: diondiondion Date: Tue, 14 Oct 2025 10:58:03 +0200 Subject: [PATCH 163/853] [Glitch] Fix videos not being indented properly in thread view Port 9a001e7839223ba896b30d8ee71c5e5d720ca8fb to glitch-soc Signed-off-by: Claire --- app/javascript/flavours/glitch/styles/components.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/flavours/glitch/styles/components.scss b/app/javascript/flavours/glitch/styles/components.scss index 0457f7515e61e3..ef800908506b69 100644 --- a/app/javascript/flavours/glitch/styles/components.scss +++ b/app/javascript/flavours/glitch/styles/components.scss @@ -1587,7 +1587,7 @@ & > .status__content, & > .status__action-bar, & > .media-gallery, - & > .video-player, + & > div > .video-player, & > .audio-player, & > .attachment-list, & > .picture-in-picture-placeholder, From 8d1e67b6b242e8843378564adcbe5dc932c62f67 Mon Sep 17 00:00:00 2001 From: Echo Date: Tue, 14 Oct 2025 11:36:25 +0200 Subject: [PATCH 164/853] [Glitch] Emoji: Cleanup new code Port 0c64e7f75e1855b5375444aa19b8676ef4b3ca0d to glitch-soc Signed-off-by: Claire --- .../glitch/components/emoji/emoji.stories.tsx | 56 +++ .../flavours/glitch/components/emoji/html.tsx | 2 +- .../glitch/components/emoji/index.tsx | 2 +- .../html_block/html_block.stories.tsx | 38 +- .../glitch/components/html_block/index.tsx | 78 ++-- .../glitch/features/emoji/emoji_picker.tsx | 2 +- .../flavours/glitch/features/emoji/hooks.ts | 78 ---- .../flavours/glitch/features/emoji/index.ts | 4 +- .../flavours/glitch/features/emoji/mode.ts | 23 +- .../glitch/features/emoji/render.test.ts | 198 +++++---- .../flavours/glitch/features/emoji/render.ts | 403 +++--------------- .../flavours/glitch/features/emoji/types.ts | 10 +- .../glitch/features/emoji/utils.test.ts | 80 ++-- .../flavours/glitch/features/emoji/utils.ts | 16 +- 14 files changed, 330 insertions(+), 660 deletions(-) create mode 100644 app/javascript/flavours/glitch/components/emoji/emoji.stories.tsx delete mode 100644 app/javascript/flavours/glitch/features/emoji/hooks.ts diff --git a/app/javascript/flavours/glitch/components/emoji/emoji.stories.tsx b/app/javascript/flavours/glitch/components/emoji/emoji.stories.tsx new file mode 100644 index 00000000000000..d4f5663ae4dc6d --- /dev/null +++ b/app/javascript/flavours/glitch/components/emoji/emoji.stories.tsx @@ -0,0 +1,56 @@ +import type { ComponentProps } from 'react'; + +import type { Meta, StoryObj } from '@storybook/react-vite'; + +import { importCustomEmojiData } from '@/flavours/glitch/features/emoji/loader'; + +import { Emoji } from './index'; + +type EmojiProps = ComponentProps & { state: string }; + +const meta = { + title: 'Components/Emoji', + component: Emoji, + args: { + code: '🖤', + state: 'auto', + }, + argTypes: { + code: { + name: 'Emoji', + }, + state: { + control: { + type: 'select', + labels: { + auto: 'Auto', + native: 'Native', + twemoji: 'Twemoji', + }, + }, + options: ['auto', 'native', 'twemoji'], + name: 'Emoji Style', + mapping: { + auto: { meta: { emoji_style: 'auto' } }, + native: { meta: { emoji_style: 'native' } }, + twemoji: { meta: { emoji_style: 'twemoji' } }, + }, + }, + }, + render(args) { + void importCustomEmojiData(); + return ; + }, +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = {}; + +export const CustomEmoji: Story = { + args: { + code: ':custom:', + }, +}; diff --git a/app/javascript/flavours/glitch/components/emoji/html.tsx b/app/javascript/flavours/glitch/components/emoji/html.tsx index b4689101d55f2b..ee4c84f1f539cd 100644 --- a/app/javascript/flavours/glitch/components/emoji/html.tsx +++ b/app/javascript/flavours/glitch/components/emoji/html.tsx @@ -14,7 +14,7 @@ import { polymorphicForwardRef } from '@/types/polymorphic'; import { AnimateEmojiProvider, CustomEmojiProvider } from './context'; import { textToEmojis } from './index'; -interface EmojiHTMLProps { +export interface EmojiHTMLProps { htmlString: string; extraEmojis?: CustomEmojiMapArg; className?: string; diff --git a/app/javascript/flavours/glitch/components/emoji/index.tsx b/app/javascript/flavours/glitch/components/emoji/index.tsx index b79a45289c6c30..6ca3321452b30c 100644 --- a/app/javascript/flavours/glitch/components/emoji/index.tsx +++ b/app/javascript/flavours/glitch/components/emoji/index.tsx @@ -2,7 +2,7 @@ import type { FC } from 'react'; import { useContext, useEffect, useState } from 'react'; import { EMOJI_TYPE_CUSTOM } from '@/flavours/glitch/features/emoji/constants'; -import { useEmojiAppState } from '@/flavours/glitch/features/emoji/hooks'; +import { useEmojiAppState } from '@/flavours/glitch/features/emoji/mode'; import { unicodeHexToUrl } from '@/flavours/glitch/features/emoji/normalize'; import { isStateLoaded, diff --git a/app/javascript/flavours/glitch/components/html_block/html_block.stories.tsx b/app/javascript/flavours/glitch/components/html_block/html_block.stories.tsx index 9c104ba45cb68e..6fb3206df0e8c1 100644 --- a/app/javascript/flavours/glitch/components/html_block/html_block.stories.tsx +++ b/app/javascript/flavours/glitch/components/html_block/html_block.stories.tsx @@ -7,23 +7,49 @@ const meta = { title: 'Components/HTMLBlock', component: HTMLBlock, args: { - contents: - '

Hello, world!

\n

A link

\n

This should be filtered out:

', + htmlString: `

Hello, world!

+

A link

+

This should be filtered out:

+

This also has emoji: 🖤

`, + }, + argTypes: { + extraEmojis: { + table: { + disable: true, + }, + }, + onElement: { + table: { + disable: true, + }, + }, + onAttribute: { + table: { + disable: true, + }, + }, }, render(args) { return ( // Just for visual clarity in Storybook. -
- -
+ /> ); }, + // Force Twemoji to demonstrate emoji rendering. + parameters: { + state: { + meta: { + emoji_style: 'twemoji', + }, + }, + }, } satisfies Meta; export default meta; diff --git a/app/javascript/flavours/glitch/components/html_block/index.tsx b/app/javascript/flavours/glitch/components/html_block/index.tsx index 8072937331471a..be7b28ec3ff4e3 100644 --- a/app/javascript/flavours/glitch/components/html_block/index.tsx +++ b/app/javascript/flavours/glitch/components/html_block/index.tsx @@ -1,50 +1,30 @@ -import type { FC, ReactNode } from 'react'; -import { useMemo } from 'react'; - -import { cleanExtraEmojis } from '@/flavours/glitch/features/emoji/normalize'; -import type { CustomEmojiMapArg } from '@/flavours/glitch/features/emoji/types'; -import { createLimitedCache } from '@/flavours/glitch/utils/cache'; - -import { htmlStringToComponents } from '../../utils/html'; - -// Use a module-level cache to avoid re-rendering the same HTML multiple times. -const cache = createLimitedCache({ maxSize: 1000 }); - -interface HTMLBlockProps { - contents: string; - extraEmojis?: CustomEmojiMapArg; -} - -export const HTMLBlock: FC = ({ - contents: raw, - extraEmojis, -}) => { - const customEmojis = useMemo( - () => cleanExtraEmojis(extraEmojis), - [extraEmojis], - ); - const contents = useMemo(() => { - const key = JSON.stringify({ raw, customEmojis }); - if (cache.has(key)) { - return cache.get(key); - } - - const rendered = htmlStringToComponents(raw, { - onText, - extraArgs: { customEmojis }, +import { useCallback } from 'react'; + +import type { OnElementHandler } from '@/flavours/glitch/utils/html'; +import { polymorphicForwardRef } from '@/types/polymorphic'; + +import type { EmojiHTMLProps } from '../emoji/html'; +import { ModernEmojiHTML } from '../emoji/html'; +import { useElementHandledLink } from '../status/handled_link'; + +export const HTMLBlock = polymorphicForwardRef< + 'div', + EmojiHTMLProps & Parameters[0] +>( + ({ + onElement: onParentElement, + hrefToMention, + hashtagAccountId, + ...props + }) => { + const { onElement: onLinkElement } = useElementHandledLink({ + hrefToMention, + hashtagAccountId, }); - - cache.set(key, rendered); - return rendered; - }, [raw, customEmojis]); - - return contents; -}; - -function onText( - text: string, - // eslint-disable-next-line @typescript-eslint/no-unused-vars -- Doesn't do anything, just showing how typing would work. - { customEmojis }: { customEmojis: CustomEmojiMapArg | null }, -) { - return text; -} + const onElement: OnElementHandler = useCallback( + (...args) => onParentElement?.(...args) ?? onLinkElement(...args), + [onLinkElement, onParentElement], + ); + return ; + }, +); diff --git a/app/javascript/flavours/glitch/features/emoji/emoji_picker.tsx b/app/javascript/flavours/glitch/features/emoji/emoji_picker.tsx index 4677d6115f4d0b..8daadffd0ad406 100644 --- a/app/javascript/flavours/glitch/features/emoji/emoji_picker.tsx +++ b/app/javascript/flavours/glitch/features/emoji/emoji_picker.tsx @@ -7,7 +7,7 @@ import { assetHost } from 'flavours/glitch/utils/config'; import { EMOJI_MODE_NATIVE } from './constants'; import EmojiData from './emoji_data.json'; -import { useEmojiAppState } from './hooks'; +import { useEmojiAppState } from './mode'; const backgroundImageFnDefault = () => `${assetHost}/emoji/sheet_15_1.png`; diff --git a/app/javascript/flavours/glitch/features/emoji/hooks.ts b/app/javascript/flavours/glitch/features/emoji/hooks.ts deleted file mode 100644 index 067fb1d48b9204..00000000000000 --- a/app/javascript/flavours/glitch/features/emoji/hooks.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { useCallback, useLayoutEffect, useMemo, useState } from 'react'; - -import { createAppSelector, useAppSelector } from '@/flavours/glitch/store'; -import { isModernEmojiEnabled } from '@/flavours/glitch/utils/environment'; - -import { toSupportedLocale } from './locale'; -import { determineEmojiMode } from './mode'; -import { cleanExtraEmojis } from './normalize'; -import { emojifyElement, emojifyText } from './render'; -import type { CustomEmojiMapArg, EmojiAppState } from './types'; -import { stringHasAnyEmoji } from './utils'; - -interface UseEmojifyOptions { - text: string; - extraEmojis?: CustomEmojiMapArg; - deep?: boolean; -} - -export function useEmojify({ - text, - extraEmojis, - deep = true, -}: UseEmojifyOptions) { - const [emojifiedText, setEmojifiedText] = useState(null); - - const appState = useEmojiAppState(); - const extra = useMemo(() => cleanExtraEmojis(extraEmojis), [extraEmojis]); - - const emojify = useCallback( - async (input: string) => { - let result: string | null = null; - if (deep) { - const wrapper = document.createElement('div'); - wrapper.innerHTML = input; - if (await emojifyElement(wrapper, appState, extra ?? {})) { - result = wrapper.innerHTML; - } - } else { - result = await emojifyText(text, appState, extra ?? {}); - } - if (result) { - setEmojifiedText(result); - } else { - setEmojifiedText(input); - } - }, - [appState, deep, extra, text], - ); - useLayoutEffect(() => { - if (isModernEmojiEnabled() && !!text.trim() && stringHasAnyEmoji(text)) { - void emojify(text); - } else { - // If no emoji or we don't want to render, fall back. - setEmojifiedText(text); - } - }, [emojify, text]); - - return emojifiedText; -} - -const modeSelector = createAppSelector( - [(state) => state.meta.get('emoji_style') as string], - (emoji_style) => determineEmojiMode(emoji_style), -); - -export function useEmojiAppState(): EmojiAppState { - const locale = useAppSelector((state) => - toSupportedLocale(state.meta.get('locale') as string), - ); - const mode = useAppSelector(modeSelector); - - return { - currentLocale: locale, - locales: [locale], - mode, - darkTheme: document.body.classList.contains('theme-default'), - }; -} diff --git a/app/javascript/flavours/glitch/features/emoji/index.ts b/app/javascript/flavours/glitch/features/emoji/index.ts index dd3fe841ba40a2..2d181085a1168a 100644 --- a/app/javascript/flavours/glitch/features/emoji/index.ts +++ b/app/javascript/flavours/glitch/features/emoji/index.ts @@ -10,6 +10,8 @@ let worker: Worker | null = null; const log = emojiLogger('index'); +const WORKER_TIMEOUT = 1_000; // 1 second + export function initializeEmoji() { log('initializing emojis'); if (!worker && 'Worker' in window) { @@ -29,7 +31,7 @@ export function initializeEmoji() { log('worker is not ready after timeout'); worker = null; void fallbackLoad(); - }, 500); + }, WORKER_TIMEOUT); thisWorker.addEventListener('message', (event: MessageEvent) => { const { data: message } = event; if (message === 'ready') { diff --git a/app/javascript/flavours/glitch/features/emoji/mode.ts b/app/javascript/flavours/glitch/features/emoji/mode.ts index 994881bca1ec65..197f130b5f276d 100644 --- a/app/javascript/flavours/glitch/features/emoji/mode.ts +++ b/app/javascript/flavours/glitch/features/emoji/mode.ts @@ -1,6 +1,7 @@ // Credit to Nolan Lawson for the original implementation. // See: https://github.com/nolanlawson/emoji-picker-element/blob/master/src/picker/utils/testColorEmojiSupported.js +import { createAppSelector, useAppSelector } from '@/flavours/glitch/store'; import { isDevelopment } from '@/flavours/glitch/utils/environment'; import { @@ -8,7 +9,27 @@ import { EMOJI_MODE_NATIVE_WITH_FLAGS, EMOJI_MODE_TWEMOJI, } from './constants'; -import type { EmojiMode } from './types'; +import { toSupportedLocale } from './locale'; +import type { EmojiAppState, EmojiMode } from './types'; + +const modeSelector = createAppSelector( + [(state) => state.meta.get('emoji_style') as string], + (emoji_style) => determineEmojiMode(emoji_style), +); + +export function useEmojiAppState(): EmojiAppState { + const locale = useAppSelector((state) => + toSupportedLocale(state.meta.get('locale') as string), + ); + const mode = useAppSelector(modeSelector); + + return { + currentLocale: locale, + locales: [locale], + mode, + darkTheme: document.body.classList.contains('theme-default'), + }; +} type Feature = Uint8ClampedArray; diff --git a/app/javascript/flavours/glitch/features/emoji/render.test.ts b/app/javascript/flavours/glitch/features/emoji/render.test.ts index 108cf747504048..05dbc388c458d5 100644 --- a/app/javascript/flavours/glitch/features/emoji/render.test.ts +++ b/app/javascript/flavours/glitch/features/emoji/render.test.ts @@ -1,101 +1,12 @@ import { customEmojiFactory, unicodeEmojiFactory } from '@/testing/factories'; -import { EMOJI_MODE_TWEMOJI } from './constants'; import * as db from './database'; +import * as loader from './loader'; import { - emojifyElement, - emojifyText, - testCacheClear, + loadEmojiDataToState, + stringToEmojiState, tokenizeText, } from './render'; -import type { EmojiAppState } from './types'; - -function mockDatabase() { - return { - searchCustomEmojisByShortcodes: vi - .spyOn(db, 'searchCustomEmojisByShortcodes') - .mockResolvedValue([customEmojiFactory()]), - searchEmojisByHexcodes: vi - .spyOn(db, 'searchEmojisByHexcodes') - .mockResolvedValue([ - unicodeEmojiFactory({ - hexcode: '1F60A', - label: 'smiling face with smiling eyes', - unicode: '😊', - }), - unicodeEmojiFactory({ - hexcode: '1F1EA-1F1FA', - label: 'flag-eu', - unicode: '🇪🇺', - }), - ]), - }; -} - -const expectedSmileImage = - '😊'; -const expectedFlagImage = - '🇪🇺'; - -function testAppState(state: Partial = {}) { - return { - locales: ['en'], - mode: EMOJI_MODE_TWEMOJI, - currentLocale: 'en', - darkTheme: false, - ...state, - } satisfies EmojiAppState; -} - -describe('emojifyElement', () => { - function testElement(text = '

Hello 😊🇪🇺!

:custom:

') { - const testElement = document.createElement('div'); - testElement.innerHTML = text; - return testElement; - } - - afterEach(() => { - testCacheClear(); - vi.restoreAllMocks(); - }); - - test('caches element rendering results', async () => { - const { searchCustomEmojisByShortcodes, searchEmojisByHexcodes } = - mockDatabase(); - await emojifyElement(testElement(), testAppState()); - await emojifyElement(testElement(), testAppState()); - await emojifyElement(testElement(), testAppState()); - expect(searchEmojisByHexcodes).toHaveBeenCalledExactlyOnceWith( - ['1F1EA-1F1FA', '1F60A'], - 'en', - ); - expect(searchCustomEmojisByShortcodes).toHaveBeenCalledExactlyOnceWith([ - ':custom:', - ]); - }); - - test('returns null when no emoji are found', async () => { - mockDatabase(); - const actual = await emojifyElement( - testElement('

here is just text :)

'), - testAppState(), - ); - expect(actual).toBeNull(); - }); -}); - -describe('emojifyText', () => { - test('returns original input when no emoji are in string', async () => { - const actual = await emojifyText('nothing here', testAppState()); - expect(actual).toBe('nothing here'); - }); - - test('renders Unicode emojis to twemojis', async () => { - mockDatabase(); - const actual = await emojifyText('Hello 😊🇪🇺!', testAppState()); - expect(actual).toBe(`Hello ${expectedSmileImage}${expectedFlagImage}!`); - }); -}); describe('tokenizeText', () => { test('returns an array of text to be a single token', () => { @@ -162,3 +73,106 @@ describe('tokenizeText', () => { ]); }); }); + +describe('stringToEmojiState', () => { + test('returns unicode emoji state for valid unicode emoji', () => { + expect(stringToEmojiState('😊')).toEqual({ + type: 'unicode', + code: '1F60A', + }); + }); + + test('returns custom emoji state for valid custom emoji', () => { + expect(stringToEmojiState(':smile:')).toEqual({ + type: 'custom', + code: 'smile', + data: undefined, + }); + }); + + test('returns custom emoji state with data when provided', () => { + const customEmoji = { + smile: customEmojiFactory({ + shortcode: 'smile', + url: 'https://example.com/smile.png', + static_url: 'https://example.com/smile_static.png', + }), + }; + expect(stringToEmojiState(':smile:', customEmoji)).toEqual({ + type: 'custom', + code: 'smile', + data: customEmoji.smile, + }); + }); + + test('returns null for invalid emoji strings', () => { + expect(stringToEmojiState('notanemoji')).toBeNull(); + expect(stringToEmojiState(':invalid-emoji:')).toBeNull(); + }); +}); + +describe('loadEmojiDataToState', () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + test('loads unicode data into state', async () => { + const dbCall = vi + .spyOn(db, 'loadEmojiByHexcode') + .mockResolvedValue(unicodeEmojiFactory()); + const unicodeState = { type: 'unicode', code: '1F60A' } as const; + const result = await loadEmojiDataToState(unicodeState, 'en'); + expect(dbCall).toHaveBeenCalledWith('1F60A', 'en'); + expect(result).toEqual({ + type: 'unicode', + code: '1F60A', + data: unicodeEmojiFactory(), + }); + }); + + test('loads custom emoji data into state', async () => { + const dbCall = vi + .spyOn(db, 'loadCustomEmojiByShortcode') + .mockResolvedValueOnce(customEmojiFactory()); + const customState = { type: 'custom', code: 'smile' } as const; + const result = await loadEmojiDataToState(customState, 'en'); + expect(dbCall).toHaveBeenCalledWith('smile'); + expect(result).toEqual({ + type: 'custom', + code: 'smile', + data: customEmojiFactory(), + }); + }); + + test('returns null if unicode emoji not found in database', async () => { + vi.spyOn(db, 'loadEmojiByHexcode').mockResolvedValueOnce(undefined); + const unicodeState = { type: 'unicode', code: '1F60A' } as const; + const result = await loadEmojiDataToState(unicodeState, 'en'); + expect(result).toBeNull(); + }); + + test('returns null if custom emoji not found in database', async () => { + vi.spyOn(db, 'loadCustomEmojiByShortcode').mockResolvedValueOnce(undefined); + const customState = { type: 'custom', code: 'smile' } as const; + const result = await loadEmojiDataToState(customState, 'en'); + expect(result).toBeNull(); + }); + + test('retries loading emoji data once if initial load fails', async () => { + const dbCall = vi + .spyOn(db, 'loadEmojiByHexcode') + .mockRejectedValue(new db.LocaleNotLoadedError('en')); + vi.spyOn(loader, 'importEmojiData').mockResolvedValueOnce(); + const consoleCall = vi + .spyOn(console, 'warn') + .mockImplementationOnce(() => null); + + const unicodeState = { type: 'unicode', code: '1F60A' } as const; + const result = await loadEmojiDataToState(unicodeState, 'en'); + + expect(dbCall).toHaveBeenCalledTimes(2); + expect(loader.importEmojiData).toHaveBeenCalledWith('en'); + expect(consoleCall).toHaveBeenCalled(); + expect(result).toBeNull(); + }); +}); diff --git a/app/javascript/flavours/glitch/features/emoji/render.ts b/app/javascript/flavours/glitch/features/emoji/render.ts index 5e10f9367c40ac..574d5ef59b2484 100644 --- a/app/javascript/flavours/glitch/features/emoji/render.ts +++ b/app/javascript/flavours/glitch/features/emoji/render.ts @@ -1,7 +1,3 @@ -import { autoPlayGif } from '@/flavours/glitch/initial_state'; -import { createLimitedCache } from '@/flavours/glitch/utils/cache'; -import * as perf from '@/flavours/glitch/utils/performance'; - import { EMOJI_MODE_NATIVE, EMOJI_MODE_NATIVE_WITH_FLAGS, @@ -12,33 +8,69 @@ import { loadCustomEmojiByShortcode, loadEmojiByHexcode, LocaleNotLoadedError, - searchCustomEmojisByShortcodes, - searchEmojisByHexcodes, } from './database'; import { importEmojiData } from './loader'; -import { emojiToUnicodeHex, unicodeHexToUrl } from './normalize'; +import { emojiToUnicodeHex } from './normalize'; import type { - EmojiAppState, EmojiLoadedState, EmojiMode, EmojiState, EmojiStateCustom, - EmojiStateMap, EmojiStateUnicode, ExtraCustomEmojiMap, - LocaleOrCustom, } from './types'; import { anyEmojiRegex, emojiLogger, isCustomEmoji, isUnicodeEmoji, - stringHasAnyEmoji, stringHasUnicodeFlags, } from './utils'; const log = emojiLogger('render'); +type TokenizedText = (string | EmojiState)[]; + +/** + * Tokenizes text into strings and emoji states. + * @param text Text to tokenize. + * @returns Array of strings and emoji states. + */ +export function tokenizeText(text: string): TokenizedText { + if (!text.trim()) { + return [text]; + } + + const tokens = []; + let lastIndex = 0; + for (const match of text.matchAll(anyEmojiRegex())) { + if (match.index > lastIndex) { + tokens.push(text.slice(lastIndex, match.index)); + } + + const code = match[0]; + + if (code.startsWith(':') && code.endsWith(':')) { + // Custom emoji + tokens.push({ + type: EMOJI_TYPE_CUSTOM, + code, + } satisfies EmojiStateCustom); + } else { + // Unicode emoji + tokens.push({ + type: EMOJI_TYPE_UNICODE, + code: code, + } satisfies EmojiStateUnicode); + } + lastIndex = match.index + code.length; + } + if (lastIndex < text.length) { + tokens.push(text.slice(lastIndex)); + } + return tokens; +} + /** * Parses emoji string to extract emoji state. * @param code Hex code or custom shortcode. @@ -132,305 +164,19 @@ export function isStateLoaded(state: EmojiState): state is EmojiLoadedState { } /** - * Emojifies an element. This modifies the element in place, replacing text nodes with emojified versions. + * Determines if the given token should be rendered as an image based on the emoji mode. + * @param state Emoji state to parse. + * @param mode Rendering mode. + * @returns Whether to render as an image. */ -export async function emojifyElement( - element: Element, - appState: EmojiAppState, - extraEmojis: ExtraCustomEmojiMap = {}, -): Promise { - const cacheKey = createCacheKey(element, appState, extraEmojis); - const cached = getCached(cacheKey); - if (cached !== undefined) { - log('Cache hit on %s', element.outerHTML); - if (cached === null) { - return null; - } - element.innerHTML = cached; - return element; - } - if (!stringHasAnyEmoji(element.innerHTML)) { - updateCache(cacheKey, null); - return null; - } - perf.start('emojifyElement()'); - const queue: (HTMLElement | Text)[] = [element]; - while (queue.length > 0) { - const current = queue.shift(); - if ( - !current || - current instanceof HTMLScriptElement || - current instanceof HTMLStyleElement - ) { - continue; - } - - if ( - current.textContent && - (current instanceof Text || !current.hasChildNodes()) - ) { - const renderedContent = await textToElementArray( - current.textContent, - appState, - extraEmojis, - ); - if (renderedContent) { - if (!(current instanceof Text)) { - current.textContent = null; // Clear the text content if it's not a Text node. - } - current.replaceWith(renderedToHTML(renderedContent)); - } - continue; - } - - for (const child of current.childNodes) { - if (child instanceof HTMLElement || child instanceof Text) { - queue.push(child); - } - } - } - updateCache(cacheKey, element.innerHTML); - perf.stop('emojifyElement()'); - return element; -} - -export async function emojifyText( - text: string, - appState: EmojiAppState, - extraEmojis: ExtraCustomEmojiMap = {}, -): Promise { - const cacheKey = createCacheKey(text, appState, extraEmojis); - const cached = getCached(cacheKey); - if (cached !== undefined) { - log('Cache hit on %s', text); - return cached ?? text; - } - if (!stringHasAnyEmoji(text)) { - updateCache(cacheKey, null); - return text; - } - const eleArray = await textToElementArray(text, appState, extraEmojis); - if (!eleArray) { - updateCache(cacheKey, null); - return text; - } - const rendered = renderedToHTML(eleArray, document.createElement('div')); - updateCache(cacheKey, rendered.innerHTML); - return rendered.innerHTML; -} - -// Private functions - -const { - set: updateCache, - get: getCached, - clear: cacheClear, -} = createLimitedCache({ log: log.extend('cache') }); - -function createCacheKey( - input: HTMLElement | string, - appState: EmojiAppState, - extraEmojis: ExtraCustomEmojiMap, -) { - return JSON.stringify([ - input instanceof HTMLElement ? input.outerHTML : input, - appState, - extraEmojis, - ]); -} - -type EmojifiedTextArray = (string | HTMLImageElement)[]; - -async function textToElementArray( - text: string, - appState: EmojiAppState, - extraEmojis: ExtraCustomEmojiMap = {}, -): Promise { - // Exit if no text to convert. - if (!text.trim()) { - return null; - } - - const tokens = tokenizeText(text); - - // If only one token and it's a string, exit early. - if (tokens.length === 1 && typeof tokens[0] === 'string') { - return null; - } - - // Get all emoji from the state map, loading any missing ones. - await loadMissingEmojiIntoCache(tokens, appState, extraEmojis); - - const renderedFragments: EmojifiedTextArray = []; - for (const token of tokens) { - if (typeof token !== 'string' && shouldRenderImage(token, appState.mode)) { - let state: EmojiState | undefined; - if (token.type === EMOJI_TYPE_CUSTOM) { - const extraEmojiData = extraEmojis[token.code]; - if (extraEmojiData) { - state = { - type: EMOJI_TYPE_CUSTOM, - data: extraEmojiData, - code: token.code, - }; - } else { - state = emojiForLocale(token.code, EMOJI_TYPE_CUSTOM); - } - } else { - state = emojiForLocale( - emojiToUnicodeHex(token.code), - appState.currentLocale, - ); - } - - // If the state is valid, create an image element. Otherwise, just append as text. - if (state && typeof state !== 'string' && isStateLoaded(state)) { - const image = stateToImage(state, appState); - renderedFragments.push(image); - continue; - } - } - const text = typeof token === 'string' ? token : token.code; - renderedFragments.push(text); - } - - return renderedFragments; -} - -type TokenizedText = (string | EmojiState)[]; - -export function tokenizeText(text: string): TokenizedText { - if (!text.trim()) { - return [text]; - } - - const tokens = []; - let lastIndex = 0; - for (const match of text.matchAll(anyEmojiRegex())) { - if (match.index > lastIndex) { - tokens.push(text.slice(lastIndex, match.index)); - } - - const code = match[0]; - - if (code.startsWith(':') && code.endsWith(':')) { - // Custom emoji - tokens.push({ - type: EMOJI_TYPE_CUSTOM, - code, - } satisfies EmojiStateCustom); - } else { - // Unicode emoji - tokens.push({ - type: EMOJI_TYPE_UNICODE, - code: code, - } satisfies EmojiStateUnicode); - } - lastIndex = match.index + code.length; - } - if (lastIndex < text.length) { - tokens.push(text.slice(lastIndex)); - } - return tokens; -} - -const localeCacheMap = new Map([ - [ - EMOJI_TYPE_CUSTOM, - createLimitedCache({ log: log.extend('custom') }), - ], -]); - -function cacheForLocale(locale: LocaleOrCustom): EmojiStateMap { - return ( - localeCacheMap.get(locale) ?? - createLimitedCache({ log: log.extend(locale) }) - ); -} - -function emojiForLocale( - code: string, - locale: LocaleOrCustom, -): EmojiState | undefined { - const cache = cacheForLocale(locale); - return cache.get(code); -} - -async function loadMissingEmojiIntoCache( - tokens: TokenizedText, - { mode, currentLocale }: EmojiAppState, - extraEmojis: ExtraCustomEmojiMap, -) { - const missingUnicodeEmoji = new Set(); - const missingCustomEmoji = new Set(); - - // Iterate over tokens and check if they are in the cache already. - for (const token of tokens) { - if (typeof token === 'string') { - continue; // Skip plain strings. - } - - // If this is a custom emoji, check it separately. - if (token.type === EMOJI_TYPE_CUSTOM) { - const code = token.code; - if (code in extraEmojis) { - continue; // We don't care about extra emoji. - } - const emojiState = emojiForLocale(code, EMOJI_TYPE_CUSTOM); - if (!emojiState) { - missingCustomEmoji.add(code); - } - // Otherwise this is a unicode emoji, so check it against all locales. - } else if (shouldRenderImage(token, mode)) { - const code = emojiToUnicodeHex(token.code); - if (missingUnicodeEmoji.has(code)) { - continue; // Already marked as missing. - } - const emojiState = emojiForLocale(code, currentLocale); - if (!emojiState) { - // If it's missing in one locale, we consider it missing for all. - missingUnicodeEmoji.add(code); - } - } - } - - if (missingUnicodeEmoji.size > 0) { - const missingEmojis = Array.from(missingUnicodeEmoji).toSorted(); - const emojis = await searchEmojisByHexcodes(missingEmojis, currentLocale); - const cache = cacheForLocale(currentLocale); - for (const emoji of emojis) { - cache.set(emoji.hexcode, { - type: EMOJI_TYPE_UNICODE, - data: emoji, - code: emoji.hexcode, - }); - } - localeCacheMap.set(currentLocale, cache); - } - - if (missingCustomEmoji.size > 0) { - const missingEmojis = Array.from(missingCustomEmoji).toSorted(); - const emojis = await searchCustomEmojisByShortcodes(missingEmojis); - const cache = cacheForLocale(EMOJI_TYPE_CUSTOM); - for (const emoji of emojis) { - cache.set(emoji.shortcode, { - type: EMOJI_TYPE_CUSTOM, - data: emoji, - code: emoji.shortcode, - }); - } - localeCacheMap.set(EMOJI_TYPE_CUSTOM, cache); - } -} - -export function shouldRenderImage(token: EmojiState, mode: EmojiMode): boolean { - if (token.type === EMOJI_TYPE_UNICODE) { +export function shouldRenderImage(state: EmojiState, mode: EmojiMode): boolean { + if (state.type === EMOJI_TYPE_UNICODE) { // If the mode is native or native with flags for non-flag emoji // we can just append the text node directly. if ( mode === EMOJI_MODE_NATIVE || (mode === EMOJI_MODE_NATIVE_WITH_FLAGS && - !stringHasUnicodeFlags(token.code)) + !stringHasUnicodeFlags(state.code)) ) { return false; } @@ -438,52 +184,3 @@ export function shouldRenderImage(token: EmojiState, mode: EmojiMode): boolean { return true; } - -function stateToImage(state: EmojiLoadedState, appState: EmojiAppState) { - const image = document.createElement('img'); - image.draggable = false; - image.classList.add('emojione'); - - if (state.type === EMOJI_TYPE_UNICODE) { - image.alt = state.data.unicode; - image.title = state.data.label; - image.src = unicodeHexToUrl(state.data.hexcode, appState.darkTheme); - } else { - // Custom emoji - const shortCode = `:${state.data.shortcode}:`; - image.classList.add('custom-emoji'); - image.alt = shortCode; - image.title = shortCode; - image.src = autoPlayGif ? state.data.url : state.data.static_url; - image.dataset.original = state.data.url; - image.dataset.static = state.data.static_url; - } - - return image; -} - -function renderedToHTML(renderedArray: EmojifiedTextArray): DocumentFragment; -function renderedToHTML( - renderedArray: EmojifiedTextArray, - parent: ParentType, -): ParentType; -function renderedToHTML( - renderedArray: EmojifiedTextArray, - parent: ParentNode | null = null, -) { - const fragment = parent ?? document.createDocumentFragment(); - for (const fragmentItem of renderedArray) { - if (typeof fragmentItem === 'string') { - fragment.appendChild(document.createTextNode(fragmentItem)); - } else if (fragmentItem instanceof HTMLImageElement) { - fragment.appendChild(fragmentItem); - } - } - return fragment; -} - -// Testing helpers -export const testCacheClear = () => { - cacheClear(); - localeCacheMap.clear(); -}; diff --git a/app/javascript/flavours/glitch/features/emoji/types.ts b/app/javascript/flavours/glitch/features/emoji/types.ts index b9c53e0697ec06..a940aa4d929386 100644 --- a/app/javascript/flavours/glitch/features/emoji/types.ts +++ b/app/javascript/flavours/glitch/features/emoji/types.ts @@ -4,7 +4,6 @@ import type { FlatCompactEmoji, Locale } from 'emojibase'; import type { ApiCustomEmojiJSON } from '@/flavours/glitch/api_types/custom_emoji'; import type { CustomEmoji } from '@/flavours/glitch/models/custom_emoji'; -import type { LimitedCache } from '@/flavours/glitch/utils/cache'; import type { EMOJI_MODE_NATIVE, @@ -48,12 +47,11 @@ export interface EmojiStateCustom { data?: CustomEmojiRenderFields; } export type EmojiState = EmojiStateUnicode | EmojiStateCustom; + export type EmojiLoadedState = | Required | Required; -export type EmojiStateMap = LimitedCache; - export type CustomEmojiMapArg = | ExtraCustomEmojiMap | ImmutableList @@ -64,9 +62,3 @@ export type ExtraCustomEmojiMap = Record< string, Pick >; - -export interface TwemojiBorderInfo { - hexCode: string; - hasLightBorder: boolean; - hasDarkBorder: boolean; -} diff --git a/app/javascript/flavours/glitch/features/emoji/utils.test.ts b/app/javascript/flavours/glitch/features/emoji/utils.test.ts index b9062294c47b14..3844c814a10166 100644 --- a/app/javascript/flavours/glitch/features/emoji/utils.test.ts +++ b/app/javascript/flavours/glitch/features/emoji/utils.test.ts @@ -1,35 +1,31 @@ -import { - stringHasAnyEmoji, - stringHasCustomEmoji, - stringHasUnicodeEmoji, - stringHasUnicodeFlags, -} from './utils'; +import { isCustomEmoji, isUnicodeEmoji, stringHasUnicodeFlags } from './utils'; -describe('stringHasUnicodeEmoji', () => { +describe('isUnicodeEmoji', () => { test.concurrent.for([ - ['only text', false], - ['text with non-emoji symbols ™©', false], - ['text with emoji 😀', true], - ['multiple emojis 😀😃😄', true], - ['emoji with skin tone 👍🏽', true], - ['emoji with ZWJ 👩‍❤️‍👨', true], - ['emoji with variation selector ✊️', true], - ['emoji with keycap 1️⃣', true], - ['emoji with flags 🇺🇸', true], - ['emoji with regional indicators 🇦🇺', true], - ['emoji with gender 👩‍⚕️', true], - ['emoji with family 👨‍👩‍👧‍👦', true], - ['emoji with zero width joiner 👩‍🔬', true], - ['emoji with non-BMP codepoint 🧑‍🚀', true], - ['emoji with combining marks 👨‍👩‍👧‍👦', true], - ['emoji with enclosing keycap #️⃣', true], - ['emoji with no visible glyph \u200D', false], - ] as const)( - 'stringHasUnicodeEmoji has emojis in "%s": %o', - ([text, expected], { expect }) => { - expect(stringHasUnicodeEmoji(text)).toBe(expected); - }, - ); + ['😊', true], + ['🇿🇼', true], + ['🏴‍☠️', true], + ['🏳️‍🌈', true], + ['foo', false], + [':smile:', false], + ['😊foo', false], + ] as const)('isUnicodeEmoji("%s") is %o', ([input, expected], { expect }) => { + expect(isUnicodeEmoji(input)).toBe(expected); + }); +}); + +describe('isCustomEmoji', () => { + test.concurrent.for([ + [':smile:', true], + [':smile_123:', true], + [':SMILE:', true], + ['😊', false], + ['foo', false], + [':smile', false], + ['smile:', false], + ] as const)('isCustomEmoji("%s") is %o', ([input, expected], { expect }) => { + expect(isCustomEmoji(input)).toBe(expected); + }); }); describe('stringHasUnicodeFlags', () => { @@ -51,27 +47,3 @@ describe('stringHasUnicodeFlags', () => { }, ); }); - -describe('stringHasCustomEmoji', () => { - test('string with custom emoji returns true', () => { - expect(stringHasCustomEmoji(':custom: :test:')).toBeTruthy(); - }); - test('string without custom emoji returns false', () => { - expect(stringHasCustomEmoji('🏳️‍🌈 :🏳️‍🌈: text ™')).toBeFalsy(); - }); -}); - -describe('stringHasAnyEmoji', () => { - test('string without any emoji or characters', () => { - expect(stringHasAnyEmoji('normal text. 12356?!')).toBeFalsy(); - }); - test('string with non-emoji characters', () => { - expect(stringHasAnyEmoji('™©')).toBeFalsy(); - }); - test('has unicode emoji', () => { - expect(stringHasAnyEmoji('🏳️‍🌈🔥🇸🇹 👩‍🔬')).toBeTruthy(); - }); - test('has custom emoji', () => { - expect(stringHasAnyEmoji(':test: :custom:')).toBeTruthy(); - }); -}); diff --git a/app/javascript/flavours/glitch/features/emoji/utils.ts b/app/javascript/flavours/glitch/features/emoji/utils.ts index bb190951cf8bc6..4c6750f6e2b2e3 100644 --- a/app/javascript/flavours/glitch/features/emoji/utils.ts +++ b/app/javascript/flavours/glitch/features/emoji/utils.ts @@ -6,10 +6,6 @@ export function emojiLogger(segment: string) { return debug(`emojis:${segment}`); } -export function stringHasUnicodeEmoji(input: string): boolean { - return new RegExp(EMOJI_REGEX, supportedFlags()).test(input); -} - export function isUnicodeEmoji(input: string): boolean { return ( input.length > 0 && @@ -34,19 +30,13 @@ export function stringHasUnicodeFlags(input: string): boolean { // Constant as this is supported by all browsers. const CUSTOM_EMOJI_REGEX = /:([a-z0-9_]+):/i; +// Use the polyfill regex or the Unicode property escapes if supported. +const EMOJI_REGEX = emojiRegexPolyfill?.source ?? '\\p{RGI_Emoji}'; export function isCustomEmoji(input: string): boolean { return new RegExp(`^${CUSTOM_EMOJI_REGEX.source}$`, 'i').test(input); } -export function stringHasCustomEmoji(input: string) { - return CUSTOM_EMOJI_REGEX.test(input); -} - -export function stringHasAnyEmoji(input: string) { - return stringHasUnicodeEmoji(input) || stringHasCustomEmoji(input); -} - export function anyEmojiRegex() { return new RegExp( `${EMOJI_REGEX}|${CUSTOM_EMOJI_REGEX.source}`, @@ -64,5 +54,3 @@ function supportedFlags(flags = '') { } return flags; } - -const EMOJI_REGEX = emojiRegexPolyfill?.source ?? '\\p{RGI_Emoji}'; From 7330ec670b1ba96c2527530b757f9c83cecff122 Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 14 Oct 2025 14:21:13 +0200 Subject: [PATCH 165/853] [Glitch] Fix WebUI mistakenly allowing to attach quotes when editing Port 156f031ed046244b26016df92dbf2c72d3b23c3d to glitch-soc Signed-off-by: Claire --- .../flavours/glitch/actions/compose_typed.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/app/javascript/flavours/glitch/actions/compose_typed.ts b/app/javascript/flavours/glitch/actions/compose_typed.ts index ec929df8481856..0b6b0f50de32c9 100644 --- a/app/javascript/flavours/glitch/actions/compose_typed.ts +++ b/app/javascript/flavours/glitch/actions/compose_typed.ts @@ -21,6 +21,10 @@ import { importFetchedStatuses } from './importer'; import { openModal } from './modal'; const messages = defineMessages({ + quoteErrorEdit: { + id: 'quote_error.edit', + defaultMessage: 'Quotes cannot be added when editing a post.', + }, quoteErrorUpload: { id: 'quote_error.upload', defaultMessage: 'Quoting is not allowed with media attachments.', @@ -124,7 +128,9 @@ export const quoteComposeByStatus = createAppThunk( false, ); - if (composeState.get('poll')) { + if (composeState.get('id')) { + dispatch(showAlert({ message: messages.quoteErrorEdit })); + } else if (composeState.get('poll')) { dispatch(showAlert({ message: messages.quoteErrorPoll })); } else if ( composeState.get('is_uploading') || @@ -184,7 +190,8 @@ export const pasteLinkCompose = createDataLoadingThunk( composeState.get('quoted_status_id') || composeState.get('is_submitting') || composeState.get('poll') || - composeState.get('is_uploading') + composeState.get('is_uploading') || + composeState.get('id') ) return; From c4c906eb0c56692d9018eec6b86e01dfaa6563b1 Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 14 Oct 2025 16:04:18 +0200 Subject: [PATCH 166/853] [Glitch] Fix error in logged-out hashtag view when remote posts require log-in Port 3232eee358134ca468b40ec3b517a15fe69b7fe6 to glitch-soc Signed-off-by: Claire --- .../features/hashtag_timeline/index.jsx | 32 +++++++++++-------- .../flavours/glitch/initial_state.ts | 4 +++ 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/app/javascript/flavours/glitch/features/hashtag_timeline/index.jsx b/app/javascript/flavours/glitch/features/hashtag_timeline/index.jsx index 48335488f07575..c2c453aa377550 100644 --- a/app/javascript/flavours/glitch/features/hashtag_timeline/index.jsx +++ b/app/javascript/flavours/glitch/features/hashtag_timeline/index.jsx @@ -16,15 +16,21 @@ import { expandHashtagTimeline, clearTimeline } from 'flavours/glitch/actions/ti import Column from 'flavours/glitch/components/column'; import ColumnHeader from 'flavours/glitch/components/column_header'; import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context'; +import { remoteTopicFeedAccess, me } from 'flavours/glitch/initial_state'; import StatusListContainer from '../ui/containers/status_list_container'; import { HashtagHeader } from './components/hashtag_header'; import ColumnSettingsContainer from './containers/column_settings_container'; -const mapStateToProps = (state, props) => ({ - hasUnread: state.getIn(['timelines', `hashtag:${props.params.id}${props.params.local ? ':local' : ''}`, 'unread']) > 0, -}); +const mapStateToProps = (state, props) => { + const local = props.params.local || (!me && remoteTopicFeedAccess !== 'public'); + + return ({ + local, + hasUnread: state.getIn(['timelines', `hashtag:${props.params.id}${local ? ':local' : ''}`, 'unread']) > 0, + }); +}; class HashtagTimeline extends PureComponent { disconnects = []; @@ -113,16 +119,16 @@ class HashtagTimeline extends PureComponent { } _unload () { - const { dispatch } = this.props; - const { id, local } = this.props.params; + const { dispatch, local } = this.props; + const { id } = this.props.params; this._unsubscribe(); dispatch(clearTimeline(`hashtag:${id}${local ? ':local' : ''}`)); } _load() { - const { dispatch } = this.props; - const { id, tags, local } = this.props.params; + const { dispatch, local } = this.props; + const { id, tags } = this.props.params; this._subscribe(dispatch, id, tags, local); dispatch(expandHashtagTimeline(id, { tags, local })); @@ -133,8 +139,8 @@ class HashtagTimeline extends PureComponent { } componentDidUpdate (prevProps) { - const { params } = this.props; - const { id, tags, local } = prevProps.params; + const { params, local } = this.props; + const { id, tags } = prevProps.params; if (id !== params.id || !isEqual(tags, params.tags) || !isEqual(local, params.local)) { this._unload(); @@ -151,15 +157,15 @@ class HashtagTimeline extends PureComponent { }; handleLoadMore = maxId => { - const { dispatch, params } = this.props; - const { id, tags, local } = params; + const { dispatch, params, local } = this.props; + const { id, tags } = params; dispatch(expandHashtagTimeline(id, { maxId, tags, local })); }; render () { - const { hasUnread, columnId, multiColumn } = this.props; - const { id, local } = this.props.params; + const { hasUnread, columnId, multiColumn, local } = this.props; + const { id } = this.props.params; const pinned = !!columnId; return ( diff --git a/app/javascript/flavours/glitch/initial_state.ts b/app/javascript/flavours/glitch/initial_state.ts index 926cfbe1c297c2..06d78125bbef28 100644 --- a/app/javascript/flavours/glitch/initial_state.ts +++ b/app/javascript/flavours/glitch/initial_state.ts @@ -36,6 +36,8 @@ interface InitialStateMeta { streaming_api_base_url: string; local_live_feed_access: 'public' | 'authenticated'; remote_live_feed_access: 'public' | 'authenticated'; + local_topic_feed_access: 'public' | 'authenticated'; + remote_topic_feed_access: 'public' | 'authenticated'; title: string; show_trends: boolean; trends_as_landing_page: boolean; @@ -141,6 +143,8 @@ export const singleUserMode = getMeta('single_user_mode'); export const source_url = getMeta('source_url'); export const localLiveFeedAccess = getMeta('local_live_feed_access'); export const remoteLiveFeedAccess = getMeta('remote_live_feed_access'); +export const localTopicFeedAccess = getMeta('local_topic_feed_access'); +export const remoteTopicFeedAccess = getMeta('remote_topic_feed_access'); export const title = getMeta('title'); export const trendsAsLanding = getMeta('trends_as_landing_page'); export const useBlurhash = getMeta('use_blurhash'); From 264d068d8dc8107a492cc1ecebc4a141696466c1 Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 14 Oct 2025 18:36:55 +0200 Subject: [PATCH 167/853] Change new accounts to use new ActivityPub numeric ID scheme (#36365) --- app/models/account.rb | 9 +-- ...5_change_defaults_for_account_id_scheme.rb | 7 ++ db/schema.rb | 4 +- .../account_controller_concern_spec.rb | 2 +- .../follower_accounts_controller_spec.rb | 4 +- .../following_accounts_controller_spec.rb | 4 +- spec/lib/activitypub/tag_manager_spec.rb | 67 ++++++++++--------- spec/models/remote_follow_spec.rb | 2 +- spec/requests/activitypub/outboxes_spec.rb | 2 +- spec/requests/link_headers_spec.rb | 2 +- spec/requests/oauth/userinfo_spec.rb | 2 +- spec/requests/well_known/webfinger_spec.rb | 2 +- 12 files changed, 54 insertions(+), 53 deletions(-) create mode 100644 db/migrate/20251007142305_change_defaults_for_account_id_scheme.rb diff --git a/app/models/account.rb b/app/models/account.rb index a837cc6a6ff4e6..5f4caf9eaa7cea 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -52,7 +52,7 @@ # requested_review_at :datetime # indexable :boolean default(FALSE), not null # attribution_domains :string default([]), is an Array -# id_scheme :integer default("username_ap_id") +# id_scheme :integer default("numeric_ap_id") # class Account < ApplicationRecord @@ -446,7 +446,6 @@ def emojis before_validation :prepare_contents, if: :local? before_create :generate_keys - before_create :set_id_scheme before_destroy :clean_feed_manager def ensure_keys! @@ -471,12 +470,6 @@ def generate_keys self.public_key = keypair.public_key.to_pem end - def set_id_scheme - return unless local? && Mastodon::Feature.numeric_ap_ids_enabled? - - self.id_scheme = :numeric_ap_id - end - def normalize_domain return if local? diff --git a/db/migrate/20251007142305_change_defaults_for_account_id_scheme.rb b/db/migrate/20251007142305_change_defaults_for_account_id_scheme.rb new file mode 100644 index 00000000000000..6c07236968a05d --- /dev/null +++ b/db/migrate/20251007142305_change_defaults_for_account_id_scheme.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class ChangeDefaultsForAccountIdScheme < ActiveRecord::Migration[8.0] + def change + change_column_default :accounts, :id_scheme, from: 0, to: 1 + end +end diff --git a/db/schema.rb b/db/schema.rb index 47937f8657519b..8910bac36a8b59 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[8.0].define(version: 2025_10_07_100813) do +ActiveRecord::Schema[8.0].define(version: 2025_10_07_142305) do # These are extensions that must be enabled in order to support this database enable_extension "pg_catalog.plpgsql" @@ -199,7 +199,7 @@ t.boolean "indexable", default: false, null: false t.string "attribution_domains", default: [], array: true t.string "following_url", default: "", null: false - t.integer "id_scheme", default: 0 + t.integer "id_scheme", default: 1 t.index "(((setweight(to_tsvector('simple'::regconfig, (display_name)::text), 'A'::\"char\") || setweight(to_tsvector('simple'::regconfig, (username)::text), 'B'::\"char\")) || setweight(to_tsvector('simple'::regconfig, (COALESCE(domain, ''::character varying))::text), 'C'::\"char\")))", name: "search_index", using: :gin t.index "lower((username)::text), COALESCE(lower((domain)::text), ''::text)", name: "index_accounts_on_username_and_domain_lower", unique: true t.index ["domain", "id"], name: "index_accounts_on_domain_and_id" diff --git a/spec/controllers/concerns/account_controller_concern_spec.rb b/spec/controllers/concerns/account_controller_concern_spec.rb index df6278a6e98e66..b5c8c166433f5c 100644 --- a/spec/controllers/concerns/account_controller_concern_spec.rb +++ b/spec/controllers/concerns/account_controller_concern_spec.rb @@ -58,7 +58,7 @@ def success expect(response) .to have_http_status(200) .and have_http_link_header(webfinger_url(resource: account.to_webfinger_s)).for(rel: 'lrdd', type: 'application/jrd+json') - .and have_http_link_header(account_url(account, protocol: :https)).for(rel: 'alternate', type: 'application/activity+json') + .and have_http_link_header(ActivityPub::TagManager.instance.uri_for(account)).for(rel: 'alternate', type: 'application/activity+json') expect(response.body) .to include(account.username) end diff --git a/spec/controllers/follower_accounts_controller_spec.rb b/spec/controllers/follower_accounts_controller_spec.rb index e14ed00e609a24..dab6aadbaabfd4 100644 --- a/spec/controllers/follower_accounts_controller_spec.rb +++ b/spec/controllers/follower_accounts_controller_spec.rb @@ -49,8 +49,8 @@ expect(response.parsed_body) .to include( orderedItems: contain_exactly( - include(follow_from_bob.account.username), - include(follow_from_chris.account.username) + ActivityPub::TagManager.instance.uri_for(follow_from_bob.account), + ActivityPub::TagManager.instance.uri_for(follow_from_chris.account) ), totalItems: eq(2), partOf: be_present diff --git a/spec/controllers/following_accounts_controller_spec.rb b/spec/controllers/following_accounts_controller_spec.rb index fea4d4845c8497..666c655d74377f 100644 --- a/spec/controllers/following_accounts_controller_spec.rb +++ b/spec/controllers/following_accounts_controller_spec.rb @@ -49,8 +49,8 @@ expect(response.parsed_body) .to include( orderedItems: contain_exactly( - include(follow_of_bob.target_account.username), - include(follow_of_chris.target_account.username) + ActivityPub::TagManager.instance.uri_for(follow_of_bob.target_account), + ActivityPub::TagManager.instance.uri_for(follow_of_chris.target_account) ), totalItems: eq(2), partOf: be_present diff --git a/spec/lib/activitypub/tag_manager_spec.rb b/spec/lib/activitypub/tag_manager_spec.rb index 70e084a9c9264a..cad46ad90324b9 100644 --- a/spec/lib/activitypub/tag_manager_spec.rb +++ b/spec/lib/activitypub/tag_manager_spec.rb @@ -23,7 +23,7 @@ describe '#url_for' do context 'with a local account' do - let(:account) { Fabricate(:account) } + let(:account) { Fabricate(:account, id_scheme: :username_ap_id) } it 'returns a string starting with web domain and with the expected path' do expect(subject.url_for(account)) @@ -49,7 +49,8 @@ end context 'with a local status' do - let(:status) { Fabricate(:status) } + let(:account) { Fabricate(:account, id_scheme: :username_ap_id) } + let(:status) { Fabricate(:status, account: account) } it 'returns a string starting with web domain and with the expected path' do expect(subject.url_for(status)) @@ -58,7 +59,6 @@ context 'when using a numeric ID based scheme' do let(:account) { Fabricate(:account, id_scheme: :numeric_ap_id) } - let(:status) { Fabricate(:status, account: account) } it 'returns a string starting with web domain and with the expected path' do expect(subject.url_for(status)) @@ -86,7 +86,7 @@ end context 'with a local account' do - let(:account) { Fabricate(:account) } + let(:account) { Fabricate(:account, id_scheme: :username_ap_id) } it 'returns a string starting with web domain and with the expected path' do expect(subject.uri_for(account)) @@ -112,7 +112,8 @@ end context 'with a local status' do - let(:status) { Fabricate(:status) } + let(:account) { Fabricate(:account, id_scheme: :username_ap_id) } + let(:status) { Fabricate(:status, account: account) } it 'returns a string starting with web domain and with the expected path' do expect(subject.uri_for(status)) @@ -121,7 +122,6 @@ context 'when using a numeric ID based scheme' do let(:account) { Fabricate(:account, id_scheme: :numeric_ap_id) } - let(:status) { Fabricate(:status, account: account) } it 'returns a string starting with web domain and with the expected path' do expect(subject.uri_for(status)) @@ -140,7 +140,8 @@ end context 'with a local conversation' do - let(:status) { Fabricate(:status) } + let(:account) { Fabricate(:account, id_scheme: :username_ap_id) } + let(:status) { Fabricate(:status, account: account) } it 'returns a string starting with web domain and with the expected path' do expect(subject.uri_for(status.conversation)) @@ -149,7 +150,6 @@ context 'when using a numeric ID based scheme' do let(:account) { Fabricate(:account, id_scheme: :numeric_ap_id) } - let(:status) { Fabricate(:status, account: account) } it 'returns a string starting with web domain and with the expected path' do expect(subject.uri_for(status.conversation)) @@ -181,7 +181,7 @@ end context 'with a local account' do - let(:account) { Fabricate(:account) } + let(:account) { Fabricate(:account, id_scheme: :username_ap_id) } it 'returns a string starting with web domain and with the expected path' do expect(subject.key_uri_for(account)) @@ -218,7 +218,9 @@ describe '#approval_uri_for' do context 'with a valid local approval' do - let(:quote) { Fabricate(:quote, state: :accepted) } + let(:quoted_account) { Fabricate(:account, id_scheme: :username_ap_id) } + let(:quoted_status) { Fabricate(:status, account: quoted_account) } + let(:quote) { Fabricate(:quote, state: :accepted, quoted_status: quoted_status) } it 'returns a string with the web domain and expected path' do expect(subject.approval_uri_for(quote)) @@ -227,8 +229,6 @@ context 'when using a numeric ID based scheme' do let(:quoted_account) { Fabricate(:account, id_scheme: :numeric_ap_id) } - let(:quoted_status) { Fabricate(:status, account: quoted_account) } - let(:quote) { Fabricate(:quote, state: :accepted, quoted_status: quoted_status) } it 'returns a string with the web domain and expected path' do expect(subject.approval_uri_for(quote)) @@ -238,7 +238,9 @@ end context 'with an unapproved local quote' do - let(:quote) { Fabricate(:quote, state: :rejected) } + let(:quoted_account) { Fabricate(:account, id_scheme: :username_ap_id) } + let(:quoted_status) { Fabricate(:status, account: quoted_account) } + let(:quote) { Fabricate(:quote, state: :rejected, quoted_status: quoted_status) } it 'returns nil' do expect(subject.approval_uri_for(quote)) @@ -247,8 +249,6 @@ context 'when using a numeric ID based scheme' do let(:quoted_account) { Fabricate(:account, id_scheme: :numeric_ap_id) } - let(:quoted_status) { Fabricate(:status, account: quoted_account) } - let(:quote) { Fabricate(:quote, state: :rejected, quoted_status: quoted_status) } it 'returns nil' do expect(subject.approval_uri_for(quote)) @@ -260,7 +260,7 @@ context 'with a valid remote approval' do let(:quoted_account) { Fabricate(:account, domain: 'example.com') } let(:quoted_status) { Fabricate(:status, account: quoted_account) } - let(:quote) { Fabricate(:quote, state: :accepted, quoted_status: quoted_status, approval_uri: 'https://example.com/approvals/1') } + let(:quote) { Fabricate(:quote, status: Fabricate(:status), state: :accepted, quoted_status: quoted_status, approval_uri: 'https://example.com/approvals/1') } it 'returns the expected URI' do expect(subject.approval_uri_for(quote)).to eq quote.approval_uri @@ -268,7 +268,9 @@ end context 'with an unapproved local quote but check_approval override' do - let(:quote) { Fabricate(:quote, state: :rejected) } + let(:quoted_account) { Fabricate(:account, id_scheme: :username_ap_id) } + let(:quoted_status) { Fabricate(:status, account: quoted_account) } + let(:quote) { Fabricate(:quote, state: :rejected, quoted_status: quoted_status) } it 'returns a string with the web domain and expected path' do expect(subject.approval_uri_for(quote, check_approval: false)) @@ -277,8 +279,6 @@ context 'when using a numeric ID based scheme' do let(:quoted_account) { Fabricate(:account, id_scheme: :numeric_ap_id) } - let(:quoted_status) { Fabricate(:status, account: quoted_account) } - let(:quote) { Fabricate(:quote, state: :rejected, quoted_status: quoted_status) } it 'returns a string with the web domain and expected path' do expect(subject.approval_uri_for(quote, check_approval: false)) @@ -290,7 +290,8 @@ describe '#replies_uri_for' do context 'with a local status' do - let(:status) { Fabricate(:status) } + let(:account) { Fabricate(:account, id_scheme: :username_ap_id) } + let(:status) { Fabricate(:status, account: account) } it 'returns a string starting with web domain and with the expected path' do expect(subject.replies_uri_for(status)) @@ -299,7 +300,6 @@ context 'when using a numeric ID based scheme' do let(:account) { Fabricate(:account, id_scheme: :numeric_ap_id) } - let(:status) { Fabricate(:status, account: account) } it 'returns a string starting with web domain and with the expected path' do expect(subject.replies_uri_for(status)) @@ -311,7 +311,8 @@ describe '#likes_uri_for' do context 'with a local status' do - let(:status) { Fabricate(:status) } + let(:account) { Fabricate(:account, id_scheme: :username_ap_id) } + let(:status) { Fabricate(:status, account: account) } it 'returns a string starting with web domain and with the expected path' do expect(subject.likes_uri_for(status)) @@ -320,7 +321,6 @@ context 'when using a numeric ID based scheme' do let(:account) { Fabricate(:account, id_scheme: :numeric_ap_id) } - let(:status) { Fabricate(:status, account: account) } it 'returns a string starting with web domain and with the expected path' do expect(subject.likes_uri_for(status)) @@ -332,7 +332,8 @@ describe '#shares_uri_for' do context 'with a local status' do - let(:status) { Fabricate(:status) } + let(:account) { Fabricate(:account, id_scheme: :username_ap_id) } + let(:status) { Fabricate(:status, account: account) } it 'returns a string starting with web domain and with the expected path' do expect(subject.shares_uri_for(status)) @@ -341,7 +342,6 @@ context 'when using a numeric ID based scheme' do let(:account) { Fabricate(:account, id_scheme: :numeric_ap_id) } - let(:status) { Fabricate(:status, account: account) } it 'returns a string starting with web domain and with the expected path' do expect(subject.shares_uri_for(status)) @@ -353,7 +353,7 @@ describe '#following_uri_for' do context 'with a local account' do - let(:account) { Fabricate(:account) } + let(:account) { Fabricate(:account, id_scheme: :username_ap_id) } it 'returns a string starting with web domain and with the expected path' do expect(subject.following_uri_for(account)) @@ -373,7 +373,7 @@ describe '#followers_uri_for' do context 'with a local account' do - let(:account) { Fabricate(:account) } + let(:account) { Fabricate(:account, id_scheme: :username_ap_id) } it 'returns a string starting with web domain and with the expected path' do expect(subject.followers_uri_for(account)) @@ -400,7 +400,7 @@ end context 'with a local account' do - let(:account) { Fabricate(:account) } + let(:account) { Fabricate(:account, id_scheme: :username_ap_id) } it 'returns a string starting with web domain and with the expected path' do expect(subject.inbox_uri_for(account)) @@ -427,7 +427,7 @@ end context 'with a local account' do - let(:account) { Fabricate(:account) } + let(:account) { Fabricate(:account, id_scheme: :username_ap_id) } it 'returns a string starting with web domain and with the expected path' do expect(subject.outbox_uri_for(account)) @@ -452,7 +452,7 @@ end it 'returns followers collection for unlisted status' do - status = Fabricate(:status, visibility: :unlisted) + status = Fabricate(:status, visibility: :unlisted, account: Fabricate(:account, id_scheme: :username_ap_id)) expect(subject.to(status)).to eq [account_followers_url(status.account)] end @@ -462,7 +462,7 @@ end it 'returns followers collection for private status' do - status = Fabricate(:status, visibility: :private) + status = Fabricate(:status, visibility: :private, account: Fabricate(:account, id_scheme: :username_ap_id)) expect(subject.to(status)).to eq [account_followers_url(status.account)] end @@ -514,7 +514,7 @@ describe '#cc' do it 'returns followers collection for public status' do - status = Fabricate(:status, visibility: :public) + status = Fabricate(:status, visibility: :public, account: Fabricate(:account, id_scheme: :username_ap_id)) expect(subject.cc(status)).to eq [account_followers_url(status.account)] end @@ -591,8 +591,9 @@ end describe '#uri_to_local_id' do + let(:account) { Fabricate(:account, id_scheme: :username_ap_id) } + it 'returns the local ID' do - account = Fabricate(:account) expect(subject.uri_to_local_id(subject.uri_for(account), :username)).to eq account.username end end diff --git a/spec/models/remote_follow_spec.rb b/spec/models/remote_follow_spec.rb index b3ec7b737e23fe..aad32825625615 100644 --- a/spec/models/remote_follow_spec.rb +++ b/spec/models/remote_follow_spec.rb @@ -68,7 +68,7 @@ def expected_subscribe_url Addressable::URI.new( host: 'quitter.no', path: '/main/ostatussub', - query_values: { profile: "https://#{Rails.configuration.x.local_domain}/users/alice" }, + query_values: { profile: ActivityPub::TagManager.instance.uri_for(account) }, scheme: 'https' ).to_s end diff --git a/spec/requests/activitypub/outboxes_spec.rb b/spec/requests/activitypub/outboxes_spec.rb index 22b2f97c071932..c109214635bdf2 100644 --- a/spec/requests/activitypub/outboxes_spec.rb +++ b/spec/requests/activitypub/outboxes_spec.rb @@ -215,7 +215,7 @@ def targets_public_collection?(item) def targets_followers_collection?(item, account) item[:to].include?( - account_followers_url(account, ActionMailer::Base.default_url_options) + ActivityPub::TagManager.instance.followers_uri_for(account) ) end end diff --git a/spec/requests/link_headers_spec.rb b/spec/requests/link_headers_spec.rb index 5010f7f221f5ea..c782744f016da4 100644 --- a/spec/requests/link_headers_spec.rb +++ b/spec/requests/link_headers_spec.rb @@ -11,7 +11,7 @@ expect(response) .to have_http_link_header(webfinger_url(resource: account.to_webfinger_s)).for(rel: 'lrdd', type: 'application/jrd+json') - .and have_http_link_header(account_url(account)).for(rel: 'alternate', type: 'application/activity+json') + .and have_http_link_header(ActivityPub::TagManager.instance.uri_for(account)).for(rel: 'alternate', type: 'application/activity+json') end end end diff --git a/spec/requests/oauth/userinfo_spec.rb b/spec/requests/oauth/userinfo_spec.rb index 0aa5a21120007c..280a3a35418244 100644 --- a/spec/requests/oauth/userinfo_spec.rb +++ b/spec/requests/oauth/userinfo_spec.rb @@ -19,7 +19,7 @@ expect(response.content_type).to start_with('application/json') expect(response.parsed_body).to include({ iss: root_url, - sub: account_url(account), + sub: ActivityPub::TagManager.instance.uri_for(account), name: account.display_name, preferred_username: account.username, profile: short_account_url(account), diff --git a/spec/requests/well_known/webfinger_spec.rb b/spec/requests/well_known/webfinger_spec.rb index 0c4a3c03474111..593cecbb896cd5 100644 --- a/spec/requests/well_known/webfinger_spec.rb +++ b/spec/requests/well_known/webfinger_spec.rb @@ -27,7 +27,7 @@ expect(response.parsed_body) .to include( subject: eq(alice.to_webfinger_s), - aliases: include("https://#{Rails.configuration.x.local_domain}/@alice", "https://#{Rails.configuration.x.local_domain}/users/alice") + aliases: include("https://#{Rails.configuration.x.local_domain}/@alice", ActivityPub::TagManager.instance.uri_for(alice)) ) end end From d788e45628209f12a380ca1816fa68eb574a9cd5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 15 Oct 2025 09:08:49 +0200 Subject: [PATCH 168/853] Update dependency vite to v7.1.10 (#36468) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 20d256424aa9ca..1408fcf19fa35f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13959,8 +13959,8 @@ __metadata: linkType: hard "vite@npm:^5.0.0 || ^6.0.0 || ^7.0.0-0, vite@npm:^7.1.1": - version: 7.1.9 - resolution: "vite@npm:7.1.9" + version: 7.1.10 + resolution: "vite@npm:7.1.10" dependencies: esbuild: "npm:^0.25.0" fdir: "npm:^6.5.0" @@ -14009,7 +14009,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10c0/f628f903a137c1410232558bde99c223ea00a090bda6af77752c61f912955f0050aac12d3cfe024d08a0f150ff6fab61b3d0be75d634a59b94d49f525392e1f7 + checksum: 10c0/ea296971a3094b0e463a91af58de64dca56c8c5c563237e59d158641f8ad7f600f624c4f7c05c18fad68f414e23d50d7145118169b8dcd4bc85283c63c7185bb languageName: node linkType: hard From 5fd380096f6e1a79ef232637028b01f5953e11f2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 15 Oct 2025 07:10:52 +0000 Subject: [PATCH 169/853] Update dependency vite-plugin-pwa to v1.1.0 (#36452) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 1408fcf19fa35f..6145d48616cdad 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13894,8 +13894,8 @@ __metadata: linkType: hard "vite-plugin-pwa@npm:^1.0.2": - version: 1.0.3 - resolution: "vite-plugin-pwa@npm:1.0.3" + version: 1.1.0 + resolution: "vite-plugin-pwa@npm:1.1.0" dependencies: debug: "npm:^4.3.6" pretty-bytes: "npm:^6.1.1" @@ -13910,7 +13910,7 @@ __metadata: peerDependenciesMeta: "@vite-pwa/assets-generator": optional: true - checksum: 10c0/03fc24bd12ae4a4130979da4877e3dabddf13d7d6ff2bd68e5e8497a2643b8874a78e6c2502874277ddf2f28593d0a3b025d78af2335bdcc5d2966295784fd46 + checksum: 10c0/dc199ccbb3cd0a9f740edcbbc8efa7820f67481ae80a15340ca769c21d4f7452d9a9c1d184eac4f6e3fd1ecd9f7fdfd31cc8f9520e43e6795860fe187c77103a languageName: node linkType: hard From e3e5067772636f5f73be455403fa15168404b1dd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 15 Oct 2025 09:11:45 +0200 Subject: [PATCH 170/853] Update formatjs monorepo (#36415) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 122 +++++++++++++++++++++++------------------------------- 1 file changed, 51 insertions(+), 71 deletions(-) diff --git a/yarn.lock b/yarn.lock index 6145d48616cdad..b6a203bb746606 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2397,15 +2397,15 @@ __metadata: languageName: node linkType: hard -"@formatjs/ecma402-abstract@npm:2.3.5": - version: 2.3.5 - resolution: "@formatjs/ecma402-abstract@npm:2.3.5" +"@formatjs/ecma402-abstract@npm:2.3.6": + version: 2.3.6 + resolution: "@formatjs/ecma402-abstract@npm:2.3.6" dependencies: "@formatjs/fast-memoize": "npm:2.2.7" "@formatjs/intl-localematcher": "npm:0.6.2" decimal.js: "npm:^10.4.3" tslib: "npm:^2.8.0" - checksum: 10c0/c6cac6312a1228347adf3a6a5fd09c0593e7d199e7a56484ece7cb8121c4138ba5c2777b70f82e88d8fbe3199ef5f48b2b1444f0348ee315b930e9db33c67d84 + checksum: 10c0/63be2a73d3168bf45ab5d50db58376e852db5652d89511ae6e44f1fa03ad96ebbfe9b06a1dfaa743db06e40eb7f33bd77530b9388289855cca79a0e3fc29eacf languageName: node linkType: hard @@ -2429,14 +2429,14 @@ __metadata: languageName: node linkType: hard -"@formatjs/icu-messageformat-parser@npm:2.11.3": - version: 2.11.3 - resolution: "@formatjs/icu-messageformat-parser@npm:2.11.3" +"@formatjs/icu-messageformat-parser@npm:2.11.4": + version: 2.11.4 + resolution: "@formatjs/icu-messageformat-parser@npm:2.11.4" dependencies: - "@formatjs/ecma402-abstract": "npm:2.3.5" - "@formatjs/icu-skeleton-parser": "npm:1.8.15" + "@formatjs/ecma402-abstract": "npm:2.3.6" + "@formatjs/icu-skeleton-parser": "npm:1.8.16" tslib: "npm:^2.8.0" - checksum: 10c0/dfa08a671318bc9425f9b8e77ba0fb11856c9e1bb366b2a9c820212711d3483d9337fba50ef0a65c259c5564a6306355b065d739feae56e03b3046edba739460 + checksum: 10c0/3ea9e9dae18282881d19a5f88107b6013f514ec8675684ed2c04bee2a174032377858937243e3bd9c9263a470988a3773a53bf8d208a34a78e7843ce66f87f3b languageName: node linkType: hard @@ -2450,13 +2450,13 @@ __metadata: languageName: node linkType: hard -"@formatjs/icu-skeleton-parser@npm:1.8.15": - version: 1.8.15 - resolution: "@formatjs/icu-skeleton-parser@npm:1.8.15" +"@formatjs/icu-skeleton-parser@npm:1.8.16": + version: 1.8.16 + resolution: "@formatjs/icu-skeleton-parser@npm:1.8.16" dependencies: - "@formatjs/ecma402-abstract": "npm:2.3.5" + "@formatjs/ecma402-abstract": "npm:2.3.6" tslib: "npm:^2.8.0" - checksum: 10c0/e33478f3cdb6d49f8531f35fb80db98d49533add42cd4ab8d3f3cef72c3496ae3042dfe24f252e6afffd3e4f6c9f1dec88367973c14e779dc07947c75641cede + checksum: 10c0/6fa1586dc11c925cd8d17e927cc635d238c969a6b7e97282a924376f78622fc25336c407589d19796fb6f8124a0e7765f99ecdb1aac014edcfbe852e7c3d87f3 languageName: node linkType: hard @@ -2479,32 +2479,32 @@ __metadata: linkType: hard "@formatjs/intl-pluralrules@npm:^5.4.4": - version: 5.4.5 - resolution: "@formatjs/intl-pluralrules@npm:5.4.5" + version: 5.4.6 + resolution: "@formatjs/intl-pluralrules@npm:5.4.6" dependencies: - "@formatjs/ecma402-abstract": "npm:2.3.5" + "@formatjs/ecma402-abstract": "npm:2.3.6" "@formatjs/intl-localematcher": "npm:0.6.2" decimal.js: "npm:^10.4.3" tslib: "npm:^2.8.0" - checksum: 10c0/2405fd2a4c8ce7a5c25ae824daa1408b07664a4f5ca573683fedad78a487a118b50391b0a2234db921c615e1ed4f53e860a55cd9892708ae49f5766980495b6e + checksum: 10c0/95dd6fb3e9bd84ce44cc194f6f815d690703bd60b75bf2ae895535d2d9a1a675765879de9b54f854882fc1335cbfac6a535873d5b2d75cc5ca93c6ca172aa272 languageName: node linkType: hard -"@formatjs/intl@npm:3.1.7": - version: 3.1.7 - resolution: "@formatjs/intl@npm:3.1.7" +"@formatjs/intl@npm:3.1.8": + version: 3.1.8 + resolution: "@formatjs/intl@npm:3.1.8" dependencies: - "@formatjs/ecma402-abstract": "npm:2.3.5" + "@formatjs/ecma402-abstract": "npm:2.3.6" "@formatjs/fast-memoize": "npm:2.2.7" - "@formatjs/icu-messageformat-parser": "npm:2.11.3" - intl-messageformat: "npm:10.7.17" + "@formatjs/icu-messageformat-parser": "npm:2.11.4" + intl-messageformat: "npm:10.7.18" tslib: "npm:^2.8.0" peerDependencies: - typescript: 5.8.3 + typescript: ^5.6.0 peerDependenciesMeta: typescript: optional: true - checksum: 10c0/52d800f587ed11407879f44b971a498844f116d966f9348ef1b597b7a4ee91f8023e0270797961be8126989512859f5944c4115e39675f4959a22b7837b62e77 + checksum: 10c0/b291e867bcde491737f70254ec30898e120f36784b5ee2911dcc271fbd744e90382f03232ac7f5a55d46071f4ffccfc84b63445734117b75ca1ced659f6b7827 languageName: node linkType: hard @@ -2528,22 +2528,22 @@ __metadata: languageName: node linkType: hard -"@formatjs/ts-transformer@npm:3.14.1": - version: 3.14.1 - resolution: "@formatjs/ts-transformer@npm:3.14.1" +"@formatjs/ts-transformer@npm:3.14.2": + version: 3.14.2 + resolution: "@formatjs/ts-transformer@npm:3.14.2" dependencies: - "@formatjs/icu-messageformat-parser": "npm:2.11.3" + "@formatjs/icu-messageformat-parser": "npm:2.11.4" "@types/node": "npm:^22.0.0" chalk: "npm:^4.1.2" json-stable-stringify: "npm:^1.3.0" tslib: "npm:^2.8.0" - typescript: "npm:5.8.3" + typescript: "npm:^5.6.0" peerDependencies: ts-jest: ^29 peerDependenciesMeta: ts-jest: optional: true - checksum: 10c0/ed412d70fb0b8a57b74f1453e2605481295fda71ba462f4c65fab3d1a7f5a0c51c70fa78b9e9e2b291917eb63bbc5cffc7df27f04645832ae64e881e1327a11c + checksum: 10c0/990cf49cdc318e37825ec26b1b24d7368e89c5d03184867a4accd8b35d6d6d99a20a8abe6366c9870e56da9e04f4672990ca428686306c9ad8204b401c7d19f8 languageName: node linkType: hard @@ -5467,21 +5467,21 @@ __metadata: linkType: hard "babel-plugin-formatjs@npm:^10.5.37": - version: 10.5.40 - resolution: "babel-plugin-formatjs@npm:10.5.40" + version: 10.5.41 + resolution: "babel-plugin-formatjs@npm:10.5.41" dependencies: "@babel/core": "npm:^7.26.10" "@babel/helper-plugin-utils": "npm:^7.26.5" "@babel/plugin-syntax-jsx": "npm:^7.25.9" "@babel/traverse": "npm:^7.26.10" "@babel/types": "npm:^7.26.10" - "@formatjs/icu-messageformat-parser": "npm:2.11.3" - "@formatjs/ts-transformer": "npm:3.14.1" + "@formatjs/icu-messageformat-parser": "npm:2.11.4" + "@formatjs/ts-transformer": "npm:3.14.2" "@types/babel__core": "npm:^7.20.5" "@types/babel__helper-plugin-utils": "npm:^7.10.3" "@types/babel__traverse": "npm:^7.20.6" tslib: "npm:^2.8.0" - checksum: 10c0/b065cc92ae70dd237bc2aa151f52f91f06337b2ad268d9332cf257414da528f8376aabe7019f9ff630abf55c1b409ecbac720a6ea163397179133b244982320e + checksum: 10c0/bbe0e182185c72e4136a4cf37b2366952ad5b1d090de00a132757d2a65a5a6aef95ada93dffdc4ed0cf4338a0ff29c5a0d025d77e8b774b088c69bd68ac07ca6 languageName: node linkType: hard @@ -8379,15 +8379,15 @@ __metadata: languageName: node linkType: hard -"intl-messageformat@npm:10.7.17, intl-messageformat@npm:^10.7.16": - version: 10.7.17 - resolution: "intl-messageformat@npm:10.7.17" +"intl-messageformat@npm:10.7.18, intl-messageformat@npm:^10.7.16": + version: 10.7.18 + resolution: "intl-messageformat@npm:10.7.18" dependencies: - "@formatjs/ecma402-abstract": "npm:2.3.5" + "@formatjs/ecma402-abstract": "npm:2.3.6" "@formatjs/fast-memoize": "npm:2.2.7" - "@formatjs/icu-messageformat-parser": "npm:2.11.3" + "@formatjs/icu-messageformat-parser": "npm:2.11.4" tslib: "npm:^2.8.0" - checksum: 10c0/74445987da233cd5a6df0e4d35813ff11483b0788ff5cbbcf9e2a07c276cdd18001a3ba68583bf8d28920494b68a2be91a9c9f796062973dec3c95a4e88ffa81 + checksum: 10c0/d54da9987335cb2bca26246304cea2ca6b1cb44ca416d6b28f3aa62b11477c72f7ce0bf3f11f5d236ceb1842bdc3378a926e606496d146fde18783ec92c314e1 languageName: node linkType: hard @@ -11203,16 +11203,16 @@ __metadata: linkType: hard "react-intl@npm:^7.1.10": - version: 7.1.13 - resolution: "react-intl@npm:7.1.13" + version: 7.1.14 + resolution: "react-intl@npm:7.1.14" dependencies: - "@formatjs/ecma402-abstract": "npm:2.3.5" - "@formatjs/icu-messageformat-parser": "npm:2.11.3" - "@formatjs/intl": "npm:3.1.7" + "@formatjs/ecma402-abstract": "npm:2.3.6" + "@formatjs/icu-messageformat-parser": "npm:2.11.4" + "@formatjs/intl": "npm:3.1.8" "@types/hoist-non-react-statics": "npm:^3.3.1" "@types/react": "npm:16 || 17 || 18 || 19" hoist-non-react-statics: "npm:^3.3.2" - intl-messageformat: "npm:10.7.17" + intl-messageformat: "npm:10.7.18" tslib: "npm:^2.8.0" peerDependencies: react: 16 || 17 || 18 || 19 @@ -11220,7 +11220,7 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10c0/2288c63c3eb2b3fdb79af5fa7b0d297469cc2530143fec798d4603d713c2caf28c9cc1e3a0a53c7b0f90331a3b672ae18e0edefd2fe816de90f90daa7612fb41 + checksum: 10c0/b4361427ea05b4c9e7d87635a323854ca871710e01cd2a46b5da70b34b78a50661c04b2065258f3f49be134ca414c429c804bc34edc277784a9ffa0c04a30b04 languageName: node linkType: hard @@ -13496,16 +13496,6 @@ __metadata: languageName: node linkType: hard -"typescript@npm:5.8.3": - version: 5.8.3 - resolution: "typescript@npm:5.8.3" - bin: - tsc: bin/tsc - tsserver: bin/tsserver - checksum: 10c0/5f8bb01196e542e64d44db3d16ee0e4063ce4f3e3966df6005f2588e86d91c03e1fb131c2581baf0fb65ee79669eea6e161cd448178986587e9f6844446dbb48 - languageName: node - linkType: hard - "typescript@npm:^5.6.0, typescript@npm:~5.9.0": version: 5.9.2 resolution: "typescript@npm:5.9.2" @@ -13516,16 +13506,6 @@ __metadata: languageName: node linkType: hard -"typescript@patch:typescript@npm%3A5.8.3#optional!builtin": - version: 5.8.3 - resolution: "typescript@patch:typescript@npm%3A5.8.3#optional!builtin::version=5.8.3&hash=5786d5" - bin: - tsc: bin/tsc - tsserver: bin/tsserver - checksum: 10c0/39117e346ff8ebd87ae1510b3a77d5d92dae5a89bde588c747d25da5c146603a99c8ee588c7ef80faaf123d89ed46f6dbd918d534d641083177d5fac38b8a1cb - languageName: node - linkType: hard - "typescript@patch:typescript@npm%3A^5.6.0#optional!builtin, typescript@patch:typescript@npm%3A~5.9.0#optional!builtin": version: 5.9.2 resolution: "typescript@patch:typescript@npm%3A5.9.2#optional!builtin::version=5.9.2&hash=5786d5" From 355050842177128f53274a5718e9069a309a59f3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 15 Oct 2025 09:55:10 +0200 Subject: [PATCH 171/853] Update dependency core-js to v3.46.0 (#36417) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index b6a203bb746606..2c6848c9d97485 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6109,9 +6109,9 @@ __metadata: linkType: hard "core-js@npm:^3.30.2, core-js@npm:^3.45.0": - version: 3.45.1 - resolution: "core-js@npm:3.45.1" - checksum: 10c0/c38e5fae5a05ee3a129c45e10056aafe61dbb15fd35d27e0c289f5490387541c89741185e0aeb61acb558559c6697e016c245cca738fa169a73f2b06cd30e6b6 + version: 3.46.0 + resolution: "core-js@npm:3.46.0" + checksum: 10c0/12d559d39a58227881bc6c86c36d24dcfbe2d56e52dac42e35e8643278172596ab67f57ede98baf40b153ca1b830f37420ea32c3f7417c0c5a1fed46438ae187 languageName: node linkType: hard From d0d1fcd0340839c6e94e45a381a2b56e8e777514 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 15 Oct 2025 07:56:45 +0000 Subject: [PATCH 172/853] Update opentelemetry-ruby (non-major) (#36477) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile | 2 +- Gemfile.lock | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Gemfile b/Gemfile index aa201d1e72b75b..a12e716920071c 100644 --- a/Gemfile +++ b/Gemfile @@ -105,7 +105,7 @@ gem 'prometheus_exporter', '~> 2.2', require: false gem 'opentelemetry-api', '~> 1.7.0' group :opentelemetry do - gem 'opentelemetry-exporter-otlp', '~> 0.30.0', require: false + gem 'opentelemetry-exporter-otlp', '~> 0.31.0', require: false gem 'opentelemetry-instrumentation-active_job', '~> 0.9.0', require: false gem 'opentelemetry-instrumentation-active_model_serializers', '~> 0.23.0', require: false gem 'opentelemetry-instrumentation-concurrent_ruby', '~> 0.23.0', require: false diff --git a/Gemfile.lock b/Gemfile.lock index 1d63e0d955cf2c..991cdf1549a32f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -121,7 +121,7 @@ GEM erubi (>= 1.0.0) rack (>= 0.9.0) rouge (>= 1.0.0) - bigdecimal (3.2.3) + bigdecimal (3.3.1) bindata (2.5.1) binding_of_caller (1.0.1) debug_inspector (>= 1.2.0) @@ -277,7 +277,7 @@ GEM google-protobuf (4.32.1) bigdecimal rake (>= 13) - googleapis-common-protos-types (1.21.0) + googleapis-common-protos-types (1.22.0) google-protobuf (~> 4.26) haml (6.3.0) temple (>= 0.8.2) @@ -502,9 +502,9 @@ GEM openssl-signature_algorithm (1.3.0) openssl (> 2.0) opentelemetry-api (1.7.0) - opentelemetry-common (0.22.0) + opentelemetry-common (0.23.0) opentelemetry-api (~> 1.0) - opentelemetry-exporter-otlp (0.30.0) + opentelemetry-exporter-otlp (0.31.0) google-protobuf (>= 3.18) googleapis-common-protos-types (~> 1.3) opentelemetry-api (~> 1.1) @@ -568,7 +568,7 @@ GEM opentelemetry-instrumentation-base (~> 0.24) opentelemetry-registry (0.4.0) opentelemetry-api (~> 1.1) - opentelemetry-sdk (1.9.0) + opentelemetry-sdk (1.10.0) opentelemetry-api (~> 1.1) opentelemetry-common (~> 0.20) opentelemetry-registry (~> 0.2) @@ -1008,7 +1008,7 @@ DEPENDENCIES omniauth-saml (~> 2.0) omniauth_openid_connect (~> 0.8.0) opentelemetry-api (~> 1.7.0) - opentelemetry-exporter-otlp (~> 0.30.0) + opentelemetry-exporter-otlp (~> 0.31.0) opentelemetry-instrumentation-active_job (~> 0.9.0) opentelemetry-instrumentation-active_model_serializers (~> 0.23.0) opentelemetry-instrumentation-concurrent_ruby (~> 0.23.0) From 339673d533822f5f3274cf76053edd1a6e8f46a8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 15 Oct 2025 10:54:47 +0200 Subject: [PATCH 173/853] New Crowdin Translations (automated) (#36476) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/be.json | 1 + app/javascript/mastodon/locales/cs.json | 1 + app/javascript/mastodon/locales/da.json | 1 + app/javascript/mastodon/locales/de.json | 1 + app/javascript/mastodon/locales/el.json | 3 ++- app/javascript/mastodon/locales/es-AR.json | 1 + app/javascript/mastodon/locales/es-MX.json | 1 + app/javascript/mastodon/locales/es.json | 1 + app/javascript/mastodon/locales/fi.json | 1 + app/javascript/mastodon/locales/fo.json | 1 + app/javascript/mastodon/locales/gl.json | 1 + app/javascript/mastodon/locales/he.json | 1 + app/javascript/mastodon/locales/hu.json | 1 + app/javascript/mastodon/locales/nl.json | 1 + app/javascript/mastodon/locales/sq.json | 1 + app/javascript/mastodon/locales/tr.json | 1 + app/javascript/mastodon/locales/zh-CN.json | 1 + app/javascript/mastodon/locales/zh-TW.json | 1 + config/locales/cs.yml | 10 ++++++++++ config/locales/hu.yml | 10 ++++++++++ config/locales/tr.yml | 7 +++++++ 21 files changed, 46 insertions(+), 1 deletion(-) diff --git a/app/javascript/mastodon/locales/be.json b/app/javascript/mastodon/locales/be.json index dc02cf731a945b..0a7b3c805e6996 100644 --- a/app/javascript/mastodon/locales/be.json +++ b/app/javascript/mastodon/locales/be.json @@ -753,6 +753,7 @@ "privacy.unlisted.short": "Ціхі публічны", "privacy_policy.last_updated": "Адноўлена {date}", "privacy_policy.title": "Палітыка канфідэнцыйнасці", + "quote_error.edit": "Нельга дадаваць цытаты пры рэдагаванні допісаў.", "quote_error.poll": "Нельга цытаваць з апытаннямі.", "quote_error.quote": "За раз дазволена рабіць толькі адну цытату.", "quote_error.unauthorized": "Вы не ўвайшлі, каб цытаваць гэты допіс.", diff --git a/app/javascript/mastodon/locales/cs.json b/app/javascript/mastodon/locales/cs.json index 3ba60cb04c3a00..b9f7d0bdfb5bdc 100644 --- a/app/javascript/mastodon/locales/cs.json +++ b/app/javascript/mastodon/locales/cs.json @@ -753,6 +753,7 @@ "privacy.unlisted.short": "Ztišené veřejné", "privacy_policy.last_updated": "Naposledy aktualizováno {date}", "privacy_policy.title": "Zásady ochrany osobních údajů", + "quote_error.edit": "Citáty nemohou být přidány při úpravě příspěvku.", "quote_error.poll": "Citování není u dotazníků povoleno.", "quote_error.quote": "Je povoleno citovat pouze jednou.", "quote_error.unauthorized": "Nemáte oprávnění citovat tento příspěvek.", diff --git a/app/javascript/mastodon/locales/da.json b/app/javascript/mastodon/locales/da.json index 255b41e871aac8..c36da1a614e034 100644 --- a/app/javascript/mastodon/locales/da.json +++ b/app/javascript/mastodon/locales/da.json @@ -753,6 +753,7 @@ "privacy.unlisted.short": "Offentlig (stille)", "privacy_policy.last_updated": "Senest opdateret {date}", "privacy_policy.title": "Privatlivspolitik", + "quote_error.edit": "Citater kan ikke tilføjes ved redigering af et indlæg.", "quote_error.poll": "Citering ikke tilladt i afstemninger.", "quote_error.quote": "Kun ét citat ad gangen er tilladt.", "quote_error.unauthorized": "Du har ikke tilladelse til at citere dette indlæg.", diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json index c1d848ee079a4c..b7d52e4e501d6c 100644 --- a/app/javascript/mastodon/locales/de.json +++ b/app/javascript/mastodon/locales/de.json @@ -753,6 +753,7 @@ "privacy.unlisted.short": "Öffentlich (still)", "privacy_policy.last_updated": "Stand: {date}", "privacy_policy.title": "Datenschutzerklärung", + "quote_error.edit": "Beim Bearbeiten eines Beitrags können keine Zitate hinzugefügt werden.", "quote_error.poll": "Zitieren ist bei Umfragen nicht gestattet.", "quote_error.quote": "Es ist jeweils nur ein Zitat zulässig.", "quote_error.unauthorized": "Du bist nicht berechtigt, diesen Beitrag zu zitieren.", diff --git a/app/javascript/mastodon/locales/el.json b/app/javascript/mastodon/locales/el.json index 5c94e6d858ae84..400171aeb0ad73 100644 --- a/app/javascript/mastodon/locales/el.json +++ b/app/javascript/mastodon/locales/el.json @@ -739,7 +739,7 @@ "poll_button.add_poll": "Προσθήκη δημοσκόπησης", "poll_button.remove_poll": "Αφαίρεση δημοσκόπησης", "privacy.change": "Προσαρμογή ιδιωτικότητας ανάρτησης", - "privacy.direct.long": "Όλοι όσοι αναφέρθηκαν στην ανάρτηση", + "privacy.direct.long": "Όλοι όσοι επισημάνθηκαν στην ανάρτηση", "privacy.direct.short": "Ιδιωτική επισήμανση", "privacy.private.long": "Μόνο οι ακόλουθοί σας", "privacy.private.short": "Ακόλουθοι", @@ -753,6 +753,7 @@ "privacy.unlisted.short": "Ήσυχα δημόσια", "privacy_policy.last_updated": "Τελευταία ενημέρωση {date}", "privacy_policy.title": "Πολιτική Απορρήτου", + "quote_error.edit": "Δεν μπορούν να προστεθούν παραθέσεις κατά την επεξεργασία μιας ανάρτησης.", "quote_error.poll": "Η παράθεση δεν επιτρέπεται με δημοσκοπήσεις.", "quote_error.quote": "Επιτρέπεται μόνο μία παράθεση τη φορά.", "quote_error.unauthorized": "Δεν είστε εξουσιοδοτημένοι να παραθέσετε αυτή την ανάρτηση.", diff --git a/app/javascript/mastodon/locales/es-AR.json b/app/javascript/mastodon/locales/es-AR.json index cb6ba17612b8f4..d9b5bdaec58b62 100644 --- a/app/javascript/mastodon/locales/es-AR.json +++ b/app/javascript/mastodon/locales/es-AR.json @@ -753,6 +753,7 @@ "privacy.unlisted.short": "Público silencioso", "privacy_policy.last_updated": "Última actualización: {date}", "privacy_policy.title": "Política de privacidad", + "quote_error.edit": "Las citas no se pueden agregar al editar un mensaje.", "quote_error.poll": "No se permite citar encuestas.", "quote_error.quote": "Solo se permite una cita a la vez.", "quote_error.unauthorized": "No tenés autorización para citar este mensaje.", diff --git a/app/javascript/mastodon/locales/es-MX.json b/app/javascript/mastodon/locales/es-MX.json index 59b0b68c88043c..a523b32867b7fa 100644 --- a/app/javascript/mastodon/locales/es-MX.json +++ b/app/javascript/mastodon/locales/es-MX.json @@ -753,6 +753,7 @@ "privacy.unlisted.short": "Pública, pero discreta", "privacy_policy.last_updated": "Actualizado por última vez {date}", "privacy_policy.title": "Política de Privacidad", + "quote_error.edit": "No se pueden añadir citas mientras se edita una publicación.", "quote_error.poll": "No se permite citar encuestas.", "quote_error.quote": "Solo se permite una cita a la vez.", "quote_error.unauthorized": "No estás autorizado a citar esta publicación.", diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json index 9985cdea1e4f85..96ae78574302af 100644 --- a/app/javascript/mastodon/locales/es.json +++ b/app/javascript/mastodon/locales/es.json @@ -753,6 +753,7 @@ "privacy.unlisted.short": "Pública silenciosa", "privacy_policy.last_updated": "Actualizado por última vez {date}", "privacy_policy.title": "Política de Privacidad", + "quote_error.edit": "No se pueden añadir citas mientras se edita una publicación.", "quote_error.poll": "No es posible citar encuestas.", "quote_error.quote": "Solo se permite una cita a la vez.", "quote_error.unauthorized": "No tienes permiso para citar esta publicación.", diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json index 4cdcece7fe3206..ca38be95131cdf 100644 --- a/app/javascript/mastodon/locales/fi.json +++ b/app/javascript/mastodon/locales/fi.json @@ -753,6 +753,7 @@ "privacy.unlisted.short": "Vaivihkaa julkinen", "privacy_policy.last_updated": "Päivitetty viimeksi {date}", "privacy_policy.title": "Tietosuojakäytäntö", + "quote_error.edit": "Lainauksia ei voi lisätä julkaisua muokattaessa.", "quote_error.poll": "Äänestysten lainaaminen ei ole sallittua.", "quote_error.quote": "Vain yksi lainaus kerrallaan on sallittu.", "quote_error.unauthorized": "Sinulla ei ole valtuuksia lainata tätä julkaisua.", diff --git a/app/javascript/mastodon/locales/fo.json b/app/javascript/mastodon/locales/fo.json index a83cd427632f3b..55a3d2455b8809 100644 --- a/app/javascript/mastodon/locales/fo.json +++ b/app/javascript/mastodon/locales/fo.json @@ -753,6 +753,7 @@ "privacy.unlisted.short": "Stillur almenningur", "privacy_policy.last_updated": "Seinast dagført {date}", "privacy_policy.title": "Privatlívspolitikkur", + "quote_error.edit": "Sitatir kunnu ikki leggjast afturat tá tú rættar ein post.", "quote_error.poll": "Tað er ikki loyvt at sitera spurnarkanningar.", "quote_error.quote": "Bara ein sitering er loyvd í senn.", "quote_error.unauthorized": "Tú hevur ikki rættindi at sitera hendan postin.", diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json index 8ba7a73abe31fb..0cec616ff0489b 100644 --- a/app/javascript/mastodon/locales/gl.json +++ b/app/javascript/mastodon/locales/gl.json @@ -753,6 +753,7 @@ "privacy.unlisted.short": "Pública limitada", "privacy_policy.last_updated": "Actualizado por última vez no {date}", "privacy_policy.title": "Política de Privacidade", + "quote_error.edit": "Non se poden engadir citas ao editar unha publicación.", "quote_error.poll": "Non se permite citar as enquisas.", "quote_error.quote": "Só se permite citar unha vez.", "quote_error.unauthorized": "Non tes permiso para citar esta publicación.", diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json index 61e8cb2e5f5d51..9e7a90cab1fdc5 100644 --- a/app/javascript/mastodon/locales/he.json +++ b/app/javascript/mastodon/locales/he.json @@ -753,6 +753,7 @@ "privacy.unlisted.short": "ציבורי שקט", "privacy_policy.last_updated": "עודכן לאחרונה {date}", "privacy_policy.title": "מדיניות פרטיות", + "quote_error.edit": "לא ניתן להוסיף ציטוטים בשלב עריכת ההודעה.", "quote_error.poll": "לא ניתן לכלול משאל כאשר מחברים הודעת ציטוט.", "quote_error.quote": "רק ציטוט אחד מותר בכל הודעה.", "quote_error.unauthorized": "אין לך הרשאה לצטט את ההודעה הזו.", diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json index 1d1d824a45a171..5cc41a13404434 100644 --- a/app/javascript/mastodon/locales/hu.json +++ b/app/javascript/mastodon/locales/hu.json @@ -753,6 +753,7 @@ "privacy.unlisted.short": "Csendes nyilvános", "privacy_policy.last_updated": "Utoljára frissítve: {date}", "privacy_policy.title": "Adatvédelmi szabályzat", + "quote_error.edit": "Idézés nem adható hozzá bejegyzés szerkesztésekor.", "quote_error.poll": "Az idézés szavazások esetén nincs engedélyezve.", "quote_error.quote": "Egyszerre csak egy idézet van engedélyezve.", "quote_error.unauthorized": "Nem idézheted ezt a bejegyzést.", diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json index ecf8f46f756a02..12ffbec03df0fb 100644 --- a/app/javascript/mastodon/locales/nl.json +++ b/app/javascript/mastodon/locales/nl.json @@ -753,6 +753,7 @@ "privacy.unlisted.short": "Minder openbaar", "privacy_policy.last_updated": "Laatst bijgewerkt op {date}", "privacy_policy.title": "Privacybeleid", + "quote_error.edit": "Citaten kunnen niet tijdens het bewerken van een bericht worden toegevoegd.", "quote_error.poll": "Het is niet mogelijk om polls te citeren.", "quote_error.quote": "Je kunt maar één bericht per keer citeren.", "quote_error.unauthorized": "Je bent niet gemachtigd om dit bericht te citeren.", diff --git a/app/javascript/mastodon/locales/sq.json b/app/javascript/mastodon/locales/sq.json index 8e76cd8fe05bb9..6f6d96509dfbe3 100644 --- a/app/javascript/mastodon/locales/sq.json +++ b/app/javascript/mastodon/locales/sq.json @@ -749,6 +749,7 @@ "privacy.unlisted.short": "Publik i qetë", "privacy_policy.last_updated": "Përditësuar së fundi më {date}", "privacy_policy.title": "Rregulla Privatësie", + "quote_error.edit": "Kur përpunohet një postim, s’mund të shtohen citime.", "quote_error.poll": "Me pyetësorët nuk lejohet citim.", "quote_error.quote": "Lejohet vetëm një citim në herë.", "quote_error.unauthorized": "S’jen i autorizuar ta citoni këtë postim.", diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json index 6301c8b7dab829..19b37b569b7a6a 100644 --- a/app/javascript/mastodon/locales/tr.json +++ b/app/javascript/mastodon/locales/tr.json @@ -753,6 +753,7 @@ "privacy.unlisted.short": "Sessizce herkese açık", "privacy_policy.last_updated": "Son güncelleme {date}", "privacy_policy.title": "Gizlilik Politikası", + "quote_error.edit": "Gönderi düzenlenirken alıntılar eklenemez.", "quote_error.poll": "Anketlerde alıntıya izin verilmez.", "quote_error.quote": "Bir seferde tek bir alıntıya izin var.", "quote_error.unauthorized": "Bu gönderiyi alıntılamaya yetkiniz yok.", diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json index 87fe47d7771f64..052dfdcfd07868 100644 --- a/app/javascript/mastodon/locales/zh-CN.json +++ b/app/javascript/mastodon/locales/zh-CN.json @@ -753,6 +753,7 @@ "privacy.unlisted.short": "悄悄公开", "privacy_policy.last_updated": "最近更新于 {date}", "privacy_policy.title": "隐私政策", + "quote_error.edit": "编辑嘟文时无法添加引用。", "quote_error.poll": "不允许引用投票嘟文。", "quote_error.quote": "一次只能引用一条嘟文。", "quote_error.unauthorized": "你没有权限引用此嘟文。", diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json index 20f94573d7c731..81cb45fd3bf2e5 100644 --- a/app/javascript/mastodon/locales/zh-TW.json +++ b/app/javascript/mastodon/locales/zh-TW.json @@ -753,6 +753,7 @@ "privacy.unlisted.short": "不公開", "privacy_policy.last_updated": "最後更新:{date}", "privacy_policy.title": "隱私權政策", + "quote_error.edit": "編輯嘟文時無法新增引用嘟文。", "quote_error.poll": "無法引用投票嘟文。", "quote_error.quote": "一次僅能引用一則嘟文。", "quote_error.unauthorized": "您不被授權允許引用此嘟文。", diff --git a/config/locales/cs.yml b/config/locales/cs.yml index 8b21cfb2ebeb49..926151f09501fd 100644 --- a/config/locales/cs.yml +++ b/config/locales/cs.yml @@ -1669,6 +1669,13 @@ cs: expires_at: Vyprší uses: Použití title: Pozvat lidi + link_preview: + author_html: Podle %{name} + potentially_sensitive_content: + action: Kliknutím zobrazíte + confirm_visit: Opravdu chcete otevřít tento odkaz? + hide_button: Skrýt + label: Potenciálně citlivý obsah lists: errors: limit: Dosáhl jste maximálního počtu seznamů @@ -1985,6 +1992,9 @@ cs: other: "%{count} videí" boosted_from_html: Boostnuto z %{acct_link} content_warning: 'Varování o obsahu: %{warning}' + content_warnings: + hide: Skrýt příspěvek + show: Zobrazit více default_language: Stejný jako jazyk rozhraní disallowed_hashtags: few: 'obsahoval zakázané hashtagy: %{tags}' diff --git a/config/locales/hu.yml b/config/locales/hu.yml index 2b57ef5516132b..e85f476e4dc270 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -1591,6 +1591,13 @@ hu: expires_at: Lejárat uses: Használat title: Meghívások + link_preview: + author_html: 'Szerző: %{name}' + potentially_sensitive_content: + action: Kattints a megjelenítéshez + confirm_visit: Biztos, hogy megnyitod ezt a hivatkozást? + hide_button: Elrejtés + label: Lehet, hogy kényes tartalom lists: errors: limit: Elérted a listák maximális számát @@ -1901,6 +1908,9 @@ hu: other: "%{count} videó" boosted_from_html: Megtolva innen %{acct_link} content_warning: 'Tartalmi figyelmeztetés: %{warning}' + content_warnings: + hide: Bejegyzés elrejtése + show: Több megjelenítése default_language: Felhasználói felület nyelvével azonos disallowed_hashtags: one: 'tiltott hashtaget tartalmaz: %{tags}' diff --git a/config/locales/tr.yml b/config/locales/tr.yml index f07a66d327e586..6b53a1d191f53c 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -1591,6 +1591,13 @@ tr: expires_at: Bitiş tarihi uses: Kullanım title: İnsanları davet et + link_preview: + author_html: 'Yazan: %{name}' + potentially_sensitive_content: + action: Göstermek için tıklayın + confirm_visit: Bu bağlantıyı açmak istediğinizden emin misiniz? + hide_button: Gizle + label: Potansiyel olarak hassas içerik lists: errors: limit: Azami liste sayısına ulaştınız From d8bdce2835e024b7fca4c4db661bec2bcd067f53 Mon Sep 17 00:00:00 2001 From: Emelia Smith Date: Wed, 15 Oct 2025 11:05:10 +0200 Subject: [PATCH 174/853] Fix rendering of poll options in status history modal (#35633) --- .../ui/components/compare_history_modal.jsx | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/app/javascript/mastodon/features/ui/components/compare_history_modal.jsx b/app/javascript/mastodon/features/ui/components/compare_history_modal.jsx index c9a58265660ca6..f260444265d27d 100644 --- a/app/javascript/mastodon/features/ui/components/compare_history_modal.jsx +++ b/app/javascript/mastodon/features/ui/components/compare_history_modal.jsx @@ -93,14 +93,16 @@ class CompareHistoryModal extends PureComponent {
    {currentVersion.getIn(['poll', 'options']).map(option => (
  • - - - +
  • ))}
From 3160f5746de0c81d6464df30bc4a0435fd3d8d01 Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 15 Oct 2025 11:11:03 +0200 Subject: [PATCH 175/853] Bump version to v4.4.7 (#36478) --- CHANGELOG.md | 8 ++++++++ docker-compose.yml | 6 +++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 249596dc055f5d..ffda7eb6c7bbc9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ All notable changes to this project will be documented in this file. +## [4.4.7] - 2025-10-15 + +### Fixed + +- Fix forwarder being called with `nil` status when quote post is soft-deleted (#36463 by @ClearlyClaire) +- Fix moderation warning e-mails that include posts (#36462 by @ClearlyClaire) +- Fix allow_referrer_origin typo (#36460 by @ShadowJonathan) + ## [4.4.6] - 2025-10-13 ### Security diff --git a/docker-compose.yml b/docker-compose.yml index 38c7fd836095af..a2264b65d37618 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -59,7 +59,7 @@ services: web: # You can uncomment the following line if you want to not use the prebuilt image, for example if you have local code changes # build: . - image: ghcr.io/mastodon/mastodon:v4.4.6 + image: ghcr.io/mastodon/mastodon:v4.4.7 restart: always env_file: .env.production command: bundle exec puma -C config/puma.rb @@ -83,7 +83,7 @@ services: # build: # dockerfile: ./streaming/Dockerfile # context: . - image: ghcr.io/mastodon/mastodon-streaming:v4.4.6 + image: ghcr.io/mastodon/mastodon-streaming:v4.4.7 restart: always env_file: .env.production command: node ./streaming/index.js @@ -102,7 +102,7 @@ services: sidekiq: # You can uncomment the following line if you want to not use the prebuilt image, for example if you have local code changes # build: . - image: ghcr.io/mastodon/mastodon:v4.4.6 + image: ghcr.io/mastodon/mastodon:v4.4.7 restart: always env_file: .env.production command: bundle exec sidekiq From c6de46d12d80d867cffc1a060ba9f2950c2acfee Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 15 Oct 2025 07:30:09 -0400 Subject: [PATCH 176/853] Update `stylelint-config-standard-scss` to version 16.0.0 (#36429) Co-authored-by: diondiondion --- app/javascript/styles/mastodon/admin.scss | 14 ++--- .../styles/mastodon/components.scss | 16 +++-- app/javascript/styles/mastodon/dashboard.scss | 2 +- .../styles/mastodon/emoji_picker.scss | 2 +- app/javascript/styles/mastodon/forms.scss | 2 +- app/javascript/styles/mastodon/polls.scss | 1 - package.json | 2 +- yarn.lock | 60 +++++++++---------- 8 files changed, 48 insertions(+), 51 deletions(-) diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss index 2e05284e2828f5..5f82db933b8e2a 100644 --- a/app/javascript/styles/mastodon/admin.scss +++ b/app/javascript/styles/mastodon/admin.scss @@ -696,7 +696,7 @@ body, } &__title { - word-wrap: break-word; + overflow-wrap: break-word; } &__timestamp { @@ -747,7 +747,7 @@ body, } &__title { - word-wrap: break-word; + overflow-wrap: break-word; } &__timestamp { @@ -1397,7 +1397,7 @@ a.sparkline { .report-header { display: grid; - grid-gap: 15px; + gap: 15px; grid-template-columns: minmax(0, 1fr) 300px; &__details { @@ -1507,7 +1507,7 @@ a.sparkline { margin: 8px 0; overflow: hidden; text-overflow: ellipsis; - word-wrap: break-word; + overflow-wrap: break-word; max-height: 21px * 2; position: relative; font-size: 15px; @@ -1664,7 +1664,7 @@ a.sparkline { &__content { font-size: 15px; line-height: 20px; - word-wrap: break-word; + overflow-wrap: break-word; font-weight: 400; color: $primary-text-color; @@ -1766,7 +1766,7 @@ a.sparkline { padding: 15px; font-size: 15px; line-height: 20px; - word-wrap: break-word; + overflow-wrap: break-word; font-weight: 400; color: $primary-text-color; box-sizing: border-box; @@ -1948,7 +1948,7 @@ a.sparkline { border-radius: 4px; font-size: 15px; line-height: 20px; - word-wrap: break-word; + overflow-wrap: break-word; font-weight: 400; border: 1px solid lighten($ui-base-color, 4%); color: $primary-text-color; diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index ee54cd71ad58b6..65ed88dca92a82 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -1122,7 +1122,7 @@ .edit-indicator__content, .reply-indicator__content { position: relative; - word-wrap: break-word; + overflow-wrap: break-word; font-weight: 400; overflow: hidden; text-overflow: ellipsis; @@ -1363,7 +1363,7 @@ } .announcements__item__content { - word-wrap: break-word; + overflow-wrap: break-word; overflow-y: auto; .emojione { @@ -3968,7 +3968,7 @@ a.account__display-name { .react-toggle-screenreader-only, .sr-only { border: 0; - clip: rect(0 0 0 0); + clip-path: inset(50%); height: 1px; margin: -1px; overflow: hidden; @@ -5177,10 +5177,8 @@ a.status-card { &__menu { @include search-popout; - & { - padding: 0; - background: $ui-secondary-color; - } + padding: 0; + background: $ui-secondary-color; } &__menu-list { @@ -8322,7 +8320,7 @@ noscript { font-weight: 400; overflow: hidden; word-break: normal; - word-wrap: break-word; + overflow-wrap: break-word; p { margin-bottom: 20px; @@ -8966,7 +8964,7 @@ noscript { position: relative; font-size: 15px; line-height: 20px; - word-wrap: break-word; + overflow-wrap: break-word; font-weight: 400; max-height: 50vh; overflow: hidden; diff --git a/app/javascript/styles/mastodon/dashboard.scss b/app/javascript/styles/mastodon/dashboard.scss index c99cdc357af19e..8326022f71ab9e 100644 --- a/app/javascript/styles/mastodon/dashboard.scss +++ b/app/javascript/styles/mastodon/dashboard.scss @@ -61,7 +61,7 @@ .dashboard { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr); - grid-gap: 10px; + gap: 10px; @media screen and (width <= 1350px) { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); diff --git a/app/javascript/styles/mastodon/emoji_picker.scss b/app/javascript/styles/mastodon/emoji_picker.scss index 1fde5de1dc2f9f..d443b74fe3a173 100644 --- a/app/javascript/styles/mastodon/emoji_picker.scss +++ b/app/javascript/styles/mastodon/emoji_picker.scss @@ -190,7 +190,7 @@ padding: 0; margin: -1px; overflow: hidden; - clip: rect(0, 0, 0, 0); + clip-path: inset(50%); border: 0; } diff --git a/app/javascript/styles/mastodon/forms.scss b/app/javascript/styles/mastodon/forms.scss index b3708b722e3662..650081d1ebb0fe 100644 --- a/app/javascript/styles/mastodon/forms.scss +++ b/app/javascript/styles/mastodon/forms.scss @@ -299,7 +299,7 @@ code { color: $primary-text-color; display: block; margin-bottom: 8px; - word-wrap: break-word; + overflow-wrap: break-word; font-weight: 500; } diff --git a/app/javascript/styles/mastodon/polls.scss b/app/javascript/styles/mastodon/polls.scss index b13c9d613292cf..e8f2f5c39400a9 100644 --- a/app/javascript/styles/mastodon/polls.scss +++ b/app/javascript/styles/mastodon/polls.scss @@ -60,7 +60,6 @@ &__text { display: inline-block; - word-wrap: break-word; overflow-wrap: break-word; max-width: calc(100% - 45px - 25px); } diff --git a/package.json b/package.json index 4596fc421af63a..16095441d87ca2 100644 --- a/package.json +++ b/package.json @@ -189,7 +189,7 @@ "storybook": "^9.1.1", "stylelint": "^16.19.1", "stylelint-config-prettier-scss": "^1.0.0", - "stylelint-config-standard-scss": "^15.0.1", + "stylelint-config-standard-scss": "^16.0.0", "typescript": "~5.9.0", "typescript-eslint": "^8.45.0", "vitest": "^3.2.4" diff --git a/yarn.lock b/yarn.lock index 2c6848c9d97485..69908cafc72aa6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2915,7 +2915,7 @@ __metadata: stringz: "npm:^2.1.0" stylelint: "npm:^16.19.1" stylelint-config-prettier-scss: "npm:^1.0.0" - stylelint-config-standard-scss: "npm:^15.0.1" + stylelint-config-standard-scss: "npm:^16.0.0" substring-trie: "npm:^1.0.2" tesseract.js: "npm:^6.0.0" tiny-queue: "npm:^0.2.1" @@ -12861,62 +12861,62 @@ __metadata: languageName: node linkType: hard -"stylelint-config-recommended-scss@npm:^15.0.1": - version: 15.0.1 - resolution: "stylelint-config-recommended-scss@npm:15.0.1" +"stylelint-config-recommended-scss@npm:^16.0.1": + version: 16.0.2 + resolution: "stylelint-config-recommended-scss@npm:16.0.2" dependencies: postcss-scss: "npm:^4.0.9" - stylelint-config-recommended: "npm:^16.0.0" - stylelint-scss: "npm:^6.12.0" + stylelint-config-recommended: "npm:^17.0.0" + stylelint-scss: "npm:^6.12.1" peerDependencies: postcss: ^8.3.3 - stylelint: ^16.16.0 + stylelint: ^16.24.0 peerDependenciesMeta: postcss: optional: true - checksum: 10c0/8c5854e143145241dbff3d921298eb59e837aa695c0e6d7f08acf75de81f3f8307d39a931781bf8ac7cbe6bf9079a402fee89566206e9cfb1d728ef6b6486890 + checksum: 10c0/d4e30a881e248d8b039347bf967526f6afe6d6a07f18e2747e14568de32273e819ba478be7a61a0dd63178931b4e891050a34e73d296ab533aa434209a7f3146 languageName: node linkType: hard -"stylelint-config-recommended@npm:^16.0.0": - version: 16.0.0 - resolution: "stylelint-config-recommended@npm:16.0.0" +"stylelint-config-recommended@npm:^17.0.0": + version: 17.0.0 + resolution: "stylelint-config-recommended@npm:17.0.0" peerDependencies: - stylelint: ^16.16.0 - checksum: 10c0/b2b4ea2633a606a0f686521aa5e8908810c9dd21fd4525c86b34213de1e362b445fd5472b6e5ff251d46f999e2ca2c6c704f2efc1c08d5a532084427f4e1c9d8 + stylelint: ^16.23.0 + checksum: 10c0/49e5d1c0f58197b2c5585b85fad814fed9bdec44c9870368c46a762664c5ff158c1145b6337456ae194409d692992b5b87421d62880422f71d8a3360417f5ad1 languageName: node linkType: hard -"stylelint-config-standard-scss@npm:^15.0.1": - version: 15.0.1 - resolution: "stylelint-config-standard-scss@npm:15.0.1" +"stylelint-config-standard-scss@npm:^16.0.0": + version: 16.0.0 + resolution: "stylelint-config-standard-scss@npm:16.0.0" dependencies: - stylelint-config-recommended-scss: "npm:^15.0.1" - stylelint-config-standard: "npm:^38.0.0" + stylelint-config-recommended-scss: "npm:^16.0.1" + stylelint-config-standard: "npm:^39.0.0" peerDependencies: postcss: ^8.3.3 - stylelint: ^16.18.0 + stylelint: ^16.23.1 peerDependenciesMeta: postcss: optional: true - checksum: 10c0/85b4c85a9ecd97176ac104fb4590cd48047b6253b830d08749c024752b9bc8871bbf69eca592769d69cd4c6e3f90005960630f1c2cdaf85dbfabdb5621ecc55f + checksum: 10c0/eb77f23824c5d649b193cb71d7f9b538b32b8cc1769451b2993270361127243d4011baf891ec265711b8e34e69ce28acb57ab6c3947b51fa3713ac26f4276439 languageName: node linkType: hard -"stylelint-config-standard@npm:^38.0.0": - version: 38.0.0 - resolution: "stylelint-config-standard@npm:38.0.0" +"stylelint-config-standard@npm:^39.0.0": + version: 39.0.1 + resolution: "stylelint-config-standard@npm:39.0.1" dependencies: - stylelint-config-recommended: "npm:^16.0.0" + stylelint-config-recommended: "npm:^17.0.0" peerDependencies: - stylelint: ^16.18.0 - checksum: 10c0/8b52c7b7d6287c7495a8fe3a681e07ea9478374e7e66b28d61779072d46cd5b845530b2410df7496a008a8efafe834fb46cf07792f4cf57f996e39f24a801b90 + stylelint: ^16.23.0 + checksum: 10c0/70a9862a2cedcc2a1807bd92fc91c40877270cf8a39576b91ae056d6de51d3b68104b26f71056ff22461b4319e9ec988d009abf10ead513b2ec15569d82e865a languageName: node linkType: hard -"stylelint-scss@npm:^6.12.0": - version: 6.12.0 - resolution: "stylelint-scss@npm:6.12.0" +"stylelint-scss@npm:^6.12.1": + version: 6.12.1 + resolution: "stylelint-scss@npm:6.12.1" dependencies: css-tree: "npm:^3.0.1" is-plain-object: "npm:^5.0.0" @@ -12928,7 +12928,7 @@ __metadata: postcss-value-parser: "npm:^4.2.0" peerDependencies: stylelint: ^16.0.2 - checksum: 10c0/c0ba314badd22118047e374febf8dabac56bd351d612ed9c9fc2da5dc760996c2768605aa8d4e483cf0b0fe649c35ae5a003c8a872ee5bec1bbc2d8d45673ff5 + checksum: 10c0/9a0903d34be3c75a72bef32402899db5f6b94c0823c5944fdf1acb2c3dc61c1f70fbb322558f8cb7e42dd01ed5e0dec22ed298f03b7bacc9f467c28330acae71 languageName: node linkType: hard From fab0dd0bcfaee2df88df402d4cf1f1a4423c1fa6 Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 15 Oct 2025 13:37:22 +0200 Subject: [PATCH 177/853] Change redirection for denied registration from web app to sign-in page with error message (#36384) --- app/controllers/auth/registrations_controller.rb | 2 +- config/locales/devise.en.yml | 1 + spec/controllers/auth/registrations_controller_spec.rb | 8 ++++---- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/controllers/auth/registrations_controller.rb b/app/controllers/auth/registrations_controller.rb index fc430544fbef50..780c0be3191cbe 100644 --- a/app/controllers/auth/registrations_controller.rb +++ b/app/controllers/auth/registrations_controller.rb @@ -89,7 +89,7 @@ def after_update_path_for(_resource) end def check_enabled_registrations - redirect_to root_path unless allowed_registration?(request.remote_ip, @invite) + redirect_to new_user_session_path, alert: I18n.t('devise.failure.closed_registrations', email: Setting.site_contact_email) unless allowed_registration?(request.remote_ip, @invite) end def invite_code diff --git a/config/locales/devise.en.yml b/config/locales/devise.en.yml index 65095cd788c54d..29cc473e019d7e 100644 --- a/config/locales/devise.en.yml +++ b/config/locales/devise.en.yml @@ -7,6 +7,7 @@ en: send_paranoid_instructions: If your email address exists in our database, you will receive an email with instructions for how to confirm your email address in a few minutes. Please check your spam folder if you didn't receive this email. failure: already_authenticated: You are already signed in. + closed_registrations: Your registration attempt has been blocked due to a network policy. If you believe this is an error, contact %{email}. inactive: Your account is not activated yet. invalid: Invalid %{authentication_keys} or password. last_attempt: You have one more attempt before your account is locked. diff --git a/spec/controllers/auth/registrations_controller_spec.rb b/spec/controllers/auth/registrations_controller_spec.rb index 04c2d5dbbbbc6d..c7bbe130920fbb 100644 --- a/spec/controllers/auth/registrations_controller_spec.rb +++ b/spec/controllers/auth/registrations_controller_spec.rb @@ -12,11 +12,11 @@ allow(Rails.configuration.x).to receive(:single_user_mode).and_return(true) end - it 'redirects to root' do + it 'redirects to sign-in' do Fabricate(:account) get path - expect(response).to redirect_to '/' + expect(response).to redirect_to '/auth/sign_in' expect(Rails.configuration.x).to have_received(:single_user_mode) end end @@ -27,10 +27,10 @@ allow(Rails.configuration.x).to receive(:single_user_mode).and_return(false) end - it 'redirects to root' do + it 'redirects to sign-in' do get path - expect(response).to redirect_to '/' + expect(response).to redirect_to '/auth/sign_in' expect(Rails.configuration.x).to have_received(:single_user_mode) end end From c5fb080ab8d45804fae110a72a501791ccb5fb47 Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 15 Oct 2025 15:09:25 +0200 Subject: [PATCH 178/853] Bump version to v4.5.0-beta.1 (#36479) --- CHANGELOG.md | 72 +++++++++++++++++++++++++++++++++++++++++ lib/mastodon/version.rb | 2 +- 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ffda7eb6c7bbc9..b7c2eafaf50bcd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,78 @@ All notable changes to this project will be documented in this file. +## [4.5.0] - UNRELEASED + +### Added + +- **Add support for allowing and authoring quotes** (#35355, #35578, #35614, #35618, #35624, #35626, #35652, #35629, #35665, #35653, #35670, #35677, #35690, #35697, #35689, #35699, #35700, #35701, #35709, #35714, #35713, #35715, #35725, #35749, #35769, #35780, #35762, #35804, #35808, #35805, #35819, #35824, #35828, #35822, #35835, #35865, #35860, #35832, #35891, #35894, #35895, #35820, #35917, #35924, #35925, #35914, #35930, #35941, #35939, #35948, #35955, #35967, #35990, #35991, #35975, #35971, #36002, #35986, #36031, #36034, #36038, #36054, #36052, #36055, #36065, #36068, #36083, #36087, #36080, #36091, #36090, #36118, #36119, #36128, #36094, #36129, #36138, #36132, #36151, #36158, #36171, #36194, #36220, #36169, #36130, #36249, #36153, #36299, #36291, #36301, #36315, #36317, #36364, #36383, #36381, #36459, #36464, and #36461 by @ChaosExAnima, @ClearlyClaire, @Lycolia, @diondiondion, and @tribela)\ + This includes a revamp of the composer interface.\ + See https://blog.joinmastodon.org/2025/09/introducing-quote-posts/ for a user-centric overview of the feature, and https://docs.joinmastodon.org/client/quotes/ for API documentation. +- **Add support for fetching and refreshing replies to the web UI** (#35210, #35496, #35575, #35500, #35577, #35602, #35603, #35654, #36141, #36237, #36172, #36256, #36271, #36334, #36382, and #36239 by @ClearlyClaire, @Gargron, and @diondiondion) +- **Add ability to block words in usernames** (#35407, #35655, and #35806 by @ClearlyClaire and @Gargron) +- Add support for displaying link previews for Admin UI (#35958 by @ThisIsMissEm) +- Add support for dynamic viewport height (#36272 by @e1berd) +- Add support for numeric-based URIs for new local accounts (#32724, #36304, #36316, and #36365 by @ClearlyClaire) +- Add Traditional Mongolian to posting languages (#36196 by @shimon1024) +- Add example post with manual quote approval policy to `dev:populate_sample_data` (#36099 by @ClearlyClaire) +- Add server-side support for handling posts with a quote policy allowing followers to quote (#36093 and #36127 by @ClearlyClaire) +- Add schema.org markup to SEO-enabled posts (#36075 by @Gargron) +- Add migration to fill unset default quote policy based on default post privacy (#36041 by @ClearlyClaire) +- Add support for exposing conversation context for new public conversations according to FEP-7888 (#35959 and #36064 by @ClearlyClaire and @jesseplusplus) +- Add digest re-check before removing followers in synchronization mechanism (#34273 by @ClearlyClaire) +- Add “Posting defaults” setting page, moving existing settings from “Other” (#35896, #36033, #35966, #35969, and #36084 by @ClearlyClaire and @diondiondion) +- Add support for displaying Valkey version on admin dashboard (#35785 by @ykzts) +- Add delivery failure tracking and handling to FASP jobs (#35625, #35628, and #35723 by @oneiros) +- Add example of quote post with a preview card to development sample data (#35616 by @ClearlyClaire) +- Add second set of blocked text that applies to accounts regardless of account age for spam-blocking (#35563 by @ClearlyClaire) +- Add experimental feature to select custom emoji rendering (#35229, #35282, #35253, #35424, #35473, #35483, #35505, #35568, #35605, #35659, #35664, #35739, #35985, #36051, #36071, #36137, #36165, #36248, #36262, #36275, #36293, #36341, #36342, #36366, #36377, #36378, #36385, #36393, #36397, #36403, #36413, #36410, #36454, and #36402 by @ChaosExAnima and @braddunbar)\ + This also completely reworks the processing and rendering of emojis and server-rendered HTML in statuses and other places. + +### Changed + +- Change confirmation dialogs for follow button actions “unfollow”, “unblock”, and “withdraw request” (#36289 by @diondiondion) +- Change “Follow” button labels (#36264 by @diondiondion) +- Change display of content warnings in Admin UI (#35935 by @ThisIsMissEm) +- Change index on `follows` table to improve performance of some queries (#36374 by @ClearlyClaire) +- Change links to accounts in settings and moderation views to link to local view unless account is suspended (#36340 by @diondiondion) +- Change `timeline_preview` setting into four more granular settings (#36338 and #36467 by @ClearlyClaire) +- Change wording and design of interaction dialog to simplify it (#36124 by @diondiondion) +- Change dropdown menus to allow disabled items to be focused (#36078 by @diondiondion) +- Change modal background colours in light mode (#36069 by @diondiondion) +- Change “Posting defaults” settings page to enforce `nobody` quote policy for `private` default visibility (#36040 by @ClearlyClaire) +- Change description of “Quiet public” (#36032 by @ClearlyClaire) +- Change “Boost with original visibility” to “Share again with your followers” (#36035 by @ClearlyClaire) +- Change handling of push subscriptions to automatically delete invalid ones on delivery (#35987 by @ThisIsMissEm) +- Change design of quote posts in web UI (#35584 and #35834 by @ClearlyClaire and @Gargron) +- Change auditable accounts to be sorted by username in admin action logs interface (#35272 by @breadtk) +- Change order of translation restoration and service credit on post card (#33619 by @colindean) +- Change position of ‘add more’ to be inside table toolbar on reports (#35963 by @ThisIsMissEm) + +### Fixed + +- Fix “mute” button being displayed to unauthenticated visitors in hashtag dropdown (#36353 by @mkljczk) +- Fix overflow handling of `.more-from-author` (#36310 by @edent) +- Fix unfortunate action button wrapping in admin area (#36247 by @diondiondion) +- Fix translate button width in Safari (#36164 and #36216 by @diondiondion) +- Fix login page linking to other pages within OAuth authorization flow (#36115 by @Gargron) +- Fix stale search results being displayed in Web UI while new query is in progress (#36053 by @ChaosExAnima) +- Fix YouTube iframe not being able to start at a defined time (#26584 by @BrunoViveiros) +- Fix banned text being able to be circumvented via unicode (#35978 by @Gargron) +- Fix batch table toolbar displaying under status media (#35962 by @ThisIsMissEm) +- Fix incorrect RSS feed MIME type in gzip_types directive (#35562 by @iioflow) +- Fix 404 error after deleting status from detail view (#35800) (#35881 by @crafkaz) +- Fix feeds keyboard navigation issues (#35853, #35864, and #36267 by @braddunbar and @diondiondion) +- Fix layout shift caused by “Who to follow” widget (#35861 by @diondiondion) +- Fix Vagrantfile (#35765 by @ClearlyClaire) +- Fix reply indicator displaying wrong avatar in rare cases (#35756 by @ClearlyClaire) +- Fix `Chewy::UndefinedUpdateStrategy` in `dev:populate_sample_data` task when Elasticsearch is enabled (#35615 by @ClearlyClaire) +- Fix unnecessary account note addition for already-muted moved-to users (#35566 by @mjankowski) +- Fix seeded admin user creation failing on specific configurations (#35565 by @oneiros) +- Fix media modal images in Web UI having redundant `title` attribute (#35468 by @mayank99) +- Fix inconsistent default privacy post setting when unset in settings (#35422 by @oneiros) +- Fix glitchy status keyboard navigation (#35455 and #35504 by @diondiondion) +- Fix post being submitted when pressing “Enter” in the CW field (#35445 by @diondiondion) + ## [4.4.7] - 2025-10-15 ### Fixed diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb index 7fca8e8c8211fe..b8f6436fde3bb2 100644 --- a/lib/mastodon/version.rb +++ b/lib/mastodon/version.rb @@ -17,7 +17,7 @@ def patch end def default_prerelease - 'alpha.3' + 'beta.1' end def prerelease From 5a8ab0a3e62a8825e28bb74c1760ba6488d20c97 Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 15 Oct 2025 16:12:33 +0200 Subject: [PATCH 179/853] Update changelog with last-minute changes (#36482) --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7c2eafaf50bcd..bebb2a3b15834b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,7 @@ All notable changes to this project will be documented in this file. - Change display of content warnings in Admin UI (#35935 by @ThisIsMissEm) - Change index on `follows` table to improve performance of some queries (#36374 by @ClearlyClaire) - Change links to accounts in settings and moderation views to link to local view unless account is suspended (#36340 by @diondiondion) +- Change redirection for denied registration from web app to sign-in page with error message (#36384 by @ClearlyClaire) - Change `timeline_preview` setting into four more granular settings (#36338 and #36467 by @ClearlyClaire) - Change wording and design of interaction dialog to simplify it (#36124 by @diondiondion) - Change dropdown menus to allow disabled items to be focused (#36078 by @diondiondion) @@ -51,6 +52,7 @@ All notable changes to this project will be documented in this file. ### Fixed +- Fix rendering of poll options in status history modal (#35633 by @ThisIsMissEm) - Fix “mute” button being displayed to unauthenticated visitors in hashtag dropdown (#36353 by @mkljczk) - Fix overflow handling of `.more-from-author` (#36310 by @edent) - Fix unfortunate action button wrapping in admin area (#36247 by @diondiondion) From 2ccab6863694e1d4a43a7c63c2f4284c42ad92ea Mon Sep 17 00:00:00 2001 From: Emelia Smith Date: Wed, 15 Oct 2025 11:05:10 +0200 Subject: [PATCH 180/853] [Glitch] Fix rendering of poll options in status history modal Port d8bdce2835e024b7fca4c4db661bec2bcd067f53 to glitch-soc Signed-off-by: Claire --- .../ui/components/compare_history_modal.jsx | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/app/javascript/flavours/glitch/features/ui/components/compare_history_modal.jsx b/app/javascript/flavours/glitch/features/ui/components/compare_history_modal.jsx index 78dddf2de003ee..200061657ca07b 100644 --- a/app/javascript/flavours/glitch/features/ui/components/compare_history_modal.jsx +++ b/app/javascript/flavours/glitch/features/ui/components/compare_history_modal.jsx @@ -93,14 +93,16 @@ class CompareHistoryModal extends PureComponent {
    {currentVersion.getIn(['poll', 'options']).map(option => (
  • - - - +
  • ))}
From ef3f2ced09a9f98e80418568117eaa079e835f3e Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 15 Oct 2025 07:30:09 -0400 Subject: [PATCH 181/853] [Glitch] Update `stylelint-config-standard-scss` to version 16.0.0 Port c6de46d12d80d867cffc1a060ba9f2950c2acfee to glitch-soc Co-authored-by: diondiondion Signed-off-by: Claire --- app/javascript/flavours/glitch/styles/admin.scss | 14 +++++++------- .../flavours/glitch/styles/components.scss | 16 +++++++--------- .../flavours/glitch/styles/dashboard.scss | 2 +- .../flavours/glitch/styles/emoji_picker.scss | 2 +- app/javascript/flavours/glitch/styles/forms.scss | 2 +- app/javascript/flavours/glitch/styles/polls.scss | 7 ------- 6 files changed, 17 insertions(+), 26 deletions(-) diff --git a/app/javascript/flavours/glitch/styles/admin.scss b/app/javascript/flavours/glitch/styles/admin.scss index fc4e50dfdef861..5ce556744707e4 100644 --- a/app/javascript/flavours/glitch/styles/admin.scss +++ b/app/javascript/flavours/glitch/styles/admin.scss @@ -717,7 +717,7 @@ body, } &__title { - word-wrap: break-word; + overflow-wrap: break-word; } &__timestamp { @@ -768,7 +768,7 @@ body, } &__title { - word-wrap: break-word; + overflow-wrap: break-word; } &__timestamp { @@ -1418,7 +1418,7 @@ a.sparkline { .report-header { display: grid; - grid-gap: 15px; + gap: 15px; grid-template-columns: minmax(0, 1fr) 300px; &__details { @@ -1528,7 +1528,7 @@ a.sparkline { margin: 8px 0; overflow: hidden; text-overflow: ellipsis; - word-wrap: break-word; + overflow-wrap: break-word; max-height: 21px * 2; position: relative; font-size: 15px; @@ -1685,7 +1685,7 @@ a.sparkline { &__content { font-size: 15px; line-height: 20px; - word-wrap: break-word; + overflow-wrap: break-word; font-weight: 400; color: $primary-text-color; @@ -1787,7 +1787,7 @@ a.sparkline { padding: 15px; font-size: 15px; line-height: 20px; - word-wrap: break-word; + overflow-wrap: break-word; font-weight: 400; color: $primary-text-color; box-sizing: border-box; @@ -1969,7 +1969,7 @@ a.sparkline { border-radius: 4px; font-size: 15px; line-height: 20px; - word-wrap: break-word; + overflow-wrap: break-word; font-weight: 400; border: 1px solid lighten($ui-base-color, 4%); color: $primary-text-color; diff --git a/app/javascript/flavours/glitch/styles/components.scss b/app/javascript/flavours/glitch/styles/components.scss index ef800908506b69..c0fc55a5819072 100644 --- a/app/javascript/flavours/glitch/styles/components.scss +++ b/app/javascript/flavours/glitch/styles/components.scss @@ -1175,7 +1175,7 @@ .edit-indicator__content, .reply-indicator__content { position: relative; - word-wrap: break-word; + overflow-wrap: break-word; font-weight: 400; overflow: hidden; text-overflow: ellipsis; @@ -1422,7 +1422,7 @@ } .announcements__item__content { - word-wrap: break-word; + overflow-wrap: break-word; overflow-y: auto; .emojione { @@ -4033,7 +4033,7 @@ a.account__display-name { .react-toggle-screenreader-only, .sr-only { border: 0; - clip: rect(0 0 0 0); + clip-path: inset(50%); height: 1px; margin: -1px; overflow: hidden; @@ -5309,10 +5309,8 @@ a.status-card { &__menu { @include search-popout; - & { - padding: 0; - background: $ui-secondary-color; - } + padding: 0; + background: $ui-secondary-color; } &__menu-list { @@ -8624,7 +8622,7 @@ noscript { font-weight: 400; overflow: hidden; word-break: normal; - word-wrap: break-word; + overflow-wrap: break-word; p { margin-bottom: 20px; @@ -9269,7 +9267,7 @@ noscript { position: relative; font-size: 15px; line-height: 20px; - word-wrap: break-word; + overflow-wrap: break-word; font-weight: 400; max-height: 50vh; overflow: hidden; diff --git a/app/javascript/flavours/glitch/styles/dashboard.scss b/app/javascript/flavours/glitch/styles/dashboard.scss index c99cdc357af19e..8326022f71ab9e 100644 --- a/app/javascript/flavours/glitch/styles/dashboard.scss +++ b/app/javascript/flavours/glitch/styles/dashboard.scss @@ -61,7 +61,7 @@ .dashboard { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr); - grid-gap: 10px; + gap: 10px; @media screen and (width <= 1350px) { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); diff --git a/app/javascript/flavours/glitch/styles/emoji_picker.scss b/app/javascript/flavours/glitch/styles/emoji_picker.scss index 1fde5de1dc2f9f..d443b74fe3a173 100644 --- a/app/javascript/flavours/glitch/styles/emoji_picker.scss +++ b/app/javascript/flavours/glitch/styles/emoji_picker.scss @@ -190,7 +190,7 @@ padding: 0; margin: -1px; overflow: hidden; - clip: rect(0, 0, 0, 0); + clip-path: inset(50%); border: 0; } diff --git a/app/javascript/flavours/glitch/styles/forms.scss b/app/javascript/flavours/glitch/styles/forms.scss index 87e6411bc6fa2e..aad79c9876f2d1 100644 --- a/app/javascript/flavours/glitch/styles/forms.scss +++ b/app/javascript/flavours/glitch/styles/forms.scss @@ -300,7 +300,7 @@ code { color: $primary-text-color; display: block; margin-bottom: 8px; - word-wrap: break-word; + overflow-wrap: break-word; font-weight: 500; } diff --git a/app/javascript/flavours/glitch/styles/polls.scss b/app/javascript/flavours/glitch/styles/polls.scss index 5775f9723616e3..e8f2f5c39400a9 100644 --- a/app/javascript/flavours/glitch/styles/polls.scss +++ b/app/javascript/flavours/glitch/styles/polls.scss @@ -6,12 +6,6 @@ margin-top: 16px; font-size: 14px; - ul, - .e-content & ul { - margin: 0; - list-style: none; - } - li { margin-bottom: 10px; position: relative; @@ -66,7 +60,6 @@ &__text { display: inline-block; - word-wrap: break-word; overflow-wrap: break-word; max-width: calc(100% - 45px - 25px); } From 905aa9434def08d792506dc78d779d1262050d06 Mon Sep 17 00:00:00 2001 From: Aung Htet Nay <57069407+aunghtetnay@users.noreply.github.com> Date: Wed, 15 Oct 2025 21:55:39 +0630 Subject: [PATCH 182/853] Change FFmpeg source to GitHub mirror in Dockerfile (#36424) --- Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index ad8150552a4c05..e457ae3623b316 100644 --- a/Dockerfile +++ b/Dockerfile @@ -208,12 +208,12 @@ FROM build AS ffmpeg # renovate: datasource=repology depName=ffmpeg packageName=openpkg_current/ffmpeg ARG FFMPEG_VERSION=8.0 # ffmpeg download URL, change with [--build-arg FFMPEG_URL="https://ffmpeg.org/releases"] -ARG FFMPEG_URL=https://ffmpeg.org/releases +ARG FFMPEG_URL=https://github.com/FFmpeg/FFmpeg/archive/refs/tags WORKDIR /usr/local/ffmpeg/src # Download and extract ffmpeg source code -ADD ${FFMPEG_URL}/ffmpeg-${FFMPEG_VERSION}.tar.xz /usr/local/ffmpeg/src/ -RUN tar xf ffmpeg-${FFMPEG_VERSION}.tar.xz; +ADD ${FFMPEG_URL}/n${FFMPEG_VERSION}.tar.gz /usr/local/ffmpeg/src/ +RUN tar xf n${FFMPEG_VERSION}.tar.gz && mv FFmpeg-n${FFMPEG_VERSION} ffmpeg-${FFMPEG_VERSION}; WORKDIR /usr/local/ffmpeg/src/ffmpeg-${FFMPEG_VERSION} From 28a42bb62c71f7a2b25002a41ebc586445a93b69 Mon Sep 17 00:00:00 2001 From: diondiondion Date: Wed, 15 Oct 2025 17:38:36 +0200 Subject: [PATCH 183/853] Fix low-contrast hover colour of alert actions (light theme only) (#36484) --- app/javascript/styles/mastodon/components.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 65ed88dca92a82..78c711c5528eae 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -10439,7 +10439,7 @@ noscript { &:hover, &:focus, &:active { - background: color.change($ui-base-color, $alpha: 0.85); + background: color.change($white, $alpha: 0.15); } } From 869eeecfee61d6e2a18ca3f7761809c0493e1fcc Mon Sep 17 00:00:00 2001 From: diondiondion Date: Wed, 15 Oct 2025 19:30:47 +0200 Subject: [PATCH 184/853] Show new replies early if the fetch-all-replies task takes long to finish (#36481) --- .../status/components/refresh_controller.tsx | 51 +++++++++++++------ app/javascript/mastodon/locales/en.json | 2 +- app/javascript/mastodon/reducers/contexts.ts | 7 ++- 3 files changed, 42 insertions(+), 18 deletions(-) diff --git a/app/javascript/mastodon/features/status/components/refresh_controller.tsx b/app/javascript/mastodon/features/status/components/refresh_controller.tsx index 8297922cbb1ee6..253cce469197f6 100644 --- a/app/javascript/mastodon/features/status/components/refresh_controller.tsx +++ b/app/javascript/mastodon/features/status/components/refresh_controller.tsx @@ -38,7 +38,7 @@ const messages = defineMessages({ }, success: { id: 'status.context.loading_success', - defaultMessage: 'All replies loaded', + defaultMessage: 'New replies loaded', }, error: { id: 'status.context.loading_error', @@ -81,22 +81,38 @@ export const RefreshController: React.FC<{ useEffect(() => { let timeoutId: ReturnType; - const scheduleRefresh = (refresh: AsyncRefreshHeader) => { + const scheduleRefresh = ( + refresh: AsyncRefreshHeader, + iteration: number, + ) => { timeoutId = setTimeout(() => { void apiGetAsyncRefresh(refresh.id).then((result) => { - // If the refresh status is not finished, - // schedule another refresh and exit - if (result.async_refresh.status !== 'finished') { - scheduleRefresh(refresh); + // At three scheduled refreshes, we consider the job + // long-running and attempt to fetch any new replies so far + const isLongRunning = iteration === 3; + + const { status, result_count } = result.async_refresh; + + // If the refresh status is not finished and not long-running, + // we just schedule another refresh and exit + if (status === 'running' && !isLongRunning) { + scheduleRefresh(refresh, iteration + 1); return; } - // Refresh status is finished. The action below will clear `refreshHeader` - dispatch(completeContextRefresh({ statusId })); + // If refresh status is finished, clear `refreshHeader` + // (we don't want to do this if it's just a long-running job) + if (status === 'finished') { + dispatch(completeContextRefresh({ statusId })); + } // Exit if there's nothing to fetch - if (result.async_refresh.result_count === 0) { - setLoadingState('idle'); + if (result_count === 0) { + if (status === 'finished') { + setLoadingState('idle'); + } else { + scheduleRefresh(refresh, iteration + 1); + } return; } @@ -106,10 +122,15 @@ export const RefreshController: React.FC<{ // If so, they will populate `contexts.pendingReplies[statusId]` void dispatch(fetchContext({ statusId, prefetchOnly: true })) .then(() => { - // Reset loading state to `idle` – but if the fetch - // has resulted in new pending replies, the `hasPendingReplies` + // Reset loading state to `idle`. If the fetch has + // resulted in new pending replies, the `hasPendingReplies` // flag will switch the loading state to 'more-available' - setLoadingState('idle'); + if (status === 'finished') { + setLoadingState('idle'); + } else { + // Keep background fetch going if `isLongRunning` is true + scheduleRefresh(refresh, iteration + 1); + } }) .catch(() => { // Show an error if the fetch failed @@ -121,7 +142,7 @@ export const RefreshController: React.FC<{ // Initialise a refresh if (refreshHeader && !wasDismissed) { - scheduleRefresh(refreshHeader); + scheduleRefresh(refreshHeader, 1); setLoadingState('loading'); } @@ -135,7 +156,7 @@ export const RefreshController: React.FC<{ if (loadingState === 'success') { const timeoutId = setTimeout(() => { setLoadingState('idle'); - }, 3000); + }, 2500); return () => { clearTimeout(timeoutId); diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index 5ecf32ff6d6822..6917bfef36c4d7 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -876,7 +876,7 @@ "status.contains_quote": "Contains quote", "status.context.loading": "Loading more replies", "status.context.loading_error": "Couldn't load new replies", - "status.context.loading_success": "All replies loaded", + "status.context.loading_success": "New replies loaded", "status.context.more_replies_found": "More replies found", "status.context.retry": "Retry", "status.context.show": "Show", diff --git a/app/javascript/mastodon/reducers/contexts.ts b/app/javascript/mastodon/reducers/contexts.ts index 0a31c49828480d..0331c8083a4132 100644 --- a/app/javascript/mastodon/reducers/contexts.ts +++ b/app/javascript/mastodon/reducers/contexts.ts @@ -166,7 +166,10 @@ const updateContext = (state: Draft, status: ApiStatusJSON): void => { export const contextsReducer = createReducer(initialState, (builder) => { builder .addCase(fetchContext.fulfilled, (state, action) => { - if (action.payload.prefetchOnly) { + const currentReplies = state.replies[action.meta.arg.statusId] ?? []; + const hasReplies = currentReplies.length > 0; + // Ignore prefetchOnly if there are no replies - then we can load them immediately + if (action.payload.prefetchOnly && hasReplies) { storePrefetchedReplies( state, action.meta.arg.statusId, @@ -179,7 +182,7 @@ export const contextsReducer = createReducer(initialState, (builder) => { action.payload.context, ); - if (action.payload.refresh) { + if (action.payload.refresh && !action.payload.prefetchOnly) { state.refreshing[action.meta.arg.statusId] = action.payload.refresh; } } From ef53dcfd8c593655ac907e0c7f3c3018e3a91b72 Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 16 Oct 2025 11:10:53 +0200 Subject: [PATCH 185/853] Fix pinned hashtag columns fully refreshing unprompted (#36497) --- app/javascript/mastodon/features/hashtag_timeline/index.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/mastodon/features/hashtag_timeline/index.jsx b/app/javascript/mastodon/features/hashtag_timeline/index.jsx index 1a7ffa6c23ffeb..791f494d3d8abd 100644 --- a/app/javascript/mastodon/features/hashtag_timeline/index.jsx +++ b/app/javascript/mastodon/features/hashtag_timeline/index.jsx @@ -142,7 +142,7 @@ class HashtagTimeline extends PureComponent { const { params, local } = this.props; const { id, tags } = prevProps.params; - if (id !== params.id || !isEqual(tags, params.tags) || !isEqual(local, params.local)) { + if (id !== params.id || !isEqual(tags, params.tags) || !isEqual(local, prevProps.local)) { this._unload(); this._load(); } From 241ad1c5878161f5f4a19c16ed6c042f1c2cb6c2 Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 16 Oct 2025 11:24:22 +0200 Subject: [PATCH 186/853] Update docker-compose.yml sidekiq health check to work for both 4.4 and 4.5 (#36498) --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index a2264b65d37618..3cc3b7f4880781 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -115,7 +115,7 @@ services: volumes: - ./public/system:/mastodon/public/system healthcheck: - test: ['CMD-SHELL', "ps aux | grep '[s]idekiq\ 7' || false"] + test: ['CMD-SHELL', "ps aux | grep '[s]idekiq\ [78]' || false"] ## Uncomment to enable federation with tor instances along with adding the following ENV variables ## http_hidden_proxy=http://privoxy:8118 From 05244c335d23951b9ec069bd682845cc9c435968 Mon Sep 17 00:00:00 2001 From: diondiondion Date: Thu, 16 Oct 2025 11:44:24 +0200 Subject: [PATCH 187/853] Restructure appearance settings to introduce new Advanced settings section (#36496) --- app/javascript/styles/mastodon/admin.scss | 4 +-- .../preferences/appearance/show.html.haml | 27 ++++++++++--------- config/locales/af.yml | 2 -- config/locales/an.yml | 3 --- config/locales/ar.yml | 3 --- config/locales/ast.yml | 3 --- config/locales/az.yml | 3 --- config/locales/be.yml | 3 --- config/locales/bg.yml | 3 --- config/locales/ca.yml | 3 --- config/locales/ckb.yml | 3 --- config/locales/co.yml | 3 --- config/locales/cs.yml | 3 --- config/locales/cy.yml | 3 --- config/locales/da.yml | 3 --- config/locales/de.yml | 3 --- config/locales/el.yml | 3 --- config/locales/en-GB.yml | 3 --- config/locales/en.yml | 5 ++-- config/locales/eo.yml | 3 --- config/locales/es-AR.yml | 3 --- config/locales/es-MX.yml | 3 --- config/locales/es.yml | 3 --- config/locales/et.yml | 3 --- config/locales/eu.yml | 3 --- config/locales/fa.yml | 3 --- config/locales/fi.yml | 3 --- config/locales/fo.yml | 3 --- config/locales/fr-CA.yml | 3 --- config/locales/fr.yml | 3 --- config/locales/fy.yml | 3 --- config/locales/ga.yml | 3 --- config/locales/gd.yml | 3 --- config/locales/gl.yml | 3 --- config/locales/he.yml | 3 --- config/locales/hr.yml | 1 - config/locales/hu.yml | 3 --- config/locales/hy.yml | 3 --- config/locales/ia.yml | 3 --- config/locales/id.yml | 3 --- config/locales/ie.yml | 3 --- config/locales/io.yml | 3 --- config/locales/is.yml | 3 --- config/locales/it.yml | 5 ---- config/locales/ja.yml | 3 --- config/locales/kab.yml | 1 - config/locales/kk.yml | 3 --- config/locales/ko.yml | 3 --- config/locales/ku.yml | 3 --- config/locales/lad.yml | 3 --- config/locales/lt.yml | 3 --- config/locales/lv.yml | 3 --- config/locales/ms.yml | 3 --- config/locales/my.yml | 3 --- config/locales/nl.yml | 3 --- config/locales/nn.yml | 3 --- config/locales/no.yml | 3 --- config/locales/oc.yml | 3 --- config/locales/pl.yml | 3 --- config/locales/pt-BR.yml | 3 --- config/locales/pt-PT.yml | 3 --- config/locales/ru.yml | 3 --- config/locales/sc.yml | 3 --- config/locales/sco.yml | 3 --- config/locales/si.yml | 3 --- config/locales/simple_form.en.yml | 8 +++--- config/locales/sk.yml | 3 --- config/locales/sl.yml | 3 --- config/locales/sq.yml | 3 --- config/locales/sr-Latn.yml | 3 --- config/locales/sr.yml | 3 --- config/locales/sv.yml | 3 --- config/locales/th.yml | 3 --- config/locales/tr.yml | 3 --- config/locales/uk.yml | 3 --- config/locales/vi.yml | 3 --- config/locales/zh-CN.yml | 3 --- config/locales/zh-HK.yml | 3 --- config/locales/zh-TW.yml | 3 --- 79 files changed, 23 insertions(+), 243 deletions(-) diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss index 5f82db933b8e2a..b76d7ef843de0a 100644 --- a/app/javascript/styles/mastodon/admin.scss +++ b/app/javascript/styles/mastodon/admin.scss @@ -300,9 +300,9 @@ $content-width: 840px; font-size: 13px; font-weight: 700; color: $darker-text-color; - padding-bottom: 8px; + padding-top: 24px; margin-bottom: 8px; - border-bottom: 1px solid var(--background-border-color); + border-top: 1px solid var(--background-border-color); } h6 { diff --git a/app/views/settings/preferences/appearance/show.html.haml b/app/views/settings/preferences/appearance/show.html.haml index 72e2575a8ea6e1..3dc60697a44c34 100644 --- a/app/views/settings/preferences/appearance/show.html.haml +++ b/app/views/settings/preferences/appearance/show.html.haml @@ -47,15 +47,6 @@ #{t 'appearance.localization.body'} #{content_tag(:a, t('appearance.localization.guide_link_text'), href: t('appearance.localization.guide_link'), target: '_blank', rel: 'noopener')} = f.simple_fields_for :settings, current_user.settings do |ff| - %h4= t 'appearance.advanced_web_interface' - - %p.hint= t 'appearance.advanced_web_interface_hint' - - .fields-group - = ff.input :'web.advanced_layout', - hint: false, - label: I18n.t('simple_form.labels.defaults.setting_advanced_layout'), - wrapper: :with_label %h4= t 'appearance.animations_and_accessibility' .fields-group @@ -77,12 +68,10 @@ .fields-group = ff.input :'web.trends', wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_trends') - %h4= t 'appearance.confirmation_dialogs' + %h4= t 'appearance.boosting_preferences' .fields-group - = ff.input :'web.reblog_modal', wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_boost_modal') - = ff.input :'web.delete_modal', wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_delete_modal') - = ff.input :'web.missing_alt_text_modal', wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_missing_alt_text_modal') + = ff.input :'web.reblog_modal', wrapper: :with_label, hint: I18n.t('simple_form.hints.defaults.setting_boost_modal'), label: I18n.t('simple_form.labels.defaults.setting_boost_modal') %h4= t 'appearance.sensitive_content' @@ -106,5 +95,17 @@ .fields-group = ff.input :'web.expand_content_warnings', wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_expand_spoilers') + %h4= t 'appearance.advanced_settings' + + .fields-group + = ff.input :'web.advanced_layout', + hint: I18n.t('simple_form.hints.defaults.setting_advanced_layout'), + label: I18n.t('simple_form.labels.defaults.setting_advanced_layout'), + wrapper: :with_label + + .fields-group + = ff.input :'web.delete_modal', wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_delete_modal') + = ff.input :'web.missing_alt_text_modal', wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_missing_alt_text_modal') + .actions = f.button :button, t('generic.save_changes'), type: :submit diff --git a/config/locales/af.yml b/config/locales/af.yml index 89ede096e28daf..4f6cacffea7e6a 100644 --- a/config/locales/af.yml +++ b/config/locales/af.yml @@ -93,8 +93,6 @@ af: status: Status title: Webhoeke webhook: Web-hoek - appearance: - advanced_web_interface_hint: As jy die volle wydte van jou skerm gebruik, laat die gevorderde webkoppelvlak jou toe om kolomme met verskillende soorte inligting langs mekaar te rangskik. So kan jy, byvoorbeeld, tegelyk jou tuistoevoer, kennisgewings, gefedereerde tydlyn en nog ander lyste of hutsetikette dophou. auth: apply_for_account: Doen aansoek om ’n rekening logout: Teken uit diff --git a/config/locales/an.yml b/config/locales/an.yml index 4b9385d5f8fcd7..64aa98ce5de9bc 100644 --- a/config/locales/an.yml +++ b/config/locales/an.yml @@ -877,10 +877,7 @@ an: hint_html: Si quiers migrar d'unatra cuenta a esta, aquí puetz creyar un alias, que ye necesario antes de que puedas empecipiar a mover seguidors d'a cuenta anterior ta esta. Esta acción per ella mesma ye inofensiva y reversible. La migración d'a cuenta s'inicia dende la cuenta antiga. remove: Desvincular alias appearance: - advanced_web_interface: Interficie web abanzada - advanced_web_interface_hint: 'Si deseya utilizar tot l''amplo de pantalla, la interficie web abanzada le permite configurar quantas columnas diferents pa veyer tanta información a lo mesmo tiempo como quiera: Inicio, notificacions, linia de tiempo federada, qualsequier numero de listas y etiquetas.' animations_and_accessibility: Animacions y accesibilidat - confirmation_dialogs: Dialogos de confirmación discovery: Descubrir localization: body: Mastodon ye traduciu con la aduya de voluntarios. diff --git a/config/locales/ar.yml b/config/locales/ar.yml index f48e9fc9ef9f15..fb60171805750c 100644 --- a/config/locales/ar.yml +++ b/config/locales/ar.yml @@ -1253,10 +1253,7 @@ ar: hint_html: إذا كنت ترغب في الانتقال من حساب آخر إلى هذا الحساب الحالي، يمكنك إنشاء اسم مستعار هنا، والذي هو مطلوب قبل أن تتمكن من المضي قدما في نقل متابِعيك من الحساب القديم إلى هذا الحساب. هذا الإجراء بحد ذاته هو غير مؤذي و قابل للعكس. تتم بداية تهجير الحساب من الحساب القديم. remove: إلغاء ربط الكنية appearance: - advanced_web_interface: واجهة الويب المتقدمة - advanced_web_interface_hint: 'إذا كنت ترغب في استخدام عرض شاشتك بأكمله، فواجهة الويب المتقدمة تسمح لك بضبط العديد من الأعمدة المختلفة لرؤية أكبر قدر من المعلومات التي ترغب فيها في آن واحد: الخيط الرئيسي والإشعارات والخيط الزمني الفدرالي وأي عدد من القوائم والوسوم.' animations_and_accessibility: الإتاحة والحركة - confirmation_dialogs: نوافذ التأكيد discovery: الاستكشاف localization: body: ماستدون يُترجِمه متطوّعون. diff --git a/config/locales/ast.yml b/config/locales/ast.yml index e2bca6e8cb8196..b0e1052382a3bb 100644 --- a/config/locales/ast.yml +++ b/config/locales/ast.yml @@ -432,10 +432,7 @@ ast: aliases: empty: Nun tienes nengún nomatu. appearance: - advanced_web_interface: Interfaz web avanzada - advanced_web_interface_hint: 'Si quies asegúrate de que s''use tol llargor de la pantalla, la interfaz web avanzada permítete configurar columnes estremaes pa ver muncha más información al empar: Aniciu, avisos, llinia de tiempu federada y cualesquier cantidá de llistes y etiquetes.' animations_and_accessibility: Animaciones y accesibilidá - confirmation_dialogs: Diálogos de confirmación discovery: Descubrimientu localization: body: Mastodon tradúcenlu voluntarios, diff --git a/config/locales/az.yml b/config/locales/az.yml index 0fa11278cee7dd..1f35a7ada1e7a6 100644 --- a/config/locales/az.yml +++ b/config/locales/az.yml @@ -118,10 +118,7 @@ az: next_steps: Moderasiya qərarını geri almaq üçün etirazı təsdiqləyə, ya da etirazı yox saya bilərsiniz. subject: "%{username}, %{instance} üzərindəki bir moderasiya qərarına etiraz edir" appearance: - advanced_web_interface: Qabaqcıl veb interfeys - advanced_web_interface_hint: 'Tam ekran enini istifadə etmək istəyirsinizsə, qabaqcıl veb interfeys, istədiyiniz qədər məlumatı eyni anda görə bilməyiniz üçün bir çox fərqli sütunu konfiqurasiya etməyinizə imkan verir: Əsas ekran, bildirişlər, birləşmiş zaman xətti, istənilən sayda siyahı və mövzu etiketləri.' animations_and_accessibility: Animasiyalar və erişiləbilənlik - confirmation_dialogs: Təsdiq dialoq pəncərələri discovery: Kəşf et localization: guide_link_text: Hər kəs töhfə verə bilər. diff --git a/config/locales/be.yml b/config/locales/be.yml index ebbfb8bf6d70f5..bbce0603271b30 100644 --- a/config/locales/be.yml +++ b/config/locales/be.yml @@ -1224,10 +1224,7 @@ be: hint_html: Калі вы хочаце перайсці з іншага ўліковага запісу ў гэты, то тут вы можаце стварыць псеўданім, каб перамясціць падпісчыкаў са старога ўліковага запісу ў гэты. Гэта дзеянне з'яўляецца бясшкодным і зварачальным. Перанос уліковага запісу пачынаецца са старога ўліковага запісу. remove: Адмацаваць псеўданім appearance: - advanced_web_interface: Пашыраны вэб-інтэрфейс - advanced_web_interface_hint: 'Калі вы хочаце выкарыстоўваць усю шырыню экрана, пашыраны вэб-інтэрфейс дазваляе вам наладзіць мноства розных слупкоў, каб бачыць столькі інфармацыі, колькі вам трэба: галоўная, апавяшчэнні, глабальная стужка, любая колькасць спісаў і хэштэгаў.' animations_and_accessibility: Анімацыі і даступнасць - confirmation_dialogs: Дыялогавыя вокны пацвярджэння discovery: Адкрыцці localization: body: Mastodon перакладаецца добраахвотнікамі. diff --git a/config/locales/bg.yml b/config/locales/bg.yml index 309d634914e72c..1f22bf0047e695 100644 --- a/config/locales/bg.yml +++ b/config/locales/bg.yml @@ -1166,10 +1166,7 @@ bg: hint_html: Ако желаете да се преместите от друг акаунт към този, тук можете да създадете псевдоним, което се изисква преди да можете да пристъпите към преместване на последователите си от стария акаунт към този. Това действие е безопасно и възстановимо. Миграцията към новия акаунт се инициира от стария акаунт. remove: Разкачвне на псевдонима appearance: - advanced_web_interface: Разширен уеб интерфейс - advanced_web_interface_hint: 'Ако искате да употребявате цялата ширина на екрана си, разширеният уеб интерфейс ви позволява да настроите най-различни колони, за да виждате едновременно множество сведения, колкото искате: Начало, известия, федеративен инфоканал, произволен брой списъци и хаштагове.' animations_and_accessibility: Анимация и достъпност - confirmation_dialogs: Диалогов прозорец за потвърждение discovery: Откриване localization: body: Mastodon е преведено от доброволци. diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 1c69c680928e32..c3be44daa8e853 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -1176,10 +1176,7 @@ ca: hint_html: Si et vols moure des d'un altre compte a aquest, aquí pots crear un àlies, el qual és requerit abans que puguis procedir a moure els seguidors del compte vell a aquest. Aquesta acció és per si mateixa inofensiva i reversible. La migració del compte és iniciada des de'l compte vell. remove: Desvincula l'àlies appearance: - advanced_web_interface: Interfície web avançada - advanced_web_interface_hint: 'Si vols fer ús de tota l''amplada de la teva pantalla, la interfície web avançada et permet configurar diverses columnes per a veure molta més informació al mateix temps: Inici, notificacions, línia de temps federada i qualsevol quantitat de llistes i etiquetes.' animations_and_accessibility: Animacions i accessibilitat - confirmation_dialogs: Diàlegs de confirmació discovery: Descobriment localization: body: Mastodon és traduït per voluntaris. diff --git a/config/locales/ckb.yml b/config/locales/ckb.yml index 891453a7cef39d..8494e6e46ff3d7 100644 --- a/config/locales/ckb.yml +++ b/config/locales/ckb.yml @@ -545,10 +545,7 @@ ckb: hint_html: ئەگەر دەتەوێت لە هەژمارەیەکی ترەوە بگوێزریتەوە بۆ ئەم هەژمارە، لێرەدا دەتوانیت نازناوێک دروست بکەیت، پێش ئەوەی ئەوە بەردەوام بیت لە گواستنەوەی لە هەژمارە کۆنەکە بۆ ئەم هەژمارە پێویستە. ئەم کردەوەیە خۆی لە خۆیدا بێ زەرە و ناگەڕێتەوەگواستنەوەی لە هەژمارەی کۆنە بۆ هەژمارەی نوێ دەستی پێکردووە. remove: سڕینەوەی پەیوەندی ناز ناو appearance: - advanced_web_interface: روخساری پێشکەوتوو - advanced_web_interface_hint: 'ئەگەر دەتەوێت پانی شاشەکە بەکاربێنیت، دەتوانی بە یارمەتی ڕووکاری پێشکەوتوو چەندین ستوونی جیاواز ڕێکبخەیت بۆ بینینی زانیاری زیاتر لە هەمان کات کە دەتەوێت بیبینیت: نووسراوەکانی نووسەرانی دیکە، ئاگانامەکان، پێرستی نووسراوەکانی هەموو شوێنێک، وە هەر ژمارەیەک لە لیستەکان و هاشتاگەکان.' animations_and_accessibility: ئەنیمەیشن و توانایی دەستپێگەیشتن - confirmation_dialogs: پەیامەکانی پەسەندکراو discovery: دۆزینەوە localization: body: ماستۆدۆن لەلایەن خۆبەخشەوە وەردەگێڕێت. diff --git a/config/locales/co.yml b/config/locales/co.yml index 01dcc19ba3adee..268377d7dd33ba 100644 --- a/config/locales/co.yml +++ b/config/locales/co.yml @@ -508,10 +508,7 @@ co: hint_html: Per traslucà da un altru contu à questu, quì pudete creà un pseudonimu o "alias", riquisitu per trasferì l'abbunati da u vechju contu à u novu. St'azzione sola ùn face nunda è pò esse annullata senza prublemi. A migrazione hè principiata dapoi u vechju contu. remove: Sguassà u pseudonimu appearance: - advanced_web_interface: Interfaccia web avanzata - advanced_web_interface_hint: 'S''è voi vulete fà usu di a larghezza sana di u vostru screnu, l''interfaccia web avanzata vi permette di cunfigurà parechje culonne sfarente per vede tutta l''infurmazione chì vulete vede in listessu tempu: Accolta, nutificazione, linea pubblica, è tutti l''hashtag è liste chì vulete.' animations_and_accessibility: Animazione è accessibilità - confirmation_dialogs: Pop-up di cunfirmazione discovery: Scuperta localization: body: Mastodon hè tradottu da una squadra di vuluntari. diff --git a/config/locales/cs.yml b/config/locales/cs.yml index 926151f09501fd..3919dbe98d0d8c 100644 --- a/config/locales/cs.yml +++ b/config/locales/cs.yml @@ -1224,10 +1224,7 @@ cs: hint_html: Chcete-li se přesunout z jiného účtu na tento, můžete si zde vytvořit alias, který je vyžadován předtím, než můžete pokračovat přesunem sledujících ze starého účtu na tento. Tato akce sama o sobě je neškodná a vratná. Přesun účtu se zahajuje ze starého účtu. remove: Odpojit alias appearance: - advanced_web_interface: Pokročilé webové rozhraní - advanced_web_interface_hint: 'Chcete-li využít celé šířky vaší obrazovky, dovolí vám pokročilé webové rozhraní nastavit si mnoho různých sloupců, takže ve stejnou chvíli uvidíte tolik informací, kolik chcete: domovskou časovou osu, oznámení, federovanou časovou osu a libovolný počet seznamů a hashtagů.' animations_and_accessibility: Animace a přístupnost - confirmation_dialogs: Potvrzovací dialogy discovery: Objevování localization: body: Mastodon je překládán dobrovolníky. diff --git a/config/locales/cy.yml b/config/locales/cy.yml index e6dfd21b15cbd7..61d1d9d8afab65 100644 --- a/config/locales/cy.yml +++ b/config/locales/cy.yml @@ -1262,10 +1262,7 @@ cy: hint_html: Os ydych chi am symud o gyfrif arall i'r un hwn, gallwch greu enw arall yma, sy'n ofynnol cyn y gallwch symud ymlaen i symud dilynwyr o'r hen gyfrif i'r un hwn. Mae'r weithred hon ynddo'i hun yn ddiniwed ac yn wrthdroadwy. Mae'r mudo cyfrif yn cael ei wneud o'r hen gyfrif. remove: Dadgysylltu'r enw arall appearance: - advanced_web_interface: Rhyngwyneb gwe uwch - advanced_web_interface_hint: 'Os ydych chi am ddefnyddio lled eich sgrin gyfan, mae''r rhyngwyneb gwe datblygedig yn caniatáu i chi ffurfweddu llawer o wahanol golofnau i weld faint bynnag o wybodaeth ar yr un pryd ag y dymunwch: Cartref, hysbysiadau, ffrydiau ffederaleiddiwyd, faint bynnag o restrau a hashnodau.' animations_and_accessibility: Animeiddiadau a hygyrchedd - confirmation_dialogs: Deialogau cadarnhau discovery: Darganfod localization: body: Mae Mastodon yn cael ei gyfieithu gan wirfoddolwyr. diff --git a/config/locales/da.yml b/config/locales/da.yml index 0f8bb88cd3fc7d..e8eaae64bf95d2 100644 --- a/config/locales/da.yml +++ b/config/locales/da.yml @@ -1186,10 +1186,7 @@ da: hint_html: Ønsker du at flytte fra en anden konto til denne, kan du hér oprette det alias, der kræves, for at du kan fortsætte med at flytte følgere fra den gamle konto til denne. Denne handling er i sig selv harmløs og reversibel. Kontomigreringen påbegyndes fra den gamle konto. remove: Fjern aliaslinkning appearance: - advanced_web_interface: Avanceret webgrænseflade - advanced_web_interface_hint: 'Ønsker du udnytte hele skærmbredden, lader den avancerede webgrænseflade dig opsætte mange forskellige kolonner for at se så meget information på samme tid som ønsket: Hjem, notifikationer, federeret tidslinje, et hvilket som helst antal lister og hashtags.' animations_and_accessibility: Animationer og tilgængelighed - confirmation_dialogs: Bekræftelsesdialoger discovery: Opdagelse localization: body: Mastodon oversættes af frivillige. diff --git a/config/locales/de.yml b/config/locales/de.yml index 3f16ac94d9bc11..69c9e1332232ad 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -1186,10 +1186,7 @@ de: hint_html: Wenn du von einem anderen Konto auf dieses umziehen möchtest, dann kannst du hier einen Alias erstellen, der erforderlich ist, um deine Follower vom alten Konto auf dieses zu migrieren. Diese Aktion ist harmlos und wi­der­ruf­lich. Der Kontoumzug wird vom alten Konto aus eingeleitet. remove: Alle Aliasse aufheben appearance: - advanced_web_interface: Erweitertes Webinterface - advanced_web_interface_hint: Wenn du mehr aus deiner Bildschirmbreite herausholen möchtest, kannst du mit dem erweiterten Webinterface weitere Spalten hinzufügen und dadurch mehr Informationen auf einmal sehen, z. B. deine Startseite, die Benachrichtigungen, die föderierte Timeline sowie beliebig viele deiner Listen und Hashtags. animations_and_accessibility: Animationen und Barrierefreiheit - confirmation_dialogs: Bestätigungsdialoge discovery: Entdecken localization: body: Mastodon wird von Freiwilligen übersetzt. diff --git a/config/locales/el.yml b/config/locales/el.yml index f5a72625f72404..217c44e8ff3f67 100644 --- a/config/locales/el.yml +++ b/config/locales/el.yml @@ -1186,10 +1186,7 @@ el: hint_html: Αν θέλεις να μετακινηθείς από έναν άλλο λογαριασμό σε αυτόν εδώ, εδώ μπορείς να δημιουργήσεις ένα ψευδώνυμο, πράγμα που απαιτείται πριν προχωρήσεις για να μεταφέρεις τους ακολούθους σου από τον παλιό λογαριασμό σε αυτόν εδώ. Η ενέργεια αυτή είναι ακίνδυνη και αναστρέψιμη.Η μετακόμιση του λογαριασμού ξεκινάει από τον παλιό λογαριασμό. remove: Αποσύνδεση ψευδώνυμου appearance: - advanced_web_interface: Προηγμένη διεπαφή ιστού - advanced_web_interface_hint: 'Αν θέλεις να χρησιμοποιήσεις ολόκληρο το πλάτος της οθόνης σου, η προηγμένη λειτουργία χρήσης σου επιτρέπει να ορίσεις πολλαπλές στήλες ώστε να βλέπεις ταυτόχρονα όση πληροφορία θέλεις: Την αρχική ροή, τις ειδοποιήσεις, τις ομοσπονδιακές ροές και όσες λίστες και ετικέτες θέλεις.' animations_and_accessibility: Εφέ κινήσεων και προσβασιμότητα - confirmation_dialogs: Ερωτήσεις επιβεβαίωσης discovery: Ανακάλυψη localization: body: Το Mastodon μεταφράζεται από εθελοντές. diff --git a/config/locales/en-GB.yml b/config/locales/en-GB.yml index 621a3a4e4fde30..8cfd1b76217c92 100644 --- a/config/locales/en-GB.yml +++ b/config/locales/en-GB.yml @@ -1157,10 +1157,7 @@ en-GB: hint_html: If you want to move from another account to this one, here you can create an alias, which is required before you can proceed with moving followers from the old account to this one. This action by itself is harmless and reversible. The account migration is initiated from the old account. remove: Unlink alias appearance: - advanced_web_interface: Advanced web interface - advanced_web_interface_hint: 'If you want to make use of your entire screen width, the advanced web interface allows you to configure many different columns to see as much information at the same time as you want: Home, notifications, federated timeline, any number of lists and hashtags.' animations_and_accessibility: Animations and accessibility - confirmation_dialogs: Confirmation dialogues discovery: Discovery localization: body: Mastodon is translated by volunteers. diff --git a/config/locales/en.yml b/config/locales/en.yml index e6604e9284a031..e21698b5892105 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1186,10 +1186,9 @@ en: hint_html: If you want to move from another account to this one, here you can create an alias, which is required before you can proceed with moving followers from the old account to this one. This action by itself is harmless and reversible. The account migration is initiated from the old account. remove: Unlink alias appearance: - advanced_web_interface: Advanced web interface - advanced_web_interface_hint: 'If you want to make use of your entire screen width, the advanced web interface allows you to configure many different columns to see as much information at the same time as you want: Home, notifications, federated timeline, any number of lists and hashtags.' + advanced_settings: Advanced settings animations_and_accessibility: Animations and accessibility - confirmation_dialogs: Confirmation dialogs + boosting_preferences: Boosting preferences discovery: Discovery localization: body: Mastodon is translated by volunteers. diff --git a/config/locales/eo.yml b/config/locales/eo.yml index 812053fa390721..2a8c98b1941de0 100644 --- a/config/locales/eo.yml +++ b/config/locales/eo.yml @@ -1175,10 +1175,7 @@ eo: hint_html: Se vi volas translokiĝi de alia konto al ĉi tie, kreu alinomon. Ĝi estas sekura kaj inversebla. Ĝi komencitas de malnova konto. remove: Malligili alinomon appearance: - advanced_web_interface: Altnivela retpaĝa interfaco - advanced_web_interface_hint: 'Se vi volas uzi la tutan larĝecon de via ekrano, la kompleksa reta interfaco permesas al vi agordi multajn malsamajn kolumnojn por vidi tiom da informoj kiom vi volas samtempe: Hejmo, sciigoj, fratara templinio, kaj ajna kvanto de listoj kaj kradvortoj.' animations_and_accessibility: Animacioj kaj alirebleco - confirmation_dialogs: Konfirmaj fenestroj discovery: Eltrovo localization: body: Mastodon estas tradukita de volontuloj. diff --git a/config/locales/es-AR.yml b/config/locales/es-AR.yml index feded782ba2cc3..758021015d21e1 100644 --- a/config/locales/es-AR.yml +++ b/config/locales/es-AR.yml @@ -1186,10 +1186,7 @@ es-AR: hint_html: Si querés mudarte desde otra cuenta a esta, acá podés crear un alias, el cual es necesario antes de empezar a mudar seguidores de la cuenta vieja a ésta. Esta acción por sí misma es inofensiva y reversible. La migración de la cuenta se inicia desde la cuenta anterior. remove: Desvincular alias appearance: - advanced_web_interface: Interface web avanzada - advanced_web_interface_hint: 'Si querés hacer uso de todo el ancho de tu pantalla, la interface web avanzada te permite configurar varias columnas diferentes para ver tanta información al mismo tiempo como quieras: "Principal", "Notificaciones", "Línea temporal federada", y cualquier número de listas y etiquetas.' animations_and_accessibility: Animaciones y accesibilidad - confirmation_dialogs: Diálogos de confirmación discovery: Descubrí localization: body: Mastodon es localizado por voluntarios. diff --git a/config/locales/es-MX.yml b/config/locales/es-MX.yml index 0672b21bc476a5..d078abe8533da3 100644 --- a/config/locales/es-MX.yml +++ b/config/locales/es-MX.yml @@ -1186,10 +1186,7 @@ es-MX: hint_html: Si deseas migrar de otra cuenta a esta, aquí puedes crear un alias, que es necesario para poder mover seguidores de la cuenta anterior a esta. Esta acción por sí misma es inofensiva y reversible. La migración de la cuenta se inicia desde la cuenta anterior. remove: Desvincular alias appearance: - advanced_web_interface: Interfaz web avanzada - advanced_web_interface_hint: 'Si deseas aprovechar todo el ancho de tu pantalla, la interfaz web avanzada te permite configurar muchas columnas diferentes para ver toda la información que quieras al mismo tiempo: inicio, notificaciones, cronología federada, cualquier número de listas y etiquetas.' animations_and_accessibility: Animaciones y accesibilidad - confirmation_dialogs: Diálogos de confirmación discovery: Descubrir localization: body: Mastodon es traducido con la ayuda de voluntarios. diff --git a/config/locales/es.yml b/config/locales/es.yml index 15fd191ea41fef..4a058efd5ec4c0 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -1186,10 +1186,7 @@ es: hint_html: Si quieres migrar de otra cuenta a esta, aquí puedes crear un alias, es necesario proceder antes de empezar a mover seguidores de la cuenta anterior a esta. Esta acción por sí misma es inofensiva y reversible. La migración de la cuenta se inicia desde la cuenta antigua. remove: Desvincular alias appearance: - advanced_web_interface: Interfaz web avanzada - advanced_web_interface_hint: 'Si quieres aprovechar todo el ancho de tu pantalla, la interfaz web avanzada te permite configurar muchas columnas diferentes para ver toda la información que quieras al mismo tiempo: Inicio, notificaciones, cronología federada, cualquier número de listas y etiquetas.' animations_and_accessibility: Animaciones y accesibilidad - confirmation_dialogs: Diálogos de confirmación discovery: Descubrir localization: body: Mastodon es traducido con la ayuda de voluntarios. diff --git a/config/locales/et.yml b/config/locales/et.yml index 9607d7661d1c98..e700816493435e 100644 --- a/config/locales/et.yml +++ b/config/locales/et.yml @@ -1182,10 +1182,7 @@ et: hint_html: Kui soovid konto siia üle kolida, pead esmalt siin määrama kolitava konto aadressi. Seejärel on konto valmis võtma vastu jälgijaid vanalt kontolt. Kolitava konto aadressi määramine on iseenesest kahjutu ja tagasipööratav. Jälgijate tegelik kolimine käivitatakse vanalt kontolt. remove: Loobu suunamise vastuvõtmisest appearance: - advanced_web_interface: Kohandatud veebiliides - advanced_web_interface_hint: 'Kui soovid kasutada kogu ekraani laiust, saab kohandatud veebiliideses seadistada mitut veergu, nii et samal ajal oleks näha nii palju infot kui soovid: Kodu, teavitused, föderatsiooni ajajoon ning kuitahes palju nimekirju ja silte.' animations_and_accessibility: Animatsioonid ja ligipääs - confirmation_dialogs: Kinnitusdialoogid discovery: Avastamine localization: body: Mastodoni tõlgivad vabatahtlikud. diff --git a/config/locales/eu.yml b/config/locales/eu.yml index fb11192599b8e4..9e1fcc88a7a436 100644 --- a/config/locales/eu.yml +++ b/config/locales/eu.yml @@ -1093,10 +1093,7 @@ eu: hint_html: Beste kontu batetik hona migratu nahi baduzu, hemen ezizen bat sortu dezakezu, hau beharrezkoa da kontu zaharreko jarraitzaileak hona ekartzeko. Ekintza hau berez kaltegabea eta desegingarria da. Kontuaren migrazioa kontu zaharretik abiatzen da. remove: Deslotu ezizena appearance: - advanced_web_interface: Web interfaze aurreratua - advanced_web_interface_hint: 'Pantaila bere zabalera osoan erabili nahi baduzu, web interfaze aurreratuak hainbat zutabe desberdin konfiguratzea ahalbidetzen dizu, aldi berean nahi beste informazio ikusteko: Hasiera, jakinarazpenak, federatutako denbora-lerroa, edo nahi beste zerrenda eta traola.' animations_and_accessibility: Animazioak eta irisgarritasuna - confirmation_dialogs: Berrespen dialogoak discovery: Aurkitzea localization: body: Mastodon boluntarioek itzultzen dute. diff --git a/config/locales/fa.yml b/config/locales/fa.yml index 9c24be803516ad..bfcb4815891ca4 100644 --- a/config/locales/fa.yml +++ b/config/locales/fa.yml @@ -1182,10 +1182,7 @@ fa: hint_html: اگر می‌خواهید از حساب دیگری به این حساب منتقل شوید، این‌جا می‌توانید یک نام مستعار بسازید که برای انتقال از حساب قدیمی به این حساب لازم است. این کار به تنهایی بی‌ضرر و قابل بازگشت است. فرایند انتقال حساب از حساب قدیمی آغاز خواهد شد. remove: حذف ارتباط نام مستعار appearance: - advanced_web_interface: رابط کاربری پیشرفته - advanced_web_interface_hint: اگر می‌خواهید از تمامی پهنای صفحه‌تان استفاده کنید، رابط پیش‌رفتهٔ وب می‌گذارد هر چند ستون را که می‌خواهید، برای دیدن اطّلاعات بیش‌تر در یک زمان، پیکربندی کنید:‌خانه، آگاهی‌ها، خط زمانی عمومی،‌ هرتعدادی از سیاهه‌ها و برچسب‌ها. animations_and_accessibility: پویانمایی‌های و دسترسی‌پذیری - confirmation_dialogs: پیغام‌های تأیید discovery: کاوش localization: body: ماستودون توسط داوطلبان ترجمه شده است. diff --git a/config/locales/fi.yml b/config/locales/fi.yml index 7b19a0d820db6c..08a9b1747af5a5 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -1186,10 +1186,7 @@ fi: hint_html: Jos haluat muuttaa toisesta tilistä tähän tiliin, voit luoda tässä aliaksen, mitä vaaditaan ennen kuin voit edetä siirtämään seuraajasi vanhalta tililtä tälle tilille. Tänä toiminto on itsessään vaaraton ja kumottavissa. Tilin muuttaminen aloitetaan vanhalta tililtä. remove: Poista aliaksen linkitys appearance: - advanced_web_interface: Edistynyt selainkäyttöliittymä - advanced_web_interface_hint: 'Jos haluat hyödyntää näytön koko leveyttä, edistyneen selainkäyttöliittymän avulla voit määrittää useita erilaisia sarakkeita, niin näet kerralla niin paljon tietoa kuin haluat: kotisyöte, ilmoitukset, yleinen aikajana, mikä tahansa määrä listoja ja aihetunnisteita.' animations_and_accessibility: Animaatiot ja saavutettavuus - confirmation_dialogs: Vahvistusikkunat discovery: Löytäminen localization: body: Mastodonin ovat kääntäneet vapaaehtoiset. diff --git a/config/locales/fo.yml b/config/locales/fo.yml index 22ec7bbf25dd65..de2cfc087f0ff3 100644 --- a/config/locales/fo.yml +++ b/config/locales/fo.yml @@ -1186,10 +1186,7 @@ fo: hint_html: Ynskir tú at flyta frá eini aðrari kontu til hesa, so kanst tú stovna eitt tøkuheiti her. Tað er kravt, áðrenn tú kanst fara í gongd við at flyta fylgjarar frá gomlu kontuni til hesa. Hendan atgerðin er í sær sjálvum meinaleys og kann angrast. Flytingin av kontuni verður sett í gongd frá gomlu kontuni. remove: Strika tilknýti til tøkuheiti appearance: - advanced_web_interface: Framkomið vevmarkamót - advanced_web_interface_hint: 'Ynskir tú at brúka alla skermbreiddina, so loyvir framkomna vevmarkamóti tær at uppseta fleiri ymiskar teigar, soleiðis at tú kanst síggja so nógvar upplýsingar, sum tú ynskir, samstundis: Heima, fráboðanir, sameind tíðarlinja og óavmarkað tal av listum og frámerkjum.' animations_and_accessibility: Teknimyndagerð og atkomuligheit - confirmation_dialogs: Váttanarskermmyndir discovery: Uppdaging localization: body: Mastodon er umsett av sjálvbodnum. diff --git a/config/locales/fr-CA.yml b/config/locales/fr-CA.yml index 21bc55898377ac..0ae44cf373a08c 100644 --- a/config/locales/fr-CA.yml +++ b/config/locales/fr-CA.yml @@ -1135,10 +1135,7 @@ fr-CA: hint_html: Si vous voulez déménager d’un autre compte vers celui-ci, vous pouvez créer ici un alias, qui est nécessaire avant de pouvoir migrer les abonné·e·s de l’ancien compte vers celui-ci. Cette action en soi est inoffensive et réversible. La migration du compte est initiée à partir de l’ancien compte. remove: Détacher l'alias appearance: - advanced_web_interface: Interface web avancée - advanced_web_interface_hint: 'Si vous voulez utiliser toute la largeur de votre écran, l’interface web avancée vous permet de configurer plusieurs colonnes différentes pour voir autant d’informations que vous le souhaitez en même temps : Accueil, notifications, fil public fédéré, un nombre illimité de listes et hashtags.' animations_and_accessibility: Animations et accessibilité - confirmation_dialogs: Dialogues de confirmation discovery: Découverte localization: body: Mastodon est traduit par des volontaires. diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 36244422330217..42e0507fe404a7 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -1135,10 +1135,7 @@ fr: hint_html: Si vous voulez déménager d’un autre compte vers celui-ci, vous pouvez créer ici un alias, qui est nécessaire avant de pouvoir migrer les abonné·e·s de l’ancien compte vers celui-ci. Cette action en soi est inoffensive et réversible. La migration du compte est initiée à partir de l’ancien compte. remove: Détacher l'alias appearance: - advanced_web_interface: Interface web avancée - advanced_web_interface_hint: 'Si vous voulez utiliser toute la largeur de votre écran, l’interface web avancée vous permet de configurer plusieurs colonnes différentes pour voir autant d’informations que vous le souhaitez en même temps : Accueil, notifications, fil fédéré, un nombre illimité de listes et hashtags.' animations_and_accessibility: Animations et accessibilité - confirmation_dialogs: Dialogues de confirmation discovery: Découverte localization: body: Mastodon est traduit par des volontaires. diff --git a/config/locales/fy.yml b/config/locales/fy.yml index c631241a3192af..bad1e43f2166a5 100644 --- a/config/locales/fy.yml +++ b/config/locales/fy.yml @@ -1182,10 +1182,7 @@ fy: hint_html: Wannear’t jo fan in oare account ôf nei dizze account ferhúzje wolle, kinne jo hjir in alias oanmeitsje. Dit is nedich eardat jo troch gean kinne mei it ferhúzjen fan folgers fan de âlde nei dizze nije account. Dizze aksje is op eins net gefaarlik en omkearber. De accountmigraasje wurdt start fan de âlde account ôf. remove: Alias ûntkeppelje appearance: - advanced_web_interface: Avansearre webomjouwing - advanced_web_interface_hint: 'Wannear’t jo fan de hiele skermbreedte gebrûk meitsje wolle, stelt de avansearre webomjouwing jo yn steat om meardere ferskate kolommen te konfigurearjen. Hjirmei kinne jo safolle mooglik ynformaasje op itselde momint besjen, lykas: Start, meldingen, de globale tiidline, meardere listen en hashtags.' animations_and_accessibility: Animaasjes en tagonklikheid - confirmation_dialogs: Befêstigingen discovery: Untdekke localization: body: Mastodon wurdt troch frijwilligers oerset. diff --git a/config/locales/ga.yml b/config/locales/ga.yml index 901a3a3940a675..36aa6a88c1f64b 100644 --- a/config/locales/ga.yml +++ b/config/locales/ga.yml @@ -1243,10 +1243,7 @@ ga: hint_html: Más mian leat bogadh ó chuntas eile go dtí an ceann seo, anseo is féidir leat ailias a chruthú, a theastaíonn sular féidir leat leanúint ar aghaidh le leantóirí a bhogadh ón seanchuntas go dtí an ceann seo. Tá an gníomh seo ann féin neamhdhíobhálach agus inchúlaithe. Cuirtear tús leis an aistriú cuntais ón seanchuntas. remove: Dícheangail ailias appearance: - advanced_web_interface: Comhéadan gréasáin chun cinn - advanced_web_interface_hint: 'Más mian leat úsáid a bhaint as do leithead scáileáin ar fad, ceadaíonn an comhéadan gréasáin ardleibhéil duit go leor colúin éagsúla a chumrú chun an oiread faisnéise a fheiceáil ag an am céanna agus is mian leat: Baile, fógraí, amlíne chónaidhme, aon líon liostaí agus hashtags.' animations_and_accessibility: Beochan agus inrochtaineacht - confirmation_dialogs: Dialóga deimhnithe discovery: Fionnachtain localization: body: Oibrithe deonacha a dhéanann aistriúchán Mastodon. diff --git a/config/locales/gd.yml b/config/locales/gd.yml index 0720cf964a289a..802b925415367d 100644 --- a/config/locales/gd.yml +++ b/config/locales/gd.yml @@ -1220,10 +1220,7 @@ gd: hint_html: Nam bu mhiann leat imrich o chunntas eile dhan fhear seo, ’s urrainn dhut alias a chruthachadh an-seo agus feumaidh tu sin a dhèanamh mus urrainn dhut tòiseachadh air an luchd-leantainn agad imrich on seann-chunntas dhan fhear seo. Tha an gnìomh seo fhèin neo-chronail is chan eil e buan. Tòisichidh tu air imrich a’ chunntais on t-seann-chunntas. remove: Dì-cheangail an t-alias appearance: - advanced_web_interface: Eadar-aghaidh-lìn adhartach - advanced_web_interface_hint: 'Ma tha thu airson leud na sgrìn agad gu lèir a chleachdadh, leigidh an eadar-aghaidh-lìn adhartach leat mòran cholbhan eadar-dhealaichte a cho-rèiteachadh airson uiread de dh''fhiosrachadh ''s a thogras tu fhaicinn aig an aon àm: Dachaigh, brathan, loidhne-ama cho-naisgte, liostaichean is tagaichean hais a rèir do thoil.' animations_and_accessibility: Beòthachaidhean agus so-ruigsinneachd - confirmation_dialogs: Còmhraidhean dearbhaidh discovery: Rùrachadh localization: body: Tha Mastodon ’ga eadar-theangachadh le saor-thoilich. diff --git a/config/locales/gl.yml b/config/locales/gl.yml index c6a852fd8eaac6..9f8a23832b01a2 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -1186,10 +1186,7 @@ gl: hint_html: Se queres mudarte desde outra conta a esta nova, aquí podes crear un alcume, que é requerido antes de poder proceder a mover os seguidores da conta antiga a esta nova. Esta acción por si mesma é inocua e reversible. A migración da conta iníciase desde a conta antiga. remove: Desligar alcume appearance: - advanced_web_interface: Interface web avanzada - advanced_web_interface_hint: Se queres empregar todo o ancho da pantalla, a interface web avanzada permíteche configurar diferentes columnas para ver tanta información como queiras. Inicio, notificacións, cronoloxía federada, varias listaxes e cancelos. animations_and_accessibility: Animacións e accesibilidade - confirmation_dialogs: Diálogos de confirmación discovery: Descubrir localization: body: Mastodon tradúceno persoas voluntarias. diff --git a/config/locales/he.yml b/config/locales/he.yml index 3ea929f76c930d..85b4ace518bdc7 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -1224,10 +1224,7 @@ he: hint_html: אם ברצונך לעבור מחשבון אחר לחשבון הזה, כאן ניתן ליצור שם נרדף, הנדרש לפני שאפשר יהיה להמשיך עם העברת עוקבים מהחשבון הישן לזה. הפעולה עצמה הפיכה ובלתי מזיקה. הגירת החשבון מופעלת מהחשבון הישן. remove: הסרת שם נרדף appearance: - advanced_web_interface: ממשק ווב מתקדם - advanced_web_interface_hint: 'אם ברצונך לעשות שימוש במלוא רוחב המסך, ממשק הווב המתקדם מאפשר לך להגדיר עמודות רבות ושונות כדי לראות בו זמנית כמה מידע שתרצה/י: פיד הבית, התראות, פרהסיה ומספר כלשהו של רשימות ותגיות.' animations_and_accessibility: הנפשות ונגישות - confirmation_dialogs: חלונות אישור discovery: תגליות localization: body: מסטודון מתורגם על ידי מתנדבים. diff --git a/config/locales/hr.yml b/config/locales/hr.yml index 7d04d7278c83bc..4439460df6c218 100644 --- a/config/locales/hr.yml +++ b/config/locales/hr.yml @@ -79,7 +79,6 @@ hr: aliases: add_new: Stvori alias appearance: - advanced_web_interface: Napredno web sučelje localization: body: Mastodon prevode dobrovoljci. guide_link_text: Svi mogu doprinjeti. diff --git a/config/locales/hu.yml b/config/locales/hu.yml index e85f476e4dc270..86e2ed919b62ce 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -1186,10 +1186,7 @@ hu: hint_html: Ha másik fiókról kívánsz átlépni erre a fiókra, itt létrehozhatsz egy aliast, amelyre szükség van, mielőtt folytathatod a követők áthelyezését a régi fiókból erre. Ez az áthelyezés önmagában ártalmatlan és visszafordítható folyamat. A fiók áttelepítése a régi fiókból indul el. remove: Alias szétkapcsolása appearance: - advanced_web_interface: Speciális webes felület - advanced_web_interface_hint: 'Ha szeretnéd, a képernyő teljes szélességét kihasználhatod. A speciális webes felülettel különböző oszlopokat állíthatsz be, hogy egyszerre annyi információt láthass, amennyit csak akarsz: Kezdőoldal, értesítések, föderációs idővonal, bármennyi lista vagy hashtag.' animations_and_accessibility: Animáció és akadálymentesítés - confirmation_dialogs: Megerősítő párbeszédablakok discovery: Felfedezés localization: body: A Mastodont önkéntesek fordítják. diff --git a/config/locales/hy.yml b/config/locales/hy.yml index 933f8a4fa75e78..75220ecb13bbc1 100644 --- a/config/locales/hy.yml +++ b/config/locales/hy.yml @@ -433,10 +433,7 @@ hy: new_trending_statuses: title: Թրենդային գրառումներ appearance: - advanced_web_interface: Սյունակավոր ինտերֆեյս - advanced_web_interface_hint: Եթէ ցանկանում ես օգտագործել էկրանիդ ամբողջ լայնքը, ապա ընդլայնուած վեբ ինտերֆեյսով հնարաւոր է էկրանը բաժանել սիւնակների՝ զուգահեռ տեսնելու տարբեր տիպի ինֆորմացիա՝ տեղական հոսքը, ծանուցումները, ֆեդերացված հոսքը, և ցանկացած թվի ցուցակ ու հեշթեգ։ animations_and_accessibility: Անիմացիաներ եւ հասանելիութիւն - confirmation_dialogs: Հաստատման պատուհաններ discovery: Բացայայտում localization: body: Մաստոդոնը թարգմանուում է կամաւորների կողմից։ diff --git a/config/locales/ia.yml b/config/locales/ia.yml index 019e3f8438dec6..5a4c0ba4237175 100644 --- a/config/locales/ia.yml +++ b/config/locales/ia.yml @@ -1182,10 +1182,7 @@ ia: hint_html: Si tu vole migrar de un altere conto a iste, tu pote crear un alias ci, que es necessari pro poter transferer le sequitores del conto ancian a iste. Iste action per se es innocue e reversibile. Le migration del conto es initiate desde le conto ancian. remove: Disligar alias appearance: - advanced_web_interface: Interfacie web avantiate - advanced_web_interface_hint: 'Si tu vole utilisar tote le largessa de tu schermo, le interfacie web avantiate te permitte configurar multe columnas differente pro vider al mesme tempore tante informationes como tu vole: pagina principal, notificationes, chronologia federate, un numero illimitate de listas e hashtags.' animations_and_accessibility: Animationes e accessibilitate - confirmation_dialogs: Dialogos de confirmation discovery: Discoperta localization: body: Mastodon es traducite per voluntarios. diff --git a/config/locales/id.yml b/config/locales/id.yml index 3489519f847096..81fc5903107240 100644 --- a/config/locales/id.yml +++ b/config/locales/id.yml @@ -862,10 +862,7 @@ id: hint_html: Jika Anda ingin pindah dari akun lain ke sini, Anda dapat membuat alias, yang dilakukan sebelum Anda setuju dengan memindah pengikut dari akun lama ke akun sini. Aksi ini tidak berbahaya dan tidak bisa dikembalikan. Pemindahan akun dimulai dari akun lama. remove: Hapus tautan alias appearance: - advanced_web_interface: Antarmuka web tingkat lanjut - advanced_web_interface_hint: 'Jika Anda ingin memanfaatkan seluruh lebar layar Anda, antarmuka web tingkat lanjut memungkinkan Anda mengonfigurasi beragam kolom untuk menampilkan informasi sebanyak yang Anda inginkan: Beranda, notifikasi, linimasa gabungan, daftar, dan tagar.' animations_and_accessibility: Animasi dan aksesibilitas - confirmation_dialogs: Dialog konfirmasi discovery: Jelajah localization: body: Mastodon diterjemahkan oleh sukarelawan. diff --git a/config/locales/ie.yml b/config/locales/ie.yml index d202e96d491e37..ce219a9d6826bd 100644 --- a/config/locales/ie.yml +++ b/config/locales/ie.yml @@ -982,10 +982,7 @@ ie: hint_html: Si tu vole mover de un altri conto a ti-ci, ci tu posse crear un alias, quel es besonat ante que tu posse proceder a mover sequitores del antiqui conto a ti-ci. Ti-ci action, sol, es ínnociv e reversibil. Li conto-migration es initiat del antiqui conto. remove: Desconexer alias appearance: - advanced_web_interface: Avansat web-interfacie - advanced_web_interface_hint: 'Si tu vole usar li tot largore de tui ecran, li avansat web-interfacie permisse que tu mey configurar mult columnes diferent por vider tam mult information simultanmen quam tu vole: Hem, federat témpor-linea, quelcunc númere de listes e hashtags.' animations_and_accessibility: Animationes e accessibilitá - confirmation_dialogs: Dialogs de confirmation discovery: Decovriment localization: body: Mastodon es traductet de voluntarios. diff --git a/config/locales/io.yml b/config/locales/io.yml index 36d4ce251fdf63..eaca822f1afdbd 100644 --- a/config/locales/io.yml +++ b/config/locales/io.yml @@ -1097,10 +1097,7 @@ io: hint_html: Se vu volas transferesar de altra konto a co, hike vu povas krear alternativnomo, quo bezonesas ante vu povas durigar transferar sequanti de la olda konto a co. Ca ago esas nedanjeroza e inversigebla. Kontomigro komencesas de la olda konto. remove: Deligez alternative nomo appearance: - advanced_web_interface: Altnivela retintervizajo - advanced_web_interface_hint: 'Se vu volas uzar tota skrenlongeso, altnivela retintervizajo povigas vu modifikar multa dessama kolumni por vida multa informi en sama tempo quale vu volas: Hemo, savigi, fratara tempolineo, multa listi e gretvorti.' animations_and_accessibility: Animi e adirebleso - confirmation_dialogs: Konfirmdialogi discovery: Deskovro localization: body: Mastodon tradukesas da voluntarii. diff --git a/config/locales/is.yml b/config/locales/is.yml index 39a2150fb5aaf3..acf5fa58735a5d 100644 --- a/config/locales/is.yml +++ b/config/locales/is.yml @@ -1188,10 +1188,7 @@ is: hint_html: Ef þú vilt flytjast af öðrum notandaaðgangi yfir á þennan, þá geturðu búið hér til samnefni, sem er nauðsynlegt áður en þú getur haldið áfram við að flytja fylgjendur af gamla notandaaðgangnum yfir á þennan aðgang. Þessi aðgerð er í sjálfu sér skaðlaus og afturkræf. Yfirfærsla notandaaðgangsins er síðan ræst á gamla notandaaðgangnum. remove: Aftengja samnefni appearance: - advanced_web_interface: Ítarlegt vefviðmót - advanced_web_interface_hint: 'Ef þú vilt geta notað alla skjábreiddina gefur ítarlegt vefviðmót þér færi á að stilla marga mismunandi dálka svo hægt sé að sjá eins miklar upplýsingar í einu eins og þér hentar: Heim, tilkynningar, sameiginleg tímalína, ótiltekinn fjöldi lista og myllumerkja.' animations_and_accessibility: Hreyfingar og algilt aðgengi - confirmation_dialogs: Staðfestingargluggar discovery: Uppgötvun localization: body: Mastodon er þýtt af sjálfboðaliðum. diff --git a/config/locales/it.yml b/config/locales/it.yml index 264119d7e374c6..0735e4ed550c4c 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -1182,12 +1182,7 @@ it: hint_html: Se vuoi trasferirti da un altro account a questo, qui puoi creare un alias, che è necessario prima di poter spostare i seguaci dal vecchio account a questo. Questa azione è innocua e reversibile. La migrazione dell'account è avviata dal vecchio account. remove: Scollega alias appearance: - advanced_web_interface: Interfaccia web avanzata - advanced_web_interface_hint: |- - Se vuoi utilizzare l'intera larghezza dello schermo, l'interfaccia web avanzata ti consente di configurare varie colonne per mostrare più informazioni allo stesso tempo, secondo le tue preferenze: - Home, notifiche, timeline federata, qualsiasi numero di liste e etichette. animations_and_accessibility: Animazioni e accessibilità - confirmation_dialogs: Dialoghi di conferma discovery: Scoperta localization: body: Mastodon è tradotto da volontari. diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 184ab506d64a4a..8feb830f0fd82f 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -1151,10 +1151,7 @@ ja: hint_html: 他のアカウントからこのアカウントにフォロワーを引き継いで引っ越したい場合、ここでエイリアスを作成しておく必要があります。エイリアス自体は無害で、取り消すことができます。引っ越しは以前のアカウント側から開始する必要があります。 remove: エイリアスを削除 appearance: - advanced_web_interface: 上級者向けUI - advanced_web_interface_hint: ディスプレイを幅いっぱいまで活用したい場合、上級者向け UI をおすすめします。ホーム、通知、連合タイムライン、更にはリストやハッシュタグなど、様々な異なるカラムから望む限りの情報を一度に受け取れるような設定が可能になります。 animations_and_accessibility: アニメーションとアクセシビリティー - confirmation_dialogs: 確認ダイアログ discovery: 見つける localization: body: Mastodonは有志によって翻訳されています。 diff --git a/config/locales/kab.yml b/config/locales/kab.yml index 61fb800301dba8..a8fd955ee48588 100644 --- a/config/locales/kab.yml +++ b/config/locales/kab.yml @@ -538,7 +538,6 @@ kab: new_trending_tags: title: Ihacṭagen inezzaɣ appearance: - advanced_web_interface: Agrudem n web leqqayen discovery: Asnirem localization: body: Mastodon suqqlen-t-id yiwiziwen. diff --git a/config/locales/kk.yml b/config/locales/kk.yml index b877cb09c79f83..628dcbc3f82cd2 100644 --- a/config/locales/kk.yml +++ b/config/locales/kk.yml @@ -308,10 +308,7 @@ kk: deleted_msg: Алиасты сәтті алып тастаңыз. Осы есептік жазбадан екіншіге ауысу мүмкін болмайды. remove: Алиас сілтемесін алып тастау appearance: - advanced_web_interface: Кеңейтілген веб-интерфейс - advanced_web_interface_hint: 'Егер сіз бүкіл экранның енін пайдаланғыңыз келсе, кеңейтілген веб-интерфейс сізге көптеген ақпаратты бір уақытта қалағанша көру үшін әр түрлі бағандарды конфигурациялауға мүмкіндік береді: негізгі бет, ескертпелер, жаһандық желі, тізім мен хэштегтерді.' animations_and_accessibility: Анимациялар және қолжетімділік - confirmation_dialogs: Пікірталас диалогтары discovery: Пікірталас sensitive_content: Нәзік контент application_mailer: diff --git a/config/locales/ko.yml b/config/locales/ko.yml index 5c158223c13ca2..2503706bd0d454 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -1165,10 +1165,7 @@ ko: hint_html: 다른 계정에서 이 계정으로 옮기길 원하는 경우, 여기에서 별칭을 만들 수 있습니다, 기존 계정의 팔로워를 이쪽으로 옮기고 싶은 경우 필요한 과정입니다. 이 행동 자체는 해롭지 않고 되돌리기가 가능합니다.계정 이주는 이전 계정에서 착수하게 됩니다 remove: 별칭 연결 끊기 appearance: - advanced_web_interface: 고급 웹 인터페이스 - advanced_web_interface_hint: '화면의 가로폭을 가득 채우고 싶다면, 고급 웹 인터페이스는 한 번에 여러 정보를 볼 수 있도록 여러 컬럼을 설정할 수 있도록 합니다: 홈, 알림, 연합타임라인, 리스트, 해시태그 등' animations_and_accessibility: 애니메이션과 접근성 - confirmation_dialogs: 확인 대화상자 discovery: 발견하기 localization: body: 마스토돈은 자원봉사자들에 의해 번역되었습니다. diff --git a/config/locales/ku.yml b/config/locales/ku.yml index b05f49cd471fc3..31a0a1cf18b450 100644 --- a/config/locales/ku.yml +++ b/config/locales/ku.yml @@ -875,10 +875,7 @@ ku: hint_html: Ku tu dixwazî ji ajimêreke din bar bike bo yekî din, li vir tu dikarî bernavekê biafirîne, ku pêdivî ye berî ku tu bi şopandina şopînerên xwe ji ajimêra kevn ber bi vê yekê biçe. Ev çalakî bi serê xwe bê ziyan û vegere.Koçberiya ajimêr ji ajimêreke kevin dest pê dike. remove: Girêdana nûçikê rake appearance: - advanced_web_interface: Navrûya tevnê yê pêşketî - advanced_web_interface_hint: 'Ku tu bixwazî tevahiya ferehiya dîmendera xwe bi kar bînî, navrûya pêşketî ya tevnê dihêle ku tu gelek stûnên cihêreng saz bikî da ku di heman demê de bi qasî ku tu dixwazî zanyariyan bibînî: Serrûpel, agahdarî, demnameya giştî, her hejmarek ji rêzik û hashtagan.' animations_and_accessibility: Anîmasyon û gihînî - confirmation_dialogs: Gotûbêjên piştrastkirî discovery: Vedîtin localization: body: Mastodon ji aliyê xêrxwazan tê wergerandin. diff --git a/config/locales/lad.yml b/config/locales/lad.yml index 06bc932ea4d4b1..676de75e018145 100644 --- a/config/locales/lad.yml +++ b/config/locales/lad.yml @@ -1085,10 +1085,7 @@ lad: hint_html: Si keres migrar de otro kuento a este, aki puedes kriyar un alias, kale proseder antes de ampesar a mover suivantes del kuento anterior a este. Esta aksion por si mezma es inofensiva i reversivle. La migrasyon del kuento se inisya dizde el kuento viejo. remove: Dezata alias appearance: - advanced_web_interface: Enterfaz web avanzada - advanced_web_interface_hint: 'Si keres utilizar todo el ancho de ekran, la enterfaz web avanzada te permete konfigurar varias kolumnas desferentes para ver tanta enformasyon al mezmo tiempo komo keras: Linya prinsipala, avizos, linya de tiempo federada, kualkier numero de listas i etiketas.' animations_and_accessibility: Animasyones i aksesivilita - confirmation_dialogs: Dialogos de konfirmasyon discovery: Diskuvrimiento localization: body: Mastodon es trezladado por volontarios. diff --git a/config/locales/lt.yml b/config/locales/lt.yml index eb69f2b06d518f..d9eaf61e370c9b 100644 --- a/config/locales/lt.yml +++ b/config/locales/lt.yml @@ -805,10 +805,7 @@ lt: title: Tendencingos saitažodžiai subject: Naujos tendencijos peržiūrimos %{instance} appearance: - advanced_web_interface: Išplėstinė žiniatinklio sąsaja - advanced_web_interface_hint: 'Jei nori išnaudoti visą ekrano plotį, išplėstinė žiniatinklio sąsaja leidžia sukonfigūruoti daug skirtingų stulpelių, kad vienu metu matytum tiek informacijos, kiek tik nori: Pagrindinis, pranešimai, federacinė laiko skalė, bet kokie sąrašai ir saitažodžiai.' animations_and_accessibility: Animacijos ir pritaikymas neįgaliesiems - confirmation_dialogs: Patvirtinimo dialogai discovery: Atradimas localization: body: Mastodon verčia savanoriai. diff --git a/config/locales/lv.yml b/config/locales/lv.yml index 979933b196bb63..1a97adc6d0ef10 100644 --- a/config/locales/lv.yml +++ b/config/locales/lv.yml @@ -1163,10 +1163,7 @@ lv: hint_html: Ja vēlies pāriet no cita konta uz šo, šeit vari izveidot aizstājvārdu, kas ir nepieciešams, lai varētu turpināt sekotāju pārvietošanu no vecā konta uz šo. Šī darbība pati par sevi ir nekaitīga un atgriezeniska. Konta migrācija tiek sākta no vecā konta. remove: Atsaistīt aizstājvārdu appearance: - advanced_web_interface: Paplašinātā tīmekļa saskarne - advanced_web_interface_hint: 'Ja vēlies izmantot visu ekrāna platumu, paplašinātā tīmekļa saskarne ļauj konfigurēt daudzas dažādas kolonnas, lai vienlaikus redzētu tik daudz informācijas, cik vēlies: Sākums, paziņojumi, apvienotā ziņu lenta, neierobežots skaits sarakstu un tēmturu.' animations_and_accessibility: Animācijas un pieejamība - confirmation_dialogs: Apstiprināšanas dialogi discovery: Atklāšana localization: body: Mastodon ir tulkojuši brīvprātīgie. diff --git a/config/locales/ms.yml b/config/locales/ms.yml index 2df1e0c2b8fdd8..dc3c9c36a9b069 100644 --- a/config/locales/ms.yml +++ b/config/locales/ms.yml @@ -957,10 +957,7 @@ ms: hint_html: Jika anda ingin beralih dari akaun lain ke akaun ini, di sini anda boleh membuat alias, yang diperlukan sebelum anda boleh meneruskan dengan memindahkan pengikut dari akaun lama ke akaun ini. Tindakan ini dengan sendirinya tidak berbahaya dan boleh diterbalikkan. Penghijrahan akaun dimulakan daripada akaun lama. remove: Nyahpaut alias appearance: - advanced_web_interface: Antara muka web lanjutan - advanced_web_interface_hint: 'Jika anda ingin menggunakan keseluruhan lebar skrin anda, antara muka web lanjutan membolehkan anda mengkonfigurasi banyak lajur berbeza untuk melihat seberapa banyak maklumat pada masa yang sama seperti yang anda mahu: Laman Utama, pemberitahuan, garis masa bersekutu, sebarang bilangan senarai dan hashteg.' animations_and_accessibility: Animasi dan kebolehaksesan - confirmation_dialogs: Dialog pengesahan discovery: Penemuan localization: body: Mastodon diterjemahkan oleh sukarelawan. diff --git a/config/locales/my.yml b/config/locales/my.yml index 644e648ac54f93..bdf051ca6ee46a 100644 --- a/config/locales/my.yml +++ b/config/locales/my.yml @@ -938,10 +938,7 @@ my: hint_html: အခြားအကောင့်မှ ဤအကောင့်သို့ ပြောင်းရွှေ့လိုပါက ဤနေရာတွင် အကောင့်ဟောင်းမှ စောင့်ကြည့်သူများကို ဤအကောင့်သို့ မရွှေ့မီ လိုအပ်သော အမည်တစ်ခု ဖန်တီးနိုင်ပါသည်။ ဤလုပ်ဆောင်ချက်မှာ အန္တရာယ်ကင်းပြီး ပြန်ပြောင်းလုပ်ဆောင်နိုင်ပါသည်အကောင့်ပြောင်းရွှေ့ခြင်းကို အကောင့်ဟောင်းမှ စတင်လုပ်ဆောင်ပါသည်။ remove: နာမည်တူများကို လင့်ခ်ဖြုတ်ပါ appearance: - advanced_web_interface: အဆင့်မြင့်ဝဘ်ပုံစံ - advanced_web_interface_hint: အဆင့်မြင့်ဝဘ်အင်တာဖေ့စ်သည် မျက်နှာပြင်အကျယ်တစ်ခုလုံးကို သင် အသုံးပြုလိုပါက သင်အလိုရှိသည့်အတိုင်း အချက်အလက်များကို တစ်ပြိုင်နက်ကြည့်ရှုရန် ကော်လံများစွာဖြင့် ပြသနိုင်သည် - ပင်မစာမျက်နှာ၊ အကြောင်းကြားချက်များ၊ ဖက်ဒီစာမျက်နှာ၊ စာရင်းအရေအတွက်နှင့် hashtags မှန်သမျှကို ချိန်ညှိဖော်ပြနိုင်သည်။ animations_and_accessibility: လှုပ်ရှားမှုဆိုင်ရာများ - confirmation_dialogs: အတည်ပြုချက် ဒိုင်ယာလော့ခ်များ discovery: ရှာဖွေတွေ့ရှိမှု localization: body: Mastodon ကို စေတနာ့ဝန်ထမ်းများမှ ဘာသာပြန်ထားပါသည်။ diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 2a814367cf024d..e2d162115d6fb5 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -1186,10 +1186,7 @@ nl: hint_html: Wanneer je vanaf een ander account naar dit account wilt verhuizen, kun je hier een alias aanmaken. Dit is nodig voordat je verder kunt gaan met het verhuizen van volgers van het oude naar dit nieuwe account. Deze actie is op zich ongevaarlijk en omkeerbaar. De accountmigratie wordt gestart vanaf het oude account. remove: Alias ontkoppelen appearance: - advanced_web_interface: Geavanceerde webomgeving - advanced_web_interface_hint: 'Wanneer je van de hele schermbreedte gebruik wilt maken, stelt de geavanceerde webomgeving je in staat om meerdere verschillende kolommen te configureren. Hiermee kun je zoveel mogelijk informatie op hetzelfde moment bekijken, zoals: Start, meldingen, de globale tijdlijn, meerdere lijsten en hashtags.' animations_and_accessibility: Animaties en toegankelijkheid - confirmation_dialogs: Bevestigingen discovery: Ontdekken localization: body: Mastodon wordt door vrijwilligers vertaald. diff --git a/config/locales/nn.yml b/config/locales/nn.yml index bd59f5a1a671a7..6efd85d033ea21 100644 --- a/config/locales/nn.yml +++ b/config/locales/nn.yml @@ -1182,10 +1182,7 @@ nn: hint_html: Viss du vil flytta frå ein annan konto til denne, kan du laga eit alias her. Det treng du før du kan halda fram med å flytta fylgjarar frå den gamle kontoen til dnene. Denne handlinga er i seg sjølv harmlaus og kan angrast. Du har starta overføringa frå den gamle kontoen. remove: Fjern aliaslenking appearance: - advanced_web_interface: Avansert nettgrensesnitt - advanced_web_interface_hint: 'Om du vil bruke heile skjermbreidda di, let det avanserte nettgrensesnittet deg setje opp mange ulike kolonnar for å sjå så mykje informasjon du vil på ein gong: Heim, varsel, samla tidslinje, og kva som helst antall lister og emneknaggar.' animations_and_accessibility: Animasjonar og tilgjengelegheit - confirmation_dialogs: Bekreftelsesdialoger discovery: Oppdaging localization: body: Mastodon er omsett av friviljuge. diff --git a/config/locales/no.yml b/config/locales/no.yml index a10f4c6a6aa592..72cbad788e35ed 100644 --- a/config/locales/no.yml +++ b/config/locales/no.yml @@ -997,10 +997,7 @@ hint_html: Dersom du vil flytte fra en annen konto til den, kan du lage et alias her, som er påkrevd før du kan gå videre med å flytte følgere fra den gamle kontoen til den nye. Handlingen i seg selv er harmløs og reversibel. Kontoflyttingen har blitt satt i gang fra den gamle kontoen. remove: Fjern aliaslenking appearance: - advanced_web_interface: Avansert nettgrensesnitt - advanced_web_interface_hint: 'Hvis du ønsker å bruke hele skjermbredden din, lar det avanserte nettgrensesnittet deg sette opp mange forskjellige kolonner for å se så mye informasjon på én gang som du vil: Hjem, varslinger, fellestidslinjen, og ethvert antall lister og emneknagger.' animations_and_accessibility: Animasjoner og tilgjengelighet - confirmation_dialogs: Bekreftelsesdialoger discovery: Oppdagelse localization: body: Mastodon er oversatt av frivillige. diff --git a/config/locales/oc.yml b/config/locales/oc.yml index 51f8d8c7b4d004..1e34dcc6ea4d32 100644 --- a/config/locales/oc.yml +++ b/config/locales/oc.yml @@ -442,10 +442,7 @@ oc: add_new: Crear un alias remove: Desligar l’alias appearance: - advanced_web_interface: Interfàcia web avançada - advanced_web_interface_hint: 'Se volètz utilizar la nautor complèta de l’ecran, l’interfàcia web avançada vos permet de configurar diferentas colomnas per mostrar tan d’informacions que volètz : Acuèlh, notificacions, flux d’actualitat, e d’autras listas e etiquetas.' animations_and_accessibility: Animacion e accessibilitat - confirmation_dialogs: Fenèstras de confirmacion discovery: Descobèrta localization: body: Mastodon es traduch per de benevòls. diff --git a/config/locales/pl.yml b/config/locales/pl.yml index 20b391c8675c8c..418d908f8c2f99 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -1199,10 +1199,7 @@ pl: hint_html: Jeżeli chcesz przenieść się z innego konta na to, możesz utworzyć alias, który jest wymagany zanim zaczniesz przenoszenie obserwacji z poprzedniego konta na to. To działanie nie wyrządzi szkód i jest odwracalne. Migracja konta jest inicjowana ze starego konta. remove: Odłącz alias appearance: - advanced_web_interface: Zaawansowany interfejs użytkownika - advanced_web_interface_hint: Jeśli chcesz użyć pełną szerokość swojego ekranu, zaawansowany interfejs użytkownika pozwala Ci skonfigurować wiele różnych kolumn, by zobaczyć jak najwięcej informacji kiedy tylko chcesz. Strona główna, Powiadomienia, Globalna oś czasu, dowolna ilość list i hasztagów. animations_and_accessibility: Animacje i dostępność - confirmation_dialogs: Dialogi potwierdzenia discovery: Odkrywanie localization: body: Mastodon jest tłumaczony przez wolontariuszy. diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index 4686305e6470d2..5af8275951087e 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -1182,10 +1182,7 @@ pt-BR: hint_html: Se você quiser migrar de uma outra conta para esta, você pode criar um atalho aqui, o que é necessário antes que você possa migrar os seguidores da conta antiga para esta. Esta ação por si só é inofensiva e reversível. A migração da conta é iniciada pela conta antiga. remove: Desvincular alias appearance: - advanced_web_interface: Interface avançada de colunas - advanced_web_interface_hint: 'Se você deseja usar toda a sua largura de tela, a interface avançada permite que você configure muitas colunas diferentes para ver tantas informações ao mesmo tempo quanto você deseja: Página inicial, notificações, linha local, linha global, qualquer número de listas e hashtags.' animations_and_accessibility: Animações e acessibilidade - confirmation_dialogs: Diálogos de confirmação discovery: Descobrir localization: body: Mastodon é traduzido por voluntários. diff --git a/config/locales/pt-PT.yml b/config/locales/pt-PT.yml index 3ee797564854aa..208a91eb531641 100644 --- a/config/locales/pt-PT.yml +++ b/config/locales/pt-PT.yml @@ -1182,10 +1182,7 @@ pt-PT: hint_html: Se quiseres mudar de outra conta para esta, podes criar aqui um pseudónimo, que é necessário antes de poderes prosseguir com a migração de seguidores da conta antiga para esta. Esta ação por si só é inofensiva e reversível. A migração da conta é iniciada a partir da conta antiga. remove: Desvincular pseudónimo appearance: - advanced_web_interface: Interface web avançada - advanced_web_interface_hint: 'Se quiseres utilizar toda a largura do teu ecrã, a interface web avançada permite configurar várias colunas diferentes para veres tanta informação ao mesmo tempo quanto quiseres: página inicial, notificações, cronologia federada, qualquer número de listas e etiquetas.' animations_and_accessibility: Animações e acessibilidade - confirmation_dialogs: Caixas de confirmação discovery: Descobrir localization: body: O Mastodon é traduzido por voluntários. diff --git a/config/locales/ru.yml b/config/locales/ru.yml index cdccbb65e11bdb..12c73955791dfb 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -1202,10 +1202,7 @@ ru: hint_html: Если вы собираетесь переехать с другой учётной записи на эту, то, прежде чем вы сможете перенести подписчиков со старой учётной записи, вы должны связать учётные записи здесь. Это действие само по себе безвредно и обратимо. Начать переезд можно только со старой учётной записи. remove: Отвязать учётную запись appearance: - advanced_web_interface: Многоколоночный интерфейс - advanced_web_interface_hint: 'Многоколоночный интерфейс даёт возможность использовать всю ширину экрана, позволяя вам обозревать столько информации, сколько вы захотите. Вы можете добавить множество различных столбцов: главную ленту, уведомления, глобальную ленту, неограниченное количество списков и хештегов.' animations_and_accessibility: Анимации и доступность - confirmation_dialogs: Диалоговые окна подтверждений discovery: Актуальное localization: body: Mastodon переводится добровольцами. diff --git a/config/locales/sc.yml b/config/locales/sc.yml index 606b47cc40d19f..5757e49077db9d 100644 --- a/config/locales/sc.yml +++ b/config/locales/sc.yml @@ -655,10 +655,7 @@ sc: hint_html: Si boles mudare dae un'àteru contu a custu, inoghe as a pòdere creare unu nomìngiu, chi est rechestu in antis de sighire cun sa tràmuda de is persones chi ti sighint dae su contu betzu a custu. Custa atzione est innòcua e reversìbile. Tràmuda de su contu betzu cumintzada. remove: Disconnete su nomìngiu appearance: - advanced_web_interface: Interfache web avantzada - advanced_web_interface_hint: 'Si boles impreare totu sa largària de s''ischermu, s''interfache web avantzada ti permitit de cunfigurare diversas colunnas pro bìdere meda prus informatzione in contemporànea: printzipale, notìficas, lìnia de tempus federada e cale si siat nùmeru de listas e etichetas.' animations_and_accessibility: Animatziones e atzessibilidade - confirmation_dialogs: Diàlogos de cunfirmatzione discovery: Iscoberta localization: body: Mastodon est bortadu in manera voluntària. diff --git a/config/locales/sco.yml b/config/locales/sco.yml index 5c1e451446b47f..f90c7e692c2d84 100644 --- a/config/locales/sco.yml +++ b/config/locales/sco.yml @@ -868,10 +868,7 @@ sco: hint_html: If ye'r wantin fir tae flit fae anither accoont tae this ane, ye kin mak a alias here, this is requirt afore ye kin gae forret flittin follaers fae the auld accoont tae this ane. This action bi an o itsel is hermless an reversible. The accoont migration is initiatie fae the auld accoont. remove: Unlink alias appearance: - advanced_web_interface: Advanced wab interface - advanced_web_interface_hint: 'Gin ye''r wantin fir tae mak uise o the ful width o yer screen, the advanced wab interface lets ye configure a wheen o different columns sae''s ye kin see as muckle information at the same time as ye want: Hame, notes, federatit timeline, onie nummer o lists an hashtags.' animations_and_accessibility: Animations an accessibility - confirmation_dialogs: Confirmation dialogs discovery: Discovery localization: body: Mastodon is translatit bi volunteers. diff --git a/config/locales/si.yml b/config/locales/si.yml index e6b561b2ba1212..dee5e3bb959574 100644 --- a/config/locales/si.yml +++ b/config/locales/si.yml @@ -754,10 +754,7 @@ si: hint_html: ඔබට වෙනත් ගිණුමකින් මෙය වෙත මාරු වීමට අවශ්‍ය නම්, මෙහිදී ඔබට අන්වර්ථ නාමයක් සෑදිය හැක, එය පැරණි ගිණුමෙන් අනුගාමිකයින් මෙම ගිණුමට ගෙන යාමට පෙර අවශ්‍ය වේ. මෙම ක්‍රියාවම හානිකර නොවන සහ ආපසු හැරවිය හැකිවේ. ගිණුම් සංක්‍රමණය පැරණි ගිණුමෙන් ආරම්භ වේ. remove: අන්වර්ථය විසන්ධි කරන්න appearance: - advanced_web_interface: සංකීර්ණ අතුරු මුහුණත - advanced_web_interface_hint: 'ඔබට ඔබේ සම්පූර්ණ තිරයේ පළල භාවිතා කිරීමට අවශ්‍ය නම්, උසස් වෙබ් අතුරු මුහුණත ඔබට අවශ්‍ය පරිදි එකම වේලාවක බොහෝ තොරතුරු බැලීමට විවිධ තීරු වින්‍යාස කිරීමට ඉඩ දෙයි: නිවස, දැනුම්දීම්, ෆෙඩරේටඩ් කාලරාමුව, ඕනෑම ලැයිස්තු සහ හැෂ් ටැග්.' animations_and_accessibility: සජීවිකරණ සහ ප්‍රවේශ්‍යතාව - confirmation_dialogs: තහවුරු කිරීමේ සංවාද discovery: සොයාගැනීම localization: body: මාස්ටඩන් ස්වේච්ඡාවෙන් පරිවර්තනය කර ඇත. diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index bbc1086072cf06..1bad98c0b6c63b 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -54,8 +54,10 @@ en: password: Use at least 8 characters phrase: Will be matched regardless of casing in text or content warning of a post scopes: Which APIs the application will be allowed to access. If you select a top-level scope, you don't need to select individual ones. + setting_advanced_layout: Display Mastodon as a multi-column layout, allowing you to view the timeline, notifications, and a third column of your choosing. Not recommended for smaller screens. setting_aggregate_reblogs: Do not show new boosts for posts that have been recently boosted (only affects newly-received boosts) setting_always_send_emails: Normally e-mail notifications won't be sent when you are actively using Mastodon + setting_boost_modal: When enabled, boosting will first open a confirmation dialog in which you can change the visibility of your boost. setting_default_quote_policy_private: Followers-only posts authored on Mastodon can't be quoted by others. setting_default_quote_policy_unlisted: When people quote you, their post will also be hidden from trending timelines. setting_default_sensitive: Sensitive media is hidden by default and can be revealed with a click @@ -234,12 +236,12 @@ en: setting_aggregate_reblogs: Group boosts in timelines setting_always_send_emails: Always send e-mail notifications setting_auto_play_gif: Auto-play animated GIFs - setting_boost_modal: Show confirmation dialog before boosting + setting_boost_modal: Control boosting visibility setting_default_language: Posting language setting_default_privacy: Posting visibility setting_default_quote_policy: Who can quote setting_default_sensitive: Always mark media as sensitive - setting_delete_modal: Show confirmation dialog before deleting a post + setting_delete_modal: Warn me before deleting a post setting_disable_hover_cards: Disable profile preview on hover setting_disable_swiping: Disable swiping motions setting_display_media: Media display @@ -249,7 +251,7 @@ en: setting_emoji_style: Emoji style setting_expand_spoilers: Always expand posts marked with content warnings setting_hide_network: Hide your social graph - setting_missing_alt_text_modal: Show confirmation dialog before posting media without alt text + setting_missing_alt_text_modal: Warn me before posting media without alt text setting_reduce_motion: Reduce motion in animations setting_system_font_ui: Use system's default font setting_system_scrollbars_ui: Use system's default scrollbar diff --git a/config/locales/sk.yml b/config/locales/sk.yml index e6db6013abf987..ac3d5d8ee96b2e 100644 --- a/config/locales/sk.yml +++ b/config/locales/sk.yml @@ -803,10 +803,7 @@ sk: deleted_msg: Alias úspešne odstránený. Presun z tamtoho účtu na tento už viac nebude možný. remove: Odpoj alias appearance: - advanced_web_interface: Pokročilé webové rozhranie - advanced_web_interface_hint: 'Ak chcete využiť celkú šírku svojej obrazovky, pokročilé webové rozhranie vám umožňuje nastaviť mnoho rôznych stĺpcov, aby ste videli naraz toľko informácií, koľko chcete: Domov, upozornenia, federovanú časovú os a ľubovolný počet zoznamov či hashtagov.' animations_and_accessibility: Animácie a prístupnosť - confirmation_dialogs: Potvrdzovacie dialógy discovery: Objavovanie localization: body: Mastodon je prekladaný dobrovoľníkmi. diff --git a/config/locales/sl.yml b/config/locales/sl.yml index 123e8c47c07be0..3b957a1569a86e 100644 --- a/config/locales/sl.yml +++ b/config/locales/sl.yml @@ -1145,10 +1145,7 @@ sl: hint_html: Če se želite preseliti iz drugega računa v tega, lahko tukaj ustvarite vzdevek, ki je potreben, preden lahko nadaljujete s selitvijo sledilcev iz starega računa v tega. To dejanje je samo po sebi neškodljivo in povratno. Selitev računa sprožite iz starega računa. remove: Razveži vzdevek appearance: - advanced_web_interface: Napredni spletni vmesnik - advanced_web_interface_hint: 'Če želite uporabiti celotno širino zaslona, vam napredni spletni vmesnik omogoča, da si nastavite več različnih stolpcev in da si hkrati ogledate toliko informacij, kot želite: domačo stran, obvestila, združeno časovnico, poljubno število seznamov in ključnikov.' animations_and_accessibility: Animacije in dostopnost - confirmation_dialogs: Potrditvena okna discovery: Odkrito localization: body: Mastodon prevajamo prostovoljci. diff --git a/config/locales/sq.yml b/config/locales/sq.yml index 5a978ed66684df..7842a7569f76f0 100644 --- a/config/locales/sq.yml +++ b/config/locales/sq.yml @@ -1177,10 +1177,7 @@ sq: hint_html: Nëse doni të kaloni nga një llogari tjetër në këtë këtu, këtu mund të krijoni një alias, i cili është i domosdoshëm përpara se të ecni më tej me kalimin e ndjekësve prej llogarisë së vjetër te kjo këtu. Ky veprim, në vetvete, është i padëmshëm dhe i prapakthyeshëm. Migrimi i llogarisë fillohet prej llogarisë së vjetër. remove: Hiqe aliasin appearance: - advanced_web_interface: Ndërfaqe web e thelluar - advanced_web_interface_hint: 'Nëse doni të shfrytëzoni krejt gjerësinë e ekranit tuaj, ndërfaqja e thelluar web ju lejon të formësoni shumë shtylla për të parë në të njëjtën kohë aq hollësi sa doni: Kreu, njoftime, rrjedhë kohore të federuarash, çfarëdo numri listash dhe hashtag-ësh.' animations_and_accessibility: Animacione dhe përdorim nga persona me aftësi të kufizuara - confirmation_dialogs: Dialogë ripohimesh discovery: Zbulim localization: body: Mastodon-i përkthehet nga vullnetarë. diff --git a/config/locales/sr-Latn.yml b/config/locales/sr-Latn.yml index 3173aa34384761..9f422b058b606a 100644 --- a/config/locales/sr-Latn.yml +++ b/config/locales/sr-Latn.yml @@ -1003,10 +1003,7 @@ sr-Latn: hint_html: Ako želite da se preselite sa drugog naloga na ovaj, ovde možete napraviti pseudonim, koji je neophodan pre nego što možete nastaviti sa prebacivanjem pratilaca sa starog naloga na ovaj. Ova radnja sama po sebi je bezopasna i reverzibilna. Preseljenje naloga se inicira sa starog naloga. remove: Odveži pseudonim appearance: - advanced_web_interface: Napredno veb okruženje - advanced_web_interface_hint: 'Ako želite da iskoristite celu širinu ekrana, napredno veb okruženje vam omogućuje da konfigurišete mnogo različitih kolona da biste videli onoliko informacija u isto vreme koliko želite: početnu stranicu, obaveštenja, združenu vremensku liniju, bilo koji broj lista i heš oznaka.' animations_and_accessibility: Animacije i pristupačnost - confirmation_dialogs: Dijalozi potvrde discovery: Otkrivanje localization: body: Mastodon prevode dobrovoljci. diff --git a/config/locales/sr.yml b/config/locales/sr.yml index 9fc9ed255f79ea..b8d3ad1fc14d7b 100644 --- a/config/locales/sr.yml +++ b/config/locales/sr.yml @@ -1033,10 +1033,7 @@ sr: hint_html: Ако желите да се преселите са другог налога на овај, овде можете направити псеудоним, који је неопходан пре него што можете наставити са пребацивањем пратилаца са старог налога на овај. Ова радња сама по себи је безопасна и реверзибилна. Пресељење налога се иницира са старог налога. remove: Одвежи псеудоним appearance: - advanced_web_interface: Напредно веб окружење - advanced_web_interface_hint: 'Ако желите да искористите целу ширину екрана, напредно веб окружење вам омогућује да конфигуришете много различитих колона да бисте видели онолико информација у исто време колико желите: почетну страницу, обавештења, здружену временску линију, било који број листа и хеш ознака.' animations_and_accessibility: Анимације и приступачност - confirmation_dialogs: Дијалози потврде discovery: Откривање localization: body: Mastodon преводе добровољци. diff --git a/config/locales/sv.yml b/config/locales/sv.yml index 4a844f8a941864..df222cf147a4f7 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -1182,10 +1182,7 @@ sv: hint_html: Om du vill flytta från ett annat konto till detta kan du skapa ett alias här, detta krävs innan du kan fortsätta med att flytta följare från det gamla kontot till detta. Denna åtgärd är ofarlig och kan ångras. Kontomigreringen initieras från det gamla kontot.. remove: Avlänka alias appearance: - advanced_web_interface: Avancerat webbgränssnitt - advanced_web_interface_hint: 'Om du vill utnyttja hela skärmens bredd så kan du i det avancerade webbgränssnittet ställa in många olika kolumner för att se så mycket information samtidigt som du vill: Hem, notiser, federerad tidslinje, valfritt antal listor och hashtaggar.' animations_and_accessibility: Animationer och tillgänglighet - confirmation_dialogs: Bekräftelsedialoger discovery: Upptäck localization: body: Mastodon översätts av volontärer. diff --git a/config/locales/th.yml b/config/locales/th.yml index 9f4aeab65ffff0..46236daa91efd8 100644 --- a/config/locales/th.yml +++ b/config/locales/th.yml @@ -1091,10 +1091,7 @@ th: hint_html: หากคุณต้องการย้ายจากบัญชีอื่นไปยังบัญชีนี้ ที่นี่คุณสามารถสร้างนามแฝง ซึ่งจำเป็นก่อนที่คุณจะสามารถดำเนินการต่อด้วยการย้ายผู้ติดตามจากบัญชีเก่าไปยังบัญชีนี้ การกระทำนี้โดยตัวการกระทำเอง ไม่เป็นอันตรายและย้อนกลับได้ การโยกย้ายบัญชีเริ่มต้นจากบัญชีเก่า remove: เลิกเชื่อมโยงนามแฝง appearance: - advanced_web_interface: ส่วนติดต่อเว็บขั้นสูง - advanced_web_interface_hint: 'หากคุณต้องการใช้ประโยชน์จากความกว้างหน้าจอทั้งหมดของคุณ ส่วนติดต่อเว็บขั้นสูงอนุญาตให้คุณกำหนดค่าคอลัมน์ต่าง ๆ จำนวนมากเพื่อให้เห็นข้อมูลได้มากในเวลาเดียวกันเท่าที่คุณต้องการ: หน้าแรก, การแจ้งเตือน, เส้นเวลาที่ติดต่อกับภายนอก, รายการและแฮชแท็กจำนวนเท่าใดก็ได้' animations_and_accessibility: ภาพเคลื่อนไหวและการช่วยการเข้าถึง - confirmation_dialogs: กล่องโต้ตอบการยืนยัน discovery: การค้นพบ localization: body: Mastodon ได้รับการแปลโดยอาสาสมัคร diff --git a/config/locales/tr.yml b/config/locales/tr.yml index 6b53a1d191f53c..547cb5d30c8845 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -1186,10 +1186,7 @@ tr: hint_html: Başka bir hesaptan bu hesaba taşınmak istiyorsanız, takipçileri eski hesaptan bu hesaba taşımadan önce gerekli olan takma adı burada oluşturabilirsiniz. Bu eylem kendi başına zararsızdır ve geri döndürülebilir. Hesap taşıma işlemi eski hesaptan başlatılır. remove: Takma adların bağlantısını kaldır appearance: - advanced_web_interface: Gelişmiş web arayüzü - advanced_web_interface_hint: 'Tüm ekran genişliğinizden yararlanmak istiyorsanız, gelişmiş web arayüzü istediğiniz kadar bilgi görecek kadar çok sayıda farklı sütunu yapılandırmanıza olanak tanır: Anasayfa, bildirimler, birleşik zaman çizelgesi, istediğiniz sayıda liste ve etiket.' animations_and_accessibility: Animasyonlar ve erişilebilirlik - confirmation_dialogs: Onay iletişim kutuları discovery: Keşfet localization: body: Mastodon, gönüllüler tarafından çevrilmektedir. diff --git a/config/locales/uk.yml b/config/locales/uk.yml index 7afa383dc06e93..1d667b9eab4216 100644 --- a/config/locales/uk.yml +++ b/config/locales/uk.yml @@ -1160,10 +1160,7 @@ uk: hint_html: Якщо ви збираєтеся мігрувати з іншого облікового запису на цей, ви можете налаштувати псевдонім, який потрібен для перенесення підписок зі старою облікового запису. Ця дія сама по собі нешкідлива і її можна скасувати. Міграція облікового запису починається зі старого облікового запису. remove: Від'єднати псевдонім appearance: - advanced_web_interface: Розширений вебінтерфейс - advanced_web_interface_hint: 'Якщо ви бажаєте використовувати всю ширину вашого екрана, розширений вебінтерфейс дає змогу налаштовувати одночасний показ багатьох стовпчиків: головна, сповіщення, федеративна стрічка, будь-яка кількість списків і хештеґів.' animations_and_accessibility: Анімація та доступність - confirmation_dialogs: Діалоги підтвердження discovery: Виявлення localization: body: Mastodon перекладено волонтерами. diff --git a/config/locales/vi.yml b/config/locales/vi.yml index b38035ab071626..ffad1d1cbcc85a 100644 --- a/config/locales/vi.yml +++ b/config/locales/vi.yml @@ -1167,10 +1167,7 @@ vi: hint_html: Nếu bạn muốn chuyển từ máy chủ khác sang máy chủ này, bắt buộc bạn phải tạo tên người dùng mới thì mới có thể tiến hành chuyển được người theo dõi. Hành động này không ảnh hưởng gì và có thể đảo ngược. Việc di chuyển tài khoản được bắt đầu từ tài khoản cũ. remove: Bỏ liên kết bí danh appearance: - advanced_web_interface: Bố cục - advanced_web_interface_hint: Xếp giao diện thành nhiều cột, hợp với màn hình rộng. animations_and_accessibility: Hiệu ứng - confirmation_dialogs: Hộp thoại xác nhận discovery: Khám phá localization: body: Mastodon được dịch bởi tình nguyện viên. diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index 60ab656e7ddeb5..ba114cfbcf2898 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -1167,10 +1167,7 @@ zh-CN: hint_html: 如果你想从另一个账号迁移到这里,可以先在这里创建一个别名。要把旧账号的关注者迁移过来,这一步是必须的。设置别名的操作是无害且可撤销的账号迁移的操作会从旧账号发起。 remove: 取消关联别名 appearance: - advanced_web_interface: 高级 Web 界面 - advanced_web_interface_hint: 在高级网页界面支持自定义多栏显示,你可以利用整个屏幕的宽度,同时查看首页、通知、跨站时间线及任意数量的列表和话题。 animations_and_accessibility: 动画与可访问性 - confirmation_dialogs: 确认对话框 discovery: 发现 localization: body: Mastodon 由志愿者翻译。 diff --git a/config/locales/zh-HK.yml b/config/locales/zh-HK.yml index c0e6029819ff02..6045808fee303a 100644 --- a/config/locales/zh-HK.yml +++ b/config/locales/zh-HK.yml @@ -1001,10 +1001,7 @@ zh-HK: hint_html: 如果你想由另一個帳戶轉移到此帳號,你可以在此處創建別名 (alias),然後系統容許你將關注者由舊帳戶轉移到此帳號。此操作是無害且可以還原的帳號遷移程序,需要在舊帳號啟動。 remove: 取消連結別名 (Alias) appearance: - advanced_web_interface: 進階網頁介面 - advanced_web_interface_hint: 如果你想善用整個螢幕闊度,你可以啟用「進階網頁介面」,在畫面上配置多個不同的欄目,讓你能根據需要,同時查看盡可能多的信息,支援的欄位包括:主頁、通知、其他站點和任何的列表和標籤。 animations_and_accessibility: 動畫和輔助功能 - confirmation_dialogs: 確認對話框 discovery: 探索 localization: body: Mastodon 是由志願者翻譯的。 diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index 0a0c3a1ee5626b..ea0ff5164c066f 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -1169,10 +1169,7 @@ zh-TW: hint_html: 如果想由其他帳號轉移至此帳號,您能於此處新增別名,稍後系統將容許您將跟隨者由舊帳號轉移至此。此項作業是無害且可復原的帳號的遷移程序需要於舊帳號啟動。 remove: 取消連結別名 appearance: - advanced_web_interface: 進階網頁介面 - advanced_web_interface_hint: 進階網頁介面能使您設定許多不同的欄位來善用螢幕空間,依需要同時查看許多不同的資訊如:首頁、通知、聯邦宇宙時間軸、任意數量的列表與主題標籤。 animations_and_accessibility: 動畫與無障礙設定 - confirmation_dialogs: 確認對話框 discovery: 探索 localization: body: Mastodon 是由志願者所翻譯。 From 5404f92ceed44ee90b12e3d1373e23a98d691c77 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 16 Oct 2025 12:29:07 +0200 Subject: [PATCH 188/853] New Crowdin Translations (automated) (#36494) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/be.json | 1 - app/javascript/mastodon/locales/ca.json | 1 - app/javascript/mastodon/locales/cs.json | 1 - app/javascript/mastodon/locales/cy.json | 1 - app/javascript/mastodon/locales/da.json | 2 +- app/javascript/mastodon/locales/de.json | 2 +- app/javascript/mastodon/locales/el.json | 2 +- app/javascript/mastodon/locales/es-AR.json | 2 +- app/javascript/mastodon/locales/es-MX.json | 2 +- app/javascript/mastodon/locales/es.json | 2 +- app/javascript/mastodon/locales/et.json | 2 +- app/javascript/mastodon/locales/fi.json | 2 +- app/javascript/mastodon/locales/fo.json | 1 - app/javascript/mastodon/locales/fr-CA.json | 1 - app/javascript/mastodon/locales/fr.json | 1 - app/javascript/mastodon/locales/ga.json | 1 - app/javascript/mastodon/locales/gl.json | 2 +- app/javascript/mastodon/locales/he.json | 2 +- app/javascript/mastodon/locales/hu.json | 2 +- app/javascript/mastodon/locales/ia.json | 1 - app/javascript/mastodon/locales/is.json | 1 - app/javascript/mastodon/locales/it.json | 1 - app/javascript/mastodon/locales/lad.json | 33 ++++++++++++++ app/javascript/mastodon/locales/lv.json | 53 ++++++++++++---------- app/javascript/mastodon/locales/nan.json | 1 - app/javascript/mastodon/locales/nl.json | 1 - app/javascript/mastodon/locales/nn.json | 1 - app/javascript/mastodon/locales/pt-PT.json | 10 +++- app/javascript/mastodon/locales/sq.json | 1 - app/javascript/mastodon/locales/tr.json | 1 - app/javascript/mastodon/locales/vi.json | 3 +- app/javascript/mastodon/locales/zh-CN.json | 1 - app/javascript/mastodon/locales/zh-TW.json | 2 +- config/locales/de.yml | 2 +- config/locales/devise.da.yml | 1 + config/locales/devise.de.yml | 1 + config/locales/devise.el.yml | 1 + config/locales/devise.es-AR.yml | 1 + config/locales/devise.es-MX.yml | 1 + config/locales/devise.es.yml | 1 + config/locales/devise.et.yml | 1 + config/locales/devise.fi.yml | 1 + config/locales/devise.fo.yml | 1 + config/locales/devise.gl.yml | 1 + config/locales/devise.he.yml | 1 + config/locales/devise.hu.yml | 1 + config/locales/devise.lv.yml | 8 ++-- config/locales/devise.sq.yml | 1 + config/locales/devise.tr.yml | 1 + config/locales/devise.vi.yml | 1 + config/locales/devise.zh-TW.yml | 1 + config/locales/doorkeeper.lv.yml | 6 +-- config/locales/et.yml | 14 ++++++ config/locales/gl.yml | 10 ++++ config/locales/lad.yml | 29 ++++++++++++ config/locales/lv.yml | 18 ++++---- config/locales/pt-PT.yml | 14 ++++++ config/locales/simple_form.et.yml | 4 ++ config/locales/simple_form.lad.yml | 6 +++ 59 files changed, 196 insertions(+), 71 deletions(-) diff --git a/app/javascript/mastodon/locales/be.json b/app/javascript/mastodon/locales/be.json index 0a7b3c805e6996..dfc0538923bfaf 100644 --- a/app/javascript/mastodon/locales/be.json +++ b/app/javascript/mastodon/locales/be.json @@ -876,7 +876,6 @@ "status.contains_quote": "Утрымлівае цытату", "status.context.loading": "Загружаюцца іншыя адказы", "status.context.loading_error": "Немагчыма загрузіць новыя адказы", - "status.context.loading_success": "Усе адказы загружаныя", "status.context.more_replies_found": "Знойдзеныя іншыя адказы", "status.context.retry": "Паспрабаваць зноў", "status.context.show": "Паказаць", diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json index 956420026ac71c..555f2a459915e7 100644 --- a/app/javascript/mastodon/locales/ca.json +++ b/app/javascript/mastodon/locales/ca.json @@ -871,7 +871,6 @@ "status.contains_quote": "Conté una cita", "status.context.loading": "Es carreguen més respostes", "status.context.loading_error": "No s'han pogut carregar respostes noves", - "status.context.loading_success": "S'han carregat totes les respostes", "status.context.more_replies_found": "S'han trobat més respostes", "status.context.retry": "Torna-ho a provar", "status.context.show": "Mostra", diff --git a/app/javascript/mastodon/locales/cs.json b/app/javascript/mastodon/locales/cs.json index b9f7d0bdfb5bdc..5eccf71746ac78 100644 --- a/app/javascript/mastodon/locales/cs.json +++ b/app/javascript/mastodon/locales/cs.json @@ -876,7 +876,6 @@ "status.contains_quote": "Obsahuje citaci", "status.context.loading": "Načítání dalších odpovědí", "status.context.loading_error": "Nelze načíst nové odpovědi", - "status.context.loading_success": "Všechny odpovědi načteny", "status.context.more_replies_found": "Nalezeny další odpovědi", "status.context.retry": "Zkusit znovu", "status.context.show": "Zobrazit", diff --git a/app/javascript/mastodon/locales/cy.json b/app/javascript/mastodon/locales/cy.json index 7bd83922d9226d..57119f0b1bb9bb 100644 --- a/app/javascript/mastodon/locales/cy.json +++ b/app/javascript/mastodon/locales/cy.json @@ -875,7 +875,6 @@ "status.contains_quote": "Yn cynnwys dyfyniad", "status.context.loading": "Yn llwytho mwy o atebion", "status.context.loading_error": "Wedi methu llwytho atebion newydd", - "status.context.loading_success": "Wedi llwytho'r holl atebion", "status.context.more_replies_found": "Mwy o atebion wedi'u canfod", "status.context.retry": "Ceisio eto", "status.context.show": "Dangos", diff --git a/app/javascript/mastodon/locales/da.json b/app/javascript/mastodon/locales/da.json index c36da1a614e034..8d3e5247430e5c 100644 --- a/app/javascript/mastodon/locales/da.json +++ b/app/javascript/mastodon/locales/da.json @@ -876,7 +876,7 @@ "status.contains_quote": "Indeholder citat", "status.context.loading": "Indlæser flere svar", "status.context.loading_error": "Kunne ikke indlæse nye svar", - "status.context.loading_success": "Alle svar indlæst", + "status.context.loading_success": "Nye svar indlæst", "status.context.more_replies_found": "Flere svar fundet", "status.context.retry": "Prøv igen", "status.context.show": "Vis", diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json index b7d52e4e501d6c..5e65e8adc47bc0 100644 --- a/app/javascript/mastodon/locales/de.json +++ b/app/javascript/mastodon/locales/de.json @@ -876,7 +876,7 @@ "status.contains_quote": "Enthält Zitat", "status.context.loading": "Weitere Antworten laden", "status.context.loading_error": "Weitere Antworten konnten nicht geladen werden", - "status.context.loading_success": "Alle weiteren Antworten geladen", + "status.context.loading_success": "Neue Antworten geladen", "status.context.more_replies_found": "Weitere Antworten verfügbar", "status.context.retry": "Erneut versuchen", "status.context.show": "Anzeigen", diff --git a/app/javascript/mastodon/locales/el.json b/app/javascript/mastodon/locales/el.json index 400171aeb0ad73..8dc9e85e829dc5 100644 --- a/app/javascript/mastodon/locales/el.json +++ b/app/javascript/mastodon/locales/el.json @@ -876,7 +876,7 @@ "status.contains_quote": "Περιέχει παράθεση", "status.context.loading": "Φόρτωση περισσότερων απαντήσεων", "status.context.loading_error": "Αδυναμία φόρτωσης νέων απαντήσεων", - "status.context.loading_success": "Όλες οι απαντήσεις φορτώθηκαν", + "status.context.loading_success": "Νέες απαντήσεις φορτώθηκαν", "status.context.more_replies_found": "Βρέθηκαν περισσότερες απαντήσεις", "status.context.retry": "Επανάληψη", "status.context.show": "Εμφάνιση", diff --git a/app/javascript/mastodon/locales/es-AR.json b/app/javascript/mastodon/locales/es-AR.json index d9b5bdaec58b62..e5f79b23336c66 100644 --- a/app/javascript/mastodon/locales/es-AR.json +++ b/app/javascript/mastodon/locales/es-AR.json @@ -876,7 +876,7 @@ "status.contains_quote": "Contiene cita", "status.context.loading": "Cargando más respuestas", "status.context.loading_error": "No se pudieron cargar nuevas respuestas", - "status.context.loading_success": "Se cargaron todas las respuestas", + "status.context.loading_success": "Se cargaron nuevas respuestas", "status.context.more_replies_found": "Se encontraron más respuestas", "status.context.retry": "Reintentar", "status.context.show": "Mostrar", diff --git a/app/javascript/mastodon/locales/es-MX.json b/app/javascript/mastodon/locales/es-MX.json index a523b32867b7fa..704233e33cbfc0 100644 --- a/app/javascript/mastodon/locales/es-MX.json +++ b/app/javascript/mastodon/locales/es-MX.json @@ -876,7 +876,7 @@ "status.contains_quote": "Contiene cita", "status.context.loading": "Cargando más respuestas", "status.context.loading_error": "No se pudieron cargar nuevas respuestas", - "status.context.loading_success": "Todas las respuestas cargadas", + "status.context.loading_success": "Cargadas nuevas respuestas", "status.context.more_replies_found": "Se han encontrado más respuestas", "status.context.retry": "Reintentar", "status.context.show": "Mostrar", diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json index 96ae78574302af..8f5bfc288b3cee 100644 --- a/app/javascript/mastodon/locales/es.json +++ b/app/javascript/mastodon/locales/es.json @@ -876,7 +876,7 @@ "status.contains_quote": "Contiene cita", "status.context.loading": "Cargando más respuestas", "status.context.loading_error": "No se pudieron cargar nuevas respuestas", - "status.context.loading_success": "Se cargaron todas las respuestas", + "status.context.loading_success": "Cargadas nuevas respuestas", "status.context.more_replies_found": "Se encontraron más respuestas", "status.context.retry": "Reintentar", "status.context.show": "Mostrar", diff --git a/app/javascript/mastodon/locales/et.json b/app/javascript/mastodon/locales/et.json index 4848c4f7e15bdf..4ee768c0fa7bc2 100644 --- a/app/javascript/mastodon/locales/et.json +++ b/app/javascript/mastodon/locales/et.json @@ -753,6 +753,7 @@ "privacy.unlisted.short": "Vaikselt avalik", "privacy_policy.last_updated": "Viimati uuendatud {date}", "privacy_policy.title": "Isikuandmete kaitse", + "quote_error.edit": "Postituse muutmisel ei saa tsitaati lisada.", "quote_error.poll": "Tsiteerimine pole küsitlustes lubatud.", "quote_error.quote": "Korraga on lubatud vaid üks tsitaat.", "quote_error.unauthorized": "Sul pole õigust seda postitust tsiteerida.", @@ -875,7 +876,6 @@ "status.contains_quote": "Sisaldab tsitaati", "status.context.loading": "Laadin veel vastuseid", "status.context.loading_error": "Uute vastuste laadimine ei õnnestunud", - "status.context.loading_success": "Kõik vastused on laaditud", "status.context.more_replies_found": "Leidub veel vastuseid", "status.context.retry": "Proovi uuesti", "status.context.show": "Näita", diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json index ca38be95131cdf..94fd2f982a5086 100644 --- a/app/javascript/mastodon/locales/fi.json +++ b/app/javascript/mastodon/locales/fi.json @@ -876,7 +876,7 @@ "status.contains_quote": "Sisältää lainauksen", "status.context.loading": "Ladataan lisää vastauksia", "status.context.loading_error": "Ei voitu ladata lisää vastauksia", - "status.context.loading_success": "Kaikki vastaukset ladattu", + "status.context.loading_success": "Uudet vastaukset ladattu", "status.context.more_replies_found": "Löytyi lisää vastauksia", "status.context.retry": "Yritä uudelleen", "status.context.show": "Näytä", diff --git a/app/javascript/mastodon/locales/fo.json b/app/javascript/mastodon/locales/fo.json index 55a3d2455b8809..0225269c5c80d4 100644 --- a/app/javascript/mastodon/locales/fo.json +++ b/app/javascript/mastodon/locales/fo.json @@ -876,7 +876,6 @@ "status.contains_quote": "Inniheldur sitat", "status.context.loading": "Tekur fleiri svar niður", "status.context.loading_error": "Fekk ikki tikið nýggj svar niður", - "status.context.loading_success": "Øll svar tikin niður", "status.context.more_replies_found": "Fleiri svar funnin", "status.context.retry": "Royn aftur", "status.context.show": "Vís", diff --git a/app/javascript/mastodon/locales/fr-CA.json b/app/javascript/mastodon/locales/fr-CA.json index d5c282d2f89039..e749caf8757401 100644 --- a/app/javascript/mastodon/locales/fr-CA.json +++ b/app/javascript/mastodon/locales/fr-CA.json @@ -869,7 +869,6 @@ "status.contains_quote": "Contient la citation", "status.context.loading": "Chargement de réponses supplémentaires", "status.context.loading_error": "Impossible de charger les nouvelles réponses", - "status.context.loading_success": "Toutes les réponses sont chargées", "status.context.more_replies_found": "Plus de réponses trouvées", "status.context.retry": "Réessayer", "status.context.show": "Montrer", diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json index cc70dbc68f2905..91cf65835b9e4c 100644 --- a/app/javascript/mastodon/locales/fr.json +++ b/app/javascript/mastodon/locales/fr.json @@ -869,7 +869,6 @@ "status.contains_quote": "Contient la citation", "status.context.loading": "Chargement de réponses supplémentaires", "status.context.loading_error": "Impossible de charger les nouvelles réponses", - "status.context.loading_success": "Toutes les réponses sont chargées", "status.context.more_replies_found": "Plus de réponses trouvées", "status.context.retry": "Réessayer", "status.context.show": "Montrer", diff --git a/app/javascript/mastodon/locales/ga.json b/app/javascript/mastodon/locales/ga.json index 5b0d00d04c6744..87bf59e4b0b6b5 100644 --- a/app/javascript/mastodon/locales/ga.json +++ b/app/javascript/mastodon/locales/ga.json @@ -875,7 +875,6 @@ "status.contains_quote": "Tá luachan ann", "status.context.loading": "Ag lódáil tuilleadh freagraí", "status.context.loading_error": "Níorbh fhéidir freagraí nua a lódáil", - "status.context.loading_success": "Luchtaithe na freagraí uile", "status.context.more_replies_found": "Tuilleadh freagraí aimsithe", "status.context.retry": "Déan iarracht arís", "status.context.show": "Taispeáin", diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json index 0cec616ff0489b..668c3e5ba40238 100644 --- a/app/javascript/mastodon/locales/gl.json +++ b/app/javascript/mastodon/locales/gl.json @@ -876,7 +876,7 @@ "status.contains_quote": "Contén unha cita", "status.context.loading": "Cargando máis respostas", "status.context.loading_error": "Non se puideron mostrar novas respostas", - "status.context.loading_success": "Móstranse todas as respostas", + "status.context.loading_success": "Móstranse novas respostas", "status.context.more_replies_found": "Existen máis respostas", "status.context.retry": "Volver tentar", "status.context.show": "Mostrar", diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json index 9e7a90cab1fdc5..445c792d7a7eff 100644 --- a/app/javascript/mastodon/locales/he.json +++ b/app/javascript/mastodon/locales/he.json @@ -876,7 +876,7 @@ "status.contains_quote": "הודעה מכילה ציטוט", "status.context.loading": "נטענות תשובות נוספות", "status.context.loading_error": "טעינת תשובות נוספות נכשלה", - "status.context.loading_success": "כל התשובות נטענו", + "status.context.loading_success": "תשובות חדשות נטענו", "status.context.more_replies_found": "תשובות נוספות נמצאו", "status.context.retry": "נסה שוב", "status.context.show": "הצג", diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json index 5cc41a13404434..e77b6273c5e09e 100644 --- a/app/javascript/mastodon/locales/hu.json +++ b/app/javascript/mastodon/locales/hu.json @@ -876,7 +876,7 @@ "status.contains_quote": "Idézést tartalmaz", "status.context.loading": "Több válasz betöltése", "status.context.loading_error": "Az új válaszok nem tölthetőek be", - "status.context.loading_success": "Összes válasz betöltve", + "status.context.loading_success": "Új válaszok betöltve", "status.context.more_replies_found": "Több válasz található", "status.context.retry": "Újra", "status.context.show": "Megjelenítés", diff --git a/app/javascript/mastodon/locales/ia.json b/app/javascript/mastodon/locales/ia.json index 4a9929ddc0559a..126a7e5938e249 100644 --- a/app/javascript/mastodon/locales/ia.json +++ b/app/javascript/mastodon/locales/ia.json @@ -870,7 +870,6 @@ "status.contains_quote": "Contine un citation", "status.context.loading": "Cargante plus responsas", "status.context.loading_error": "Non poteva cargar nove responsas", - "status.context.loading_success": "Tote le responsas cargate", "status.context.more_replies_found": "Plus responsas trovate", "status.context.retry": "Tentar de novo", "status.context.show": "Monstrar", diff --git a/app/javascript/mastodon/locales/is.json b/app/javascript/mastodon/locales/is.json index 7934d15692cd2a..1188175d98336a 100644 --- a/app/javascript/mastodon/locales/is.json +++ b/app/javascript/mastodon/locales/is.json @@ -875,7 +875,6 @@ "status.contains_quote": "Inniheldur tilvitnun", "status.context.loading": "Hleð inn fleiri svörum", "status.context.loading_error": "Gat ekki hlaðið inn nýjum svörum", - "status.context.loading_success": "Öllum svörum hlaðið inn", "status.context.more_replies_found": "Fleiri svör fundust", "status.context.retry": "Reyna aftur", "status.context.show": "Sýna", diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json index bd84dfcadee600..113e4791e41be3 100644 --- a/app/javascript/mastodon/locales/it.json +++ b/app/javascript/mastodon/locales/it.json @@ -875,7 +875,6 @@ "status.contains_quote": "Contiene una citazione", "status.context.loading": "Caricamento di altre risposte", "status.context.loading_error": "Impossibile caricare nuove risposte", - "status.context.loading_success": "Tutte le risposte caricate", "status.context.more_replies_found": "Sono state trovate altre risposte", "status.context.retry": "Riprova", "status.context.show": "Mostra", diff --git a/app/javascript/mastodon/locales/lad.json b/app/javascript/mastodon/locales/lad.json index 147e362f3b0678..b223288f5fc67c 100644 --- a/app/javascript/mastodon/locales/lad.json +++ b/app/javascript/mastodon/locales/lad.json @@ -28,6 +28,7 @@ "account.disable_notifications": "Desha de avizarme sovre publikasyones de @{name}", "account.domain_blocking": "Blokando el domeno", "account.edit_profile": "Edita profil", + "account.edit_profile_short": "Edita", "account.enable_notifications": "Avizame kuando @{name} publike", "account.endorse": "Avalia en profil", "account.featured.accounts": "Profiles", @@ -36,6 +37,9 @@ "account.featured_tags.last_status_never": "No ay publikasyones", "account.follow": "Sige", "account.follow_back": "Sige tamyen", + "account.follow_back_short": "Sige tambyen", + "account.follow_request_cancel_short": "Anula", + "account.follow_request_short": "Solisitud", "account.followers": "Suivantes", "account.followers.empty": "Por agora dingun no sige a este utilizador.", "account.followers_counter": "{count, plural, one {{counter} suivante} other {{counter} suivantes}}", @@ -208,12 +212,19 @@ "confirmations.missing_alt_text.confirm": "Adjusta teksto alternativo", "confirmations.missing_alt_text.title": "Adjustar teksto alternativo?", "confirmations.mute.confirm": "Silensia", + "confirmations.quiet_post_quote_info.got_it": "Entyendo", "confirmations.redraft.confirm": "Efasa i reeskrive", "confirmations.redraft.message": "Estas siguro ke keres efasar esta publikasyon i reeskrivirla? Pedreras todos los favoritos i repartajasyones asosiados kon esta publikasyon i repuestas a eya seran guerfanadas.", "confirmations.redraft.title": "Efasar i reeskrivir?", + "confirmations.remove_from_followers.confirm": "Kita suivante", + "confirmations.remove_from_followers.title": "Kitar suivante?", "confirmations.revoke_quote.confirm": "Kita puvlikasyon", "confirmations.revoke_quote.title": "Kitar puvlikasyon?", + "confirmations.unblock.confirm": "Dezbloka", + "confirmations.unblock.title": "Dezblokar a @{name}?", "confirmations.unfollow.confirm": "Desige", + "confirmations.unfollow.title": "Desegir a @{name}?", + "confirmations.withdraw_request.confirm": "Anula solisitud", "content_warning.hide": "Eskonde puvlikasyon", "content_warning.show": "Amostra entanto", "content_warning.show_more": "Amostra mas", @@ -245,6 +256,7 @@ "domain_pill.username": "Nombre de utilizador", "domain_pill.whats_in_a_handle": "En ke konsiste el alias?", "domain_pill.your_handle": "Tu alias:", + "dropdown.empty": "Eskoje una opsyon", "embed.instructions": "Enkrusta esta publikasyon en tu sitio internetiko kopiando este kodiche.", "embed.preview": "Paresera ansina:", "emoji_button.activity": "Aktivita", @@ -384,6 +396,7 @@ "ignore_notifications_modal.not_following_title": "Inyorar avizos de personas a las kualas no siges?", "ignore_notifications_modal.private_mentions_title": "Ignorar avizos de mensyones privadas no solisitadas?", "info_button.label": "Ayuda", + "interaction_modal.go": "Va", "interaction_modal.on_another_server": "En otro sirvidor", "interaction_modal.on_this_server": "En este sirvidor", "interaction_modal.username_prompt": "Por enshemplo {example}", @@ -414,6 +427,7 @@ "keyboard_shortcuts.open_media": "Avre multimedia", "keyboard_shortcuts.pinned": "Avre lista de publikasyones fiksadas", "keyboard_shortcuts.profile": "Avre profil del autor", + "keyboard_shortcuts.quote": "Sita puvlikasyon", "keyboard_shortcuts.reply": "Arisponde a publikasyon", "keyboard_shortcuts.requests": "Avre lista de solisitudes de suivantes", "keyboard_shortcuts.search": "Enfoka en la vara de bushkeda", @@ -422,8 +436,10 @@ "keyboard_shortcuts.toggle_hidden": "Amostra/eskonde teksto detras de avertensya de kontenido (CW)", "keyboard_shortcuts.toggle_sensitivity": "Amostra/eskonde multimedia", "keyboard_shortcuts.toot": "Eskrive mueva publikasyon", + "keyboard_shortcuts.translate": "para trezladar una puvlikasyon", "keyboard_shortcuts.unfocus": "No enfoka en el area de eskrivir/bushkeda", "keyboard_shortcuts.up": "Move verso arriva en la lista", + "learn_more_link.got_it": "Entyendo", "learn_more_link.learn_more": "Ambezate mas", "lightbox.close": "Serra", "lightbox.next": "Sigiente", @@ -440,8 +456,13 @@ "lists.delete": "Efasa lista", "lists.done": "Fecho", "lists.edit": "Edita lista", + "lists.find_users_to_add": "Bushka utilizadores para adjustar", "lists.list_name": "Nombre de lista", "lists.new_list_name": "Nombre de mueva lista", + "lists.no_lists_yet": "Ainda no ay listas.", + "lists.no_members_yet": "Ainda no ay myembros.", + "lists.no_results_found": "No se toparon rezultados.", + "lists.remove_member": "Kita", "lists.replies_policy.followed": "Kualseker utilizador segido", "lists.replies_policy.list": "Miembros de la lista", "lists.replies_policy.none": "Dinguno", @@ -461,6 +482,7 @@ "navigation_bar.about": "Sovre mozotros", "navigation_bar.administration": "Administrasyon", "navigation_bar.advanced_interface": "Avre en la enterfaz avanzada", + "navigation_bar.automated_deletion": "Efasasyon otomatika de publikasyones", "navigation_bar.blocks": "Utilizadores blokados", "navigation_bar.bookmarks": "Markadores", "navigation_bar.direct": "Enmentaduras privadas", @@ -480,6 +502,8 @@ "navigation_bar.preferences": "Preferensyas", "navigation_bar.privacy_and_reach": "Privasita i alkanse", "navigation_bar.search": "Bushka", + "navigation_bar.search_trends": "Bushka / Trendes", + "navigation_panel.expand_lists": "Espande menu de lista", "not_signed_in_indicator.not_signed_in": "Nesesitas konektarse kon tu kuento para akseder este rekurso.", "notification.admin.report": "{name} raporto {target}", "notification.admin.report_statuses": "{name} raporto {target} por {category}", @@ -531,6 +555,7 @@ "notifications.column_settings.mention": "Enmentaduras:", "notifications.column_settings.poll": "Rizultados de anketas:", "notifications.column_settings.push": "Avizos arrepushados", + "notifications.column_settings.quote": "Sitas:", "notifications.column_settings.reblog": "Repartajasyones:", "notifications.column_settings.show": "Amostra en kolumna", "notifications.column_settings.sound": "Reproduse son", @@ -617,6 +642,7 @@ "relative_time.minutes": "{number} m", "relative_time.seconds": "{number} s", "relative_time.today": "oy", + "remove_quote_hint.button_label": "Entyendo", "reply_indicator.attachments": "{count, plural, one {# anekso} other {# aneksos}}", "reply_indicator.cancel": "Anula", "reply_indicator.poll": "Anketa", @@ -707,8 +733,11 @@ "status.bookmark": "Marka", "status.cancel_reblog_private": "No repartaja", "status.cannot_reblog": "Esta publikasyon no se puede repartajar", + "status.context.retry": "Reprova", + "status.context.show": "Amostra", "status.copy": "Kopia atadijo de publikasyon", "status.delete": "Efasa", + "status.delete.success": "Puvlikasyon kitada", "status.detailed_status": "Vista de konversasyon detalyada", "status.direct": "Enmenta a @{name} en privado", "status.direct_indicator": "Enmentadura privada", @@ -729,6 +758,9 @@ "status.mute_conversation": "Silensia konversasyon", "status.open": "Espande publikasyon", "status.pin": "Fiksa en profil", + "status.quote": "Sita", + "status.quote.cancel": "Anula la sita", + "status.quote_noun": "Sita", "status.read_more": "Melda mas", "status.reblog": "Repartaja", "status.reblogged_by": "{name} repartajo", @@ -736,6 +768,7 @@ "status.redraft": "Efasa i eskrive de muevo", "status.remove_bookmark": "Kita markador", "status.remove_favourite": "Kita de los favoritos", + "status.remove_quote": "Kita", "status.replied_in_thread": "Arispondo en filo", "status.replied_to": "Arispondio a {name}", "status.reply": "Arisponde", diff --git a/app/javascript/mastodon/locales/lv.json b/app/javascript/mastodon/locales/lv.json index 6f2fcb037294b9..099b8eb142f1f0 100644 --- a/app/javascript/mastodon/locales/lv.json +++ b/app/javascript/mastodon/locales/lv.json @@ -17,17 +17,18 @@ "account.add_or_remove_from_list": "Pievienot vai Noņemt no sarakstiem", "account.badges.bot": "Automatizēts", "account.badges.group": "Grupa", - "account.block": "Bloķēt @{name}", + "account.block": "Liegt @{name}", "account.block_domain": "Bloķēt domēnu {domain}", - "account.block_short": "Bloķēt", - "account.blocked": "Bloķēts", - "account.blocking": "Bloķēts", + "account.block_short": "Liegt", + "account.blocked": "Liegts", + "account.blocking": "Liegts", "account.cancel_follow_request": "Atsaukt sekošanas pieprasījumu", "account.copy": "Ievietot saiti uz profilu starpliktuvē", "account.direct": "Pieminēt @{name} privāti", "account.disable_notifications": "Pārtraukt man paziņot, kad @{name} izveido ierakstu", - "account.domain_blocking": "Bloķēts domēns", + "account.domain_blocking": "Liegts domēns", "account.edit_profile": "Labot profilu", + "account.edit_profile_short": "Labot", "account.enable_notifications": "Paziņot man, kad @{name} izveido ierakstu", "account.endorse": "Izcelts profilā", "account.familiar_followers_many": "Kam seko {name1}, {name2}, un {othersCount, plural, zero {pārējie # jums pazīstami} one {vēl viens jums pazīstams} other {pārējie # jums pazīstami}}", @@ -40,6 +41,10 @@ "account.featured_tags.last_status_never": "Nav ierakstu", "account.follow": "Sekot", "account.follow_back": "Sekot atpakaļ", + "account.follow_request": "Pieprasīt sekot", + "account.follow_request_cancel": "Atcelt pieprasījumu", + "account.follow_request_cancel_short": "Atcelt", + "account.follow_request_short": "Pieprasīt", "account.followers": "Sekotāji", "account.followers.empty": "Šim lietotājam vēl nav sekotāju.", "account.followers_counter": "{count, plural, zero {{count} sekotāju} one {{count} sekotājs} other {{count} sekotāji}}", @@ -75,9 +80,9 @@ "account.share": "Dalīties ar @{name} profilu", "account.show_reblogs": "Parādīt @{name} pastiprinātos ierakstus", "account.statuses_counter": "{count, plural, zero {{counter} ierakstu} one {{counter} ieraksts} other {{counter} ieraksti}}", - "account.unblock": "Atbloķēt @{name}", - "account.unblock_domain": "Atbloķēt domēnu {domain}", - "account.unblock_domain_short": "Atbloķēt", + "account.unblock": "Atcelt liegšanu @{name}", + "account.unblock_domain": "Atcelt domēna {domain} liegšanu", + "account.unblock_domain_short": "Atcelt liegšanu", "account.unblock_short": "Atbloķēt", "account.unendorse": "Neizcelt profilā", "account.unfollow": "Pārstāt sekot", @@ -131,7 +136,7 @@ "block_modal.show_more": "Parādīt mazāk", "block_modal.they_cant_mention": "Nevar Tevi pieminēt vai sekot Tev.", "block_modal.they_cant_see_posts": "Lietotajs nevarēs redzēt Tavus ierakstus, un Tu neredzēsi lietotāja.", - "block_modal.title": "Bloķēt lietotāju?", + "block_modal.title": "Liegt lietotāju?", "block_modal.you_wont_see_mentions": "Tu neredzēsi ierakstus, kuros ir minēts šis lietotājs.", "boost_modal.combo": "Nospied {combo}, lai nākamreiz šo izlaistu", "boost_modal.reblog": "Pastiprināt ierakstu?", @@ -154,13 +159,13 @@ "closed_registrations_modal.preamble": "Mastodon ir decentralizēts, tāpēc neatkarīgi no tā, kur Tu izveido savu kontu, varēsi sekot un mijiedarboties ar ikvienu šajā serverī. Tu pat vari to pašizvietot!", "closed_registrations_modal.title": "Reģistrēšanās Mastodon", "column.about": "Par", - "column.blocks": "Bloķētie lietotāji", + "column.blocks": "Liegtie lietotāji", "column.bookmarks": "Grāmatzīmes", "column.community": "Vietējā laika līnija", "column.create_list": "Izveidot sarakstu", "column.direct": "Privātas pieminēšanas", "column.directory": "Pārlūkot profilus", - "column.domain_blocks": "Bloķētie domēni", + "column.domain_blocks": "Liegtie domēni", "column.edit_list": "Labot sarakstu", "column.favourites": "Izlase", "column.firehose": "Tiešraides plūsmas", @@ -208,7 +213,7 @@ "compose_form.spoiler.unmarked": "Pievienot satura brīdinājumu", "compose_form.spoiler_placeholder": "Satura brīdinājums (pēc izvēles)", "confirmation_modal.cancel": "Atcelt", - "confirmations.block.confirm": "Bloķēt", + "confirmations.block.confirm": "Liegt", "confirmations.delete.confirm": "Dzēst", "confirmations.delete.message": "Vai tiešām izdzēst šo ierakstu?", "confirmations.delete.title": "Izdzēst ierakstu?", @@ -243,6 +248,8 @@ "confirmations.revoke_quote.message": "Šo darbību nevar atsaukt.", "confirmations.revoke_quote.title": "Noņemt ierakstu?", "confirmations.unfollow.confirm": "Pārstāt sekot", + "confirmations.unfollow.title": "Pārtraukt sekot {name}?", + "confirmations.withdraw_request.confirm": "Atsaukt pieprasījumu", "content_warning.hide": "Paslēpt ierakstu", "content_warning.show": "Tomēr rādīt", "content_warning.show_more": "Rādīt vairāk", @@ -262,11 +269,11 @@ "dismissable_banner.community_timeline": "Šie ir jaunākie publiskie ieraksti no cilvēkiem, kuru konti ir mitināti {domain}.", "dismissable_banner.dismiss": "Atcelt", "dismissable_banner.public_timeline": "Šie ir jaunākie Fediverse lietotāju publiskie ieraksti, kuriem {domain} seko cilvēki.", - "domain_block_modal.block": "Bloķēt serveri", + "domain_block_modal.block": "Liegt serveri", "domain_block_modal.block_account_instead": "Tā vietā liegt @{name}", "domain_block_modal.they_cant_follow": "Neviens šajā serverī nevar Tev sekot.", - "domain_block_modal.they_wont_know": "Viņi nezinās, ka tikuši bloķēti.", - "domain_block_modal.title": "Bloķēt domēnu?", + "domain_block_modal.they_wont_know": "Viņi nezinās, ka tikuši liegti.", + "domain_block_modal.title": "Liegt domēnu?", "domain_pill.activitypub_lets_connect": "Tas ļauj savienoties un mijiedarboties ar cilvēkiem ne tikai no Mastodon, bet arī starp dažādām sabiedriskajām lietotnēm.", "domain_pill.activitypub_like_language": "ActivityPub ir kā valoda, kurā Mastodon sazināš ar citiem sabiedriskajiem tīkliem.", "domain_pill.server": "Serveris", @@ -299,11 +306,11 @@ "empty_column.account_suspended": "Konta darbība ir apturēta", "empty_column.account_timeline": "Šeit nav ierakstu.", "empty_column.account_unavailable": "Profils nav pieejams", - "empty_column.blocks": "Pašreiz tu neesi nevienu bloķējis.", + "empty_column.blocks": "Pagaidām Tu neesi liedzis nevienu lietotāju.", "empty_column.bookmarked_statuses": "Pašlaik Tev nav neviena grāmatzīmēs pievienota ieraksta. Kad tādu pievienosi, tas parādīsies šeit.", "empty_column.community": "Vietējā laika līnija ir tukša. Uzraksti kaut ko publiski, lai iekustinātu visu!", "empty_column.direct": "Tev vēl nav privātu pieminēšanu. Kad Tu nosūtīsi vai saņemsi kādu, tā pārādīsies šeit.", - "empty_column.domain_blocks": "Vēl nav neviena bloķēta domēna.", + "empty_column.domain_blocks": "Vēl nav neviena liegta domēna.", "empty_column.explore_statuses": "Pašlaik nav nekā aktuāla. Ieskaties šeit vēlāk!", "empty_column.favourited_statuses": "Tev vēl nav izlasei pievienotu ierakstu. Kad pievienosi kādu, tas tiks parādīts šeit.", "empty_column.favourites": "Šo ierakstu vēl neviens nav pievienojis izlasei. Kad kāds to izdarīs, tas parādīsies šeit.", @@ -418,7 +425,7 @@ "intervals.full.hours": "{number, plural, one {# stunda} other {# stundas}}", "intervals.full.minutes": "{number, plural, one {# minūte} other {# minūtes}}", "keyboard_shortcuts.back": "Pāriet atpakaļ", - "keyboard_shortcuts.blocked": "Atvērt bloķēto lietotāju sarakstu", + "keyboard_shortcuts.blocked": "Atvērt liegto lietotāju sarakstu", "keyboard_shortcuts.boost": "Pastiprināt ierakstu", "keyboard_shortcuts.column": "Fokusēt kolonnu", "keyboard_shortcuts.compose": "Fokusēt veidojamā teksta lauku", @@ -492,10 +499,10 @@ "navigation_bar.administration": "Pārvaldība", "navigation_bar.advanced_interface": "Atvērt paplašinātā tīmekļa saskarnē", "navigation_bar.automated_deletion": "Automātiska ziņu dzēšana", - "navigation_bar.blocks": "Bloķētie lietotāji", + "navigation_bar.blocks": "Liegtie lietotāji", "navigation_bar.bookmarks": "Grāmatzīmes", "navigation_bar.direct": "Privātas pieminēšanas", - "navigation_bar.domain_blocks": "Bloķētie domēni", + "navigation_bar.domain_blocks": "Liegtie domēni", "navigation_bar.favourites": "Izlase", "navigation_bar.filters": "Apklusinātie vārdi", "navigation_bar.follow_requests": "Sekošanas pieprasījumi", @@ -641,8 +648,8 @@ "reply_indicator.attachments": "{count, plural, zero{# pielikumu} one {# pielikums} other {# pielikumi}}", "reply_indicator.cancel": "Atcelt", "reply_indicator.poll": "Aptauja", - "report.block": "Bloķēt", - "report.block_explanation": "Tu neredzēsi viņu ierakstus. Viņi nevarēs redzēt Tavus ierakstus vai sekot tev. Viņi varēs saprast, ka ir liegti.", + "report.block": "Liegt", + "report.block_explanation": "Tu neredzēsi viņu ierakstus. Viņi nevarēs redzēt Tavus ierakstus vai sekot Tev. Viņi varēs saprast, ka ir liegti.", "report.categories.legal": "Tiesisks", "report.categories.other": "Citi", "report.categories.spam": "Mēstule", @@ -723,7 +730,7 @@ "status.admin_account": "Atvērt @{name} satura pārraudzības saskarni", "status.admin_domain": "Atvērt {domain} satura pārraudzības saskarni", "status.admin_status": "Atvērt šo ziņu satura pārraudzības saskarnē", - "status.block": "Bloķēt @{name}", + "status.block": "Liegt @{name}", "status.bookmark": "Grāmatzīme", "status.cancel_reblog_private": "Nepastiprināt", "status.cannot_reblog": "Šo ierakstu nevar pastiprināt", diff --git a/app/javascript/mastodon/locales/nan.json b/app/javascript/mastodon/locales/nan.json index 5d864eeddf1c50..62404e130ecc09 100644 --- a/app/javascript/mastodon/locales/nan.json +++ b/app/javascript/mastodon/locales/nan.json @@ -875,7 +875,6 @@ "status.contains_quote": "包含引用", "status.context.loading": "載入其他回應", "status.context.loading_error": "Bē當載入新回應", - "status.context.loading_success": "回應lóng載入ah", "status.context.more_replies_found": "Tshuē-tio̍h其他回應", "status.context.retry": "Koh試", "status.context.show": "顯示", diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json index 12ffbec03df0fb..00026edbf0bc4e 100644 --- a/app/javascript/mastodon/locales/nl.json +++ b/app/javascript/mastodon/locales/nl.json @@ -876,7 +876,6 @@ "status.contains_quote": "Bevat citaat", "status.context.loading": "Meer reacties laden", "status.context.loading_error": "Kon geen nieuwe reacties laden", - "status.context.loading_success": "Alle reacties zijn geladen", "status.context.more_replies_found": "Meer reacties gevonden", "status.context.retry": "Opnieuw proberen", "status.context.show": "Tonen", diff --git a/app/javascript/mastodon/locales/nn.json b/app/javascript/mastodon/locales/nn.json index faa4efe61fb8c3..702e3cb0d208fc 100644 --- a/app/javascript/mastodon/locales/nn.json +++ b/app/javascript/mastodon/locales/nn.json @@ -875,7 +875,6 @@ "status.contains_quote": "Inneheld eit sitat", "status.context.loading": "Lastar fleire svar", "status.context.loading_error": "Kunne ikkje lasta nye svar", - "status.context.loading_success": "Alle svara er lasta", "status.context.more_replies_found": "Fann fleire svar", "status.context.retry": "Prøv om att", "status.context.show": "Vis", diff --git a/app/javascript/mastodon/locales/pt-PT.json b/app/javascript/mastodon/locales/pt-PT.json index 82fa079e9b2726..0acd1d9f407523 100644 --- a/app/javascript/mastodon/locales/pt-PT.json +++ b/app/javascript/mastodon/locales/pt-PT.json @@ -257,7 +257,12 @@ "confirmations.revoke_quote.confirm": "Remover publicação", "confirmations.revoke_quote.message": "Esta ação é irreversível.", "confirmations.revoke_quote.title": "Remover publicação?", + "confirmations.unblock.confirm": "Desbloquear", + "confirmations.unblock.title": "Desbloquear {name}?", "confirmations.unfollow.confirm": "Deixar de seguir", + "confirmations.unfollow.title": "Deixar de seguir {name}?", + "confirmations.withdraw_request.confirm": "Retirar pedido", + "confirmations.withdraw_request.title": "Retirar pedido para seguir {name}?", "content_warning.hide": "Ocultar publicação", "content_warning.show": "Mostrar mesmo assim", "content_warning.show_more": "Mostrar mais", @@ -748,6 +753,7 @@ "privacy.unlisted.short": "Público silencioso", "privacy_policy.last_updated": "Última atualização em {date}", "privacy_policy.title": "Política de privacidade", + "quote_error.edit": "Não é possível adicionar citações ao editar uma publicação.", "quote_error.poll": "Não é permitido citar sondagens.", "quote_error.quote": "Apenas é permitida uma citação de cada vez.", "quote_error.unauthorized": "Não está autorizado a citar esta publicação.", @@ -870,7 +876,7 @@ "status.contains_quote": "Contém citação", "status.context.loading": "A carregar mais respostas", "status.context.loading_error": "Não foi possível carregar novas respostas", - "status.context.loading_success": "Todas as respostas carregadas", + "status.context.loading_success": "Novas respostas carregadas", "status.context.more_replies_found": "Foram encontradas mais respostas", "status.context.retry": "Repetir", "status.context.show": "Mostrar", @@ -917,6 +923,8 @@ "status.quote_private": "Publicações privadas não podem ser citadas", "status.quotes": "{count, plural, one {citação} other {citações}}", "status.quotes.empty": "Ainda ninguém citou esta publicação. Quando alguém o fizer, aparecerá aqui.", + "status.quotes.local_other_disclaimer": "As citações rejeitadas pelo autor não serão exibidas.", + "status.quotes.remote_other_disclaimer": "Apenas citações de {domain} serão garantidamente exibidas aqui. Citações rejeitadas pelo autor não serão exibidas.", "status.read_more": "Ler mais", "status.reblog": "Impulsionar", "status.reblog_or_quote": "Partilhe ou cite", diff --git a/app/javascript/mastodon/locales/sq.json b/app/javascript/mastodon/locales/sq.json index 6f6d96509dfbe3..e46a492e070ef9 100644 --- a/app/javascript/mastodon/locales/sq.json +++ b/app/javascript/mastodon/locales/sq.json @@ -872,7 +872,6 @@ "status.contains_quote": "Përmban citim", "status.context.loading": "Po ngarkohen më tepër përgjigje", "status.context.loading_error": "S’u ngarkuan dot përgjigje të reja", - "status.context.loading_success": "Janë ngarkuar krejt përgjigjet", "status.context.more_replies_found": "U gjetën më tepër përgjigje", "status.context.retry": "Riprovoni", "status.context.show": "Shfaqe", diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json index 19b37b569b7a6a..2c6220220b6109 100644 --- a/app/javascript/mastodon/locales/tr.json +++ b/app/javascript/mastodon/locales/tr.json @@ -876,7 +876,6 @@ "status.contains_quote": "Alıntı içeriyor", "status.context.loading": "Daha fazla yanıt yükleniyor", "status.context.loading_error": "Yeni yanıtlar yüklenemiyor", - "status.context.loading_success": "Tüm yanıtlar yüklendi", "status.context.more_replies_found": "Daha fazla yanıt bulundu", "status.context.retry": "Yeniden dene", "status.context.show": "Göster", diff --git a/app/javascript/mastodon/locales/vi.json b/app/javascript/mastodon/locales/vi.json index 61de7d3e563783..c68033c5789183 100644 --- a/app/javascript/mastodon/locales/vi.json +++ b/app/javascript/mastodon/locales/vi.json @@ -753,6 +753,7 @@ "privacy.unlisted.short": "Hạn chế", "privacy_policy.last_updated": "Cập nhật lần cuối {date}", "privacy_policy.title": "Chính sách bảo mật", + "quote_error.edit": "Không thể thêm trích dẫn khi sửa tút.", "quote_error.poll": "Không thể trích dẫn vốt.", "quote_error.quote": "Chỉ được trích dẫn một lần.", "quote_error.unauthorized": "Bạn không được cấp quyền trích dẫn tút này.", @@ -875,7 +876,7 @@ "status.contains_quote": "Chứa trích dẫn", "status.context.loading": "Tải thêm các trả lời", "status.context.loading_error": "Không thể tải những trả lời mới", - "status.context.loading_success": "Đã tải toàn bộ trả lời", + "status.context.loading_success": "Đã tải những lượt trả lời mới", "status.context.more_replies_found": "Có trả lời mới", "status.context.retry": "Thử lại", "status.context.show": "Hiện", diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json index 052dfdcfd07868..3beade67c359c5 100644 --- a/app/javascript/mastodon/locales/zh-CN.json +++ b/app/javascript/mastodon/locales/zh-CN.json @@ -876,7 +876,6 @@ "status.contains_quote": "包含引用", "status.context.loading": "正在加载更多回复", "status.context.loading_error": "无法加载新回复", - "status.context.loading_success": "已加载所有回复", "status.context.more_replies_found": "已找到更多回复", "status.context.retry": "重试", "status.context.show": "显示", diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json index 81cb45fd3bf2e5..70e003688df6df 100644 --- a/app/javascript/mastodon/locales/zh-TW.json +++ b/app/javascript/mastodon/locales/zh-TW.json @@ -876,7 +876,7 @@ "status.contains_quote": "包含引用嘟文", "status.context.loading": "讀取更多回嘟", "status.context.loading_error": "無法讀取新回嘟", - "status.context.loading_success": "已讀取所有回嘟", + "status.context.loading_success": "已讀取新回嘟", "status.context.more_replies_found": "已有更多回嘟", "status.context.retry": "再試一次", "status.context.show": "顯示", diff --git a/config/locales/de.yml b/config/locales/de.yml index 69c9e1332232ad..10fc136c5156c9 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -963,7 +963,7 @@ de: message_html: Ein kritisches Mastodon-Update ist verfügbar – bitte aktualisiere so schnell wie möglich. software_version_patch_check: action: Verfügbare Updates ansehen - message_html: Ein Mastodon-Update für Fehlerkorrekturen ist verfügbar. + message_html: Ein Mastodon-Update mit Bugfixes ist verfügbar. upload_check_privacy_error: action: Für weitere Informationen hier klicken message_html: "Die Konfiguration deines Servers ist fehlerhaft. Die Privatsphäre deiner Benutzer*innen ist gefährdet." diff --git a/config/locales/devise.da.yml b/config/locales/devise.da.yml index e932ba0c9a423e..365a4347ea0cde 100644 --- a/config/locales/devise.da.yml +++ b/config/locales/devise.da.yml @@ -7,6 +7,7 @@ da: send_paranoid_instructions: Findes din e-mailadresse allerede i vores database, skulle du om få minutter modtage en e-mailvejledning til, hvordan din e-mailadresse bekræftes. Tjek spammappen, hvis e-mailen ikke ser ud til at lande i indbakken. failure: already_authenticated: Du er allerede logget ind. + closed_registrations: Dit registreringsforsøg er blevet blokeret på grund af en netværkspolitik. Hvis du mener, at dette er en fejl, så kontakt %{email}. inactive: Din konto er endnu ikke aktiveret. invalid: Ugyldig %{authentication_keys} eller adgangskode. last_attempt: Du har ét forsøg mere, før din konto bliver låst. diff --git a/config/locales/devise.de.yml b/config/locales/devise.de.yml index 706fdfbee1cfc8..a968d474796769 100644 --- a/config/locales/devise.de.yml +++ b/config/locales/devise.de.yml @@ -7,6 +7,7 @@ de: send_paranoid_instructions: Falls deine E-Mail-Adresse in unserer Datenbank hinterlegt ist, wirst du in wenigen Minuten eine E-Mail erhalten. Darin wird erklärt, wie du deine E-Mail-Adresse bestätigen kannst. Schau bitte auch in deinem Spam-Ordner nach, wenn du diese E-Mail nicht erhalten hast. failure: already_authenticated: Du bist bereits angemeldet. + closed_registrations: Deine Registrierung wurde wegen einer Netzwerkrichtlinie abgelehnt. Solltest du die Vermutung haben, dass es sich um einen Fehler handelt, wende dich bitte an %{email}. inactive: Dein Konto wurde noch nicht aktiviert. invalid: "%{authentication_keys} oder Passwort ungültig." last_attempt: Du hast nur noch einen Versuch, bevor dein Zugang gesperrt wird. diff --git a/config/locales/devise.el.yml b/config/locales/devise.el.yml index 106a48a49e603d..eaab37f48d94b9 100644 --- a/config/locales/devise.el.yml +++ b/config/locales/devise.el.yml @@ -7,6 +7,7 @@ el: send_paranoid_instructions: Αν η διεύθυνση email σου υπάρχει στη βάση μας, θα λάβεις σε μερικά λεπτά ένα email με οδηγίες επιβεβαίωσης της διεύθυνσής σου. Παρακαλούμε έλεγξε το φάκελο με τα ανεπιθύμητα αν δεν το έχεις λάβει. failure: already_authenticated: Έχεις ήδη συνδεθεί. + closed_registrations: Η προσπάθεια εγγραφής σας έχει αποκλειστεί λόγω μιας πολιτικής δικτύου. Αν πιστεύετε ότι πρόκειται για σφάλμα, επικοινωνήστε με το %{email}. inactive: Ο λογαριασμός σου δεν έχει ενεργοποιηθεί ακόμα. invalid: Λάθος %{authentication_keys} ή συνθηματικό. last_attempt: Έχεις μια ακόμα προσπάθεια πριν κλειδωθεί ο λογαριασμός σου. diff --git a/config/locales/devise.es-AR.yml b/config/locales/devise.es-AR.yml index f71b8473ec23a6..a4084441a91215 100644 --- a/config/locales/devise.es-AR.yml +++ b/config/locales/devise.es-AR.yml @@ -7,6 +7,7 @@ es-AR: send_paranoid_instructions: Si tu dirección de correo electrónico existe en nuestra base de datos, en unos minutos, vas a recibir un correo electrónico con instrucciones sobre cómo confirmar tu dirección de correo. Si pasa el tiempo y no recibiste ningún mensaje, por favor, revisá tu carpeta de correo basura / no deseado / spam. failure: already_authenticated: Ya iniciaste sesión. + closed_registrations: Tu intento de registro fue bloqueado debido a una política de red. Si creés que esto es un error, ponete en contacto con %{email}. inactive: Tu cuenta todavía no está activada. invalid: "%{authentication_keys} o contraseña no válidas." last_attempt: Tenés un intento más antes de que se bloquee tu cuenta. diff --git a/config/locales/devise.es-MX.yml b/config/locales/devise.es-MX.yml index 2e8ddc2e40ac0b..f37b1ab5f9e6f4 100644 --- a/config/locales/devise.es-MX.yml +++ b/config/locales/devise.es-MX.yml @@ -7,6 +7,7 @@ es-MX: send_paranoid_instructions: Si su dirección de correo electrónico existe en nuestra base de datos, recibirá un correo electrónico con instrucciones sobre cómo confirmar su dirección de correo en pocos minutos. failure: already_authenticated: Usted ya está registrado. + closed_registrations: Su intento de registro ha sido bloqueado debido a una política de red. Si cree que esto es un error, póngase en contacto con %{email}. inactive: Su cuenta no ha sido activada aún. invalid: "%{authentication_keys} o contraseña inválida." last_attempt: Tiene un intento más antes de que tu cuenta sea bloqueada. diff --git a/config/locales/devise.es.yml b/config/locales/devise.es.yml index ddfc1ba678c6d0..1813ab6d914d17 100644 --- a/config/locales/devise.es.yml +++ b/config/locales/devise.es.yml @@ -7,6 +7,7 @@ es: send_paranoid_instructions: Si su dirección de correo electrónico existe en nuestra base de datos, recibirá un correo electrónico con instrucciones sobre cómo confirmar su dirección de correo en pocos minutos. failure: already_authenticated: Usted ya está registrado. + closed_registrations: Su intento de registro ha sido bloqueado debido a una política de red. Si cree que esto es un error, póngase en contacto con %{email}. inactive: Su cuenta no ha sido activada aún. invalid: "%{authentication_keys} o contraseña inválida." last_attempt: Tiene un intento más antes de que tu cuenta sea bloqueada. diff --git a/config/locales/devise.et.yml b/config/locales/devise.et.yml index eb2e2951da645d..5843761ddba932 100644 --- a/config/locales/devise.et.yml +++ b/config/locales/devise.et.yml @@ -7,6 +7,7 @@ et: send_paranoid_instructions: Kui sinu e-postiaadress on meie andmebaasis, saad paari minuti pärast juhistega e-kirja, kuidas oma e-posti aadress kinnitada. Palun kontrolli oma rämpsposti kausta, kui selline e-kiri ei saabunud. failure: already_authenticated: Oled juba sisse loginud. + closed_registrations: Sinu registreerimiskatse on võrgureeglite alusel blokeeritud. Kui sa arvad, et see poleks pidanud nii olema, siis kirjuta e-posti aadressile %{email}. inactive: Sinu konto pole veel aktiveeritud. invalid: Valed %{authentication_keys} või salasõna. last_attempt: Sul on veel üks katse, enne kui konto lukustatakse. diff --git a/config/locales/devise.fi.yml b/config/locales/devise.fi.yml index d230da1f547fb0..d2465fe1acb2b7 100644 --- a/config/locales/devise.fi.yml +++ b/config/locales/devise.fi.yml @@ -7,6 +7,7 @@ fi: send_paranoid_instructions: Jos sähköpostiosoitteesi on tiedossammme, saat pian sähköpostiisi ohjeet sen vahvistamiseen. Jos viestiä ei kuulu, tarkista roskapostikansiosi. failure: already_authenticated: Olet jo kirjautunut sisään. + closed_registrations: Rekisteröitymisyrityksesi on estynyt verkkokäytännön vuoksi. Jos uskot, että tämä on virhe, ota yhteys sähköpostiosoitteeseen %{email}. inactive: Tiliäsi ei ole vielä aktivoitu. invalid: Virheellinen %{authentication_keys} tai salasana. last_attempt: Sinulla on vielä yksi yritys ennen kuin tilisi lukitaan. diff --git a/config/locales/devise.fo.yml b/config/locales/devise.fo.yml index f9783f30cc3301..aebdfc34e66fce 100644 --- a/config/locales/devise.fo.yml +++ b/config/locales/devise.fo.yml @@ -7,6 +7,7 @@ fo: send_paranoid_instructions: Um tín teldupostaddresa longu er í dátugrunninum, fær tú er um fáa minuttir ein teldupost, við frágreiðing um, hvussu hendan kann váttast. Kanna tín Spam faldara, um tú ikki sær henda. failure: already_authenticated: Tú ert longu innskrivað/ur. + closed_registrations: Tín skrásetingarroynd er blokerað vegna ein netverkspolitikk. Kontakta %{email}, um tú heldur, at hetta er ein feilur. inactive: Kontan hjá tær er ikki virkin enn. invalid: Skeivt %{authentication_keys} ella loyniorð. last_attempt: Tú kanst royna einaferð afturat áðrenn kontan verður stongd. diff --git a/config/locales/devise.gl.yml b/config/locales/devise.gl.yml index 6bbec181b805d4..04aed22dfe6cf2 100644 --- a/config/locales/devise.gl.yml +++ b/config/locales/devise.gl.yml @@ -7,6 +7,7 @@ gl: send_paranoid_instructions: Se o teu enderezo de email xa existira na nosa base de datos, vas recibir un correo coas instrucións de confirmación dentro dalgúns minutos. Por favor, comproba o cartafol de spam se non recibiches o correo. failure: already_authenticated: Xa estás conectada. + closed_registrations: Bloqueouse o teu intento de crear unha conta debido a unha directiva da rede. Se cres que é un erro, contacta con %{email}. inactive: A túa conta aínda non está activada. invalid: "%{authentication_keys} ou contrasinal non validos." last_attempt: Tes un intento máis antes de que a túa conta fique bloqueada. diff --git a/config/locales/devise.he.yml b/config/locales/devise.he.yml index 91eb75f9d1551f..085a4feaf73caa 100644 --- a/config/locales/devise.he.yml +++ b/config/locales/devise.he.yml @@ -7,6 +7,7 @@ he: send_paranoid_instructions: אם כתובת הדוא"ל שלך קיימת במסד הנתונים, יתקבל בדקות הקרובות דוא"ל עם הוראות לאימות כתובתך. יש לבדוק את תיבת הספאם ליתר בטחון אם ההודעה לא הגיעה תוך דקות ספורות. failure: already_authenticated: חשבון זה כבר מחובר. + closed_registrations: נסיון ההרשמה שלך נחסם עקב מדיניות רשת. אם לדידכם מדובר בטעות, אנא צרו קשר עם %{email}. inactive: חשבון זה טרם הופעל. invalid: "%{authentication_keys} או סיסמה לא נכונים." last_attempt: יש לך עוד ניסיון אחד לפני נעילת החשבון. diff --git a/config/locales/devise.hu.yml b/config/locales/devise.hu.yml index 5ea81bef0d18b9..3928b9f4454aba 100644 --- a/config/locales/devise.hu.yml +++ b/config/locales/devise.hu.yml @@ -7,6 +7,7 @@ hu: send_paranoid_instructions: Ha az e-mail címed már szerepel az adatbázisunkban, néhány percen belül kapsz egy levelet az e-mail cím megerősítésére vonatkozó utasításokkal. Kérjük, ellenőrizd a spam mappád, ha nem látod az e-mailt. failure: already_authenticated: Már bejelentkeztél. + closed_registrations: 'A regisztrációs kísérlet egy hálózati házirend miatt blokkolva volt. Ha úgy gondolod, hogy ez hiba, akkor vedd fel a kapcsolatot ezen a címen: %{email}.' inactive: Fiókodat még nem aktiválták. invalid: Helytelen %{authentication_keys} vagy jelszó. last_attempt: Már csak egy próbálkozásod maradt, mielőtt a fiókodat zároljuk. diff --git a/config/locales/devise.lv.yml b/config/locales/devise.lv.yml index 4b31c56ee742c1..65aa164c726ce3 100644 --- a/config/locales/devise.lv.yml +++ b/config/locales/devise.lv.yml @@ -9,8 +9,8 @@ lv: already_authenticated: Tu jau pieteicies. inactive: Tavs konts vēl nav aktivizēts. invalid: Nederīga %{authentication_keys} vai parole. - last_attempt: Tev ir vēl viens mēģinājums, pirms tavs konts tiks bloķēts. - locked: Tavs konts ir bloķēts. + last_attempt: Tev ir vēl viens mēģinājums, pirms Tavs konts tiks slēgts. + locked: Tavs konts ir slēgts. not_found_in_database: Nederīga %{authentication_keys} vai parole. omniauth_user_creation_failure: Kļūda šīs identitātes konta izveidošanā. pending: Tavs konts joprojām tiek pārskatīts. @@ -63,7 +63,7 @@ lv: subtitle: Iepriekšējie atkopes kodi tika padarīti par nederīgiem, un tika izveidoti jauni. title: 2FA atkopes kodi nomainīti unlock_instructions: - subject: 'Mastodon: Norādījumi atbloķēšanai' + subject: 'Mastodon: atslēgšanas norādes' webauthn_credential: added: explanation: Tavam kontam ir pievienota šāda drošības atslēga @@ -110,7 +110,7 @@ lv: confirmation_period_expired: jāapstiprina %{period} laikā, lūdzu, pieprasi jaunu expired: ir beidzies derīguma termiņš, lūdzu, pieprasi jaunu not_found: nav atrasts - not_locked: nebija bloķēts + not_locked: nebija slēgts not_saved: one: '1 kļūda liedza saglabāt šo %{resource}:' other: "%{count} kļūdas liedza saglabāt šo %{resource}:" diff --git a/config/locales/devise.sq.yml b/config/locales/devise.sq.yml index 69ac7bd26d6037..5eba224488bc46 100644 --- a/config/locales/devise.sq.yml +++ b/config/locales/devise.sq.yml @@ -7,6 +7,7 @@ sq: send_paranoid_instructions: Nëse adresa juaj email gjendet në bazën tonë të të dhënave, brenda pak minutash, do të merrni një email me udhëzime se si të ripohoni adresën tuaj email. Ju lutemi, nëse nuk e morët këtë email, kontrolloni dosjen e mesazheve të padëshiruar. failure: already_authenticated: Jeni tashmë i futur. + closed_registrations: Përpjekja juaj për regjistrim është bllokuar për shkak të një rregulli rrjeti. Nëse besoni se kjo është gabim, lidhuni me %{email}. inactive: Llogaria juaj s’është aktivizuar ende. invalid: "%{authentication_keys} ose fjalëkalim i pavlefshëm." last_attempt: Mund të provoni edhe një herë, përpara se llogaria juaj të kyçet. diff --git a/config/locales/devise.tr.yml b/config/locales/devise.tr.yml index 57162e805527bd..dd3b22a7d0bdc4 100644 --- a/config/locales/devise.tr.yml +++ b/config/locales/devise.tr.yml @@ -7,6 +7,7 @@ tr: send_paranoid_instructions: E-posta adresiniz veritabanımızda varsa, e-posta adresinizi birkaç dakika içinde nasıl doğrulayacağınıza ilişkin talimatları içeren bir e-posta alacaksınız. Bu e-postayı almadıysanız, lütfen spam klasörünüzü kontrol edin. failure: already_authenticated: Zaten oturum açtınız. + closed_registrations: Ağ politikası nedeniyle kayıt girişiminiz engellenmiştir. Bunun bir hata olduğunu düşünüyorsanız %{email} ile iletişime geçin. inactive: Hesabınız henüz etkinleştirilmedi. invalid: Geçersiz %{authentication_keys} ya da parola. last_attempt: Hesabınız kilitlenmeden önce bir kez daha denemeniz gerekir. diff --git a/config/locales/devise.vi.yml b/config/locales/devise.vi.yml index 2b4dc44db98f02..4fb7736f59e687 100644 --- a/config/locales/devise.vi.yml +++ b/config/locales/devise.vi.yml @@ -7,6 +7,7 @@ vi: send_paranoid_instructions: Nếu địa chỉ email của bạn đã tồn tại trong cơ sở dữ liệu của chúng tôi, bạn sẽ nhận được một email hướng dẫn cách xác minh lại địa chỉ email. Xin kiểm tra thư mục thư rác nếu như bạn không thấy email này. failure: already_authenticated: Bạn đã đăng nhập rồi. + closed_registrations: Việc đăng ký của bạn đã bị chặn do chính sách mạng. Nếu bạn cho rằng đây là lỗi, vui lòng liên hệ %{email}. inactive: Tài khoản của bạn chưa được kich hoạt. invalid: "%{authentication_keys} hoặc mật khẩu không khớp." last_attempt: Nếu thử sai lần nữa, tài khoản của bạn sẽ bị khóa. diff --git a/config/locales/devise.zh-TW.yml b/config/locales/devise.zh-TW.yml index ca01b165916b9c..9db5eac3d3f659 100644 --- a/config/locales/devise.zh-TW.yml +++ b/config/locales/devise.zh-TW.yml @@ -7,6 +7,7 @@ zh-TW: send_paranoid_instructions: 如果您的電子郵件存在於我們的資料庫,您將於幾分鐘內收到驗證信。若未收到請檢查垃圾郵件資料夾。 failure: already_authenticated: 您已登入。 + closed_registrations: 您的註冊已因網路政策被阻止。若您認為這是錯誤,煩請聯絡 %{email}。 inactive: 您的帳號尚未啟用。 invalid: 無效的 %{authentication_keys} 或密碼。 last_attempt: 帳號鎖定前,您還有最後一次嘗試機會。 diff --git a/config/locales/doorkeeper.lv.yml b/config/locales/doorkeeper.lv.yml index 4b8116e6af4ef6..a3d8902af49ed7 100644 --- a/config/locales/doorkeeper.lv.yml +++ b/config/locales/doorkeeper.lv.yml @@ -124,13 +124,13 @@ lv: admin/all: Visas administrēšanas funkcijas admin/reports: Ziņojumu pārvaldīšana all: Pilna piekļuve Tavam Mastodon kontam - blocks: Bloķētie + blocks: Liegtie bookmarks: Grāmatzīmes conversations: Sarunas crypto: Pilnīga šifrēšana favourites: Izlase filters: Filtri - follow: Seko, apklusina un liedz + follow: Sekojumi, apklusināšanas un liegumi follows: Seko lists: Saraksti media: Multividesu pielikumi @@ -184,7 +184,7 @@ lv: read:statuses: skatīt visus ierakstus write: labot visus sava konta datus write:accounts: labot manu profilu - write:blocks: bloķēt kontus un domēnus + write:blocks: liegt kontus un domēnus write:bookmarks: pievienotās grāmatzīmes write:conversations: apklusināt un dzēst sarunas write:favourites: iecienītākās ziņas diff --git a/config/locales/et.yml b/config/locales/et.yml index e700816493435e..d4462d5ad6c165 100644 --- a/config/locales/et.yml +++ b/config/locales/et.yml @@ -848,6 +848,10 @@ et: all: Kõigile disabled: Mitte kellelegi users: Sisseloginud kohalikele kasutajatele + feed_access: + modes: + authenticated: Vaid autenditud kasutajad + public: Kõik registrations: moderation_recommandation: Enne kõigi jaoks registreerimise avamist veendu, et oleks olemas adekvaatne ja reageerimisvalmis modereerijaskond! preamble: Kes saab serveril konto luua. @@ -1584,6 +1588,13 @@ et: expires_at: Aegub uses: Kasutust title: Kutsu inimesi + link_preview: + author_html: Autorilt %{name} + potentially_sensitive_content: + action: Vaatamiseks klõpsa + confirm_visit: Kas oled kindel, et soovid selle lingi avada? + hide_button: Peida + label: Võimalik delikaatne sisu lists: errors: limit: Oled jõudnud loetelude lubatud maksimumarvuni @@ -1894,6 +1905,9 @@ et: other: "%{count} videot" boosted_from_html: "%{acct_link} jagamine" content_warning: 'Sisu hoiatus: %{warning}' + content_warnings: + hide: Peida postitus + show: Näita rohkem default_language: Kasutajaliidese keelega sama disallowed_hashtags: one: 'sisaldab ebasobivat silti: %{tags}' diff --git a/config/locales/gl.yml b/config/locales/gl.yml index 9f8a23832b01a2..3fb2e368b5d972 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -1588,6 +1588,13 @@ gl: expires_at: Caduca uses: Usos title: Convidar a persoas + link_preview: + author_html: De %{name} + potentially_sensitive_content: + action: Preme para ver + confirm_visit: Tes certeza de querer abrir esta ligazón? + hide_button: Ocultar + label: Posible contido sensible lists: errors: limit: Xa acadaches o número máximo de listas @@ -1898,6 +1905,9 @@ gl: other: "%{count} vídeos" boosted_from_html: Promovida desde %{acct_link} content_warning: 'Aviso sobre o contido: %{warning}' + content_warnings: + hide: Ocultar publicación + show: Ver máis default_language: Igual que o idioma da interface disallowed_hashtags: one: 'contiña un cancelo non permitido: %{tags}' diff --git a/config/locales/lad.yml b/config/locales/lad.yml index 676de75e018145..df5188e5a3d263 100644 --- a/config/locales/lad.yml +++ b/config/locales/lad.yml @@ -479,6 +479,7 @@ lad: delete: Efasa finish_registration: Finaliza enrejistrasyon name: Nombre + registration_requested: Enrejistrasyon rekerida registrations: confirm: Konfirma reject: Refuza @@ -806,6 +807,9 @@ lad: all: A todos disabled: A dinguno users: Para los utilizadores lokales ke entrado en su kuento + feed_access: + modes: + public: Todos registrations: moderation_recommandation: Por favor, asigurate ke tyenes una taifa de moderasyon adekuada i reaktiva antes de avrir los enrejistramyentos a todos! preamble: Kontrola ken puede kriyar un kuento en tu sirvidor. @@ -860,6 +864,7 @@ lad: reblogs: Repartajasyones status_changed: Publikasyon trokada trending: Trendes + view_publicly: Ve puvlikamente visibility: Vizivilita with_media: Kon multimedia strikes: @@ -942,6 +947,7 @@ lad: action: Djenera history: Istorya live: En bivo + notify_users: Aviza a los utilizadores publish: Publika title: Terminos de servisyo title: Administrasyon @@ -1011,9 +1017,13 @@ lad: trending: En trend username_blocks: add_new: Adjusta muevo + block_registrations: Bloka enrejistrasyones + comparison: + contains: Kontyene delete: Efasa new: create: Kriya regla + not_permitted: Sin permiso warning_presets: add_new: Adjusta muevo delete: Efasa @@ -1442,6 +1452,12 @@ lad: expires_at: Kaduka uses: Uzos title: Envita a djente + link_preview: + author_html: Publikasyon de %{name} + potentially_sensitive_content: + action: Klika para amostrar + confirm_visit: Estas siguro ke keres avrir este atadijo? + hide_button: Eskonde lists: errors: limit: Tienes alkansado el karar maksimo de listas @@ -1541,6 +1557,10 @@ lad: title: Mueva enmentadura poll: subject: Una anketa de %{name} eskapo + quote: + body: 'Tu publikasyon fue sitada por %{name}:' + subject: "%{name} sito tu publikasyon" + title: Mueva sita reblog: body: 'Tu publikasyon fue repartajada por %{name}:' subject: "%{name} repartajo tu publikasyon" @@ -1646,6 +1666,7 @@ lad: scheduled_statuses: over_daily_limit: Tienes superado el limito de %{limit} publikasyones programadas para akel diya over_total_limit: Tienes superado el limito de %{limit} publikasyones programadas + too_soon: data tiene ke ser en el avenir self_destruct: lead_html: Malorozamente, %{domain} va serrar permanentemente. Si teniyas un kuento ayi, ya no podras utilizarlo, ama ainda puedes solisitar una kopya de tus datos. title: Este sirvidor esta serrando @@ -1739,6 +1760,9 @@ lad: other: "%{count} videos" boosted_from_html: Repartajado dizde %{acct_link} content_warning: 'Avertensya de kontenido: %{warning}' + content_warnings: + hide: Eskonde puvlikasyon + show: Amostra mas default_language: La mezma ke la lingua de la enterfaz disallowed_hashtags: one: 'kontenia una etiketa no permetida: %{tags}' @@ -1746,6 +1770,7 @@ lad: edited_at_html: Editado %{date} errors: in_reply_not_found: La publikasion a la ke aprovas arispondir no egziste. + quoted_status_not_found: La publikasion a la ke aprovas sitar no egziste. over_character_limit: limito de karakteres de %{max} superado pin_errors: direct: Las publikasyones ke son vizivles solo para los utilizadores enmentados no pueden fiksarse @@ -1753,7 +1778,9 @@ lad: ownership: La publikasyon de otra persona no puede fiksarse reblog: No se puede fixar una repartajasyon quote_policies: + followers: Solo suivantes nobody: Solo yo + public: Todos title: '%{name}: "%{quote}"' visibilities: direct: Enmentadura privada @@ -1835,6 +1862,8 @@ lad: recovery_instructions_html: Si piedres akseso a tu telefon, puedes uzar uno de los sigientes kodiches de rekuperasyon para obtener akseso a tu kuento. Mantenlos a salvo. Por enshemplo, puedes imprimirlos i guadrarlos kon otros dokumentos emportantes. webauthn: Yaves de sigurita user_mailer: + announcement_published: + subject: Pregon de servisyo appeal_approved: action: Preferensyas de kuento explanation: La apelasyon del amonestamiento kontra tu kuento del %{strike_date} ke mandates el %{appeal_date} fue achetada. Tu kuento se topa de muevo en dobro estado. diff --git a/config/locales/lv.yml b/config/locales/lv.yml index 1a97adc6d0ef10..d3fc9e18491abf 100644 --- a/config/locales/lv.yml +++ b/config/locales/lv.yml @@ -160,7 +160,7 @@ lv: suspension_irreversible: Šī konta dati ir neatgriezeniski izdzēsti. Tu vari atcelt konta darbības apturēšanu, lai tas būtu izmantojams, taču tas neatjaunos iepriekšējos datus. suspension_reversible_hint_html: Konta darbība ir apturēta, un dati tiks pilnībā noņemti %{date}. Līdz tam kontu var atjaunot bez jebkādām nelabvēlīgām sekām. Ja vēlies nekavējoties noņemt visus konta datus, to vari izdarīt zemāk. title: Konti - unblock_email: Atbloķēt e-pasta adresi + unblock_email: Atcelt e-pasta adreses liegumu unblocked_email_msg: "%{username} e-pasta adreses liegšana sekmīgi atcelta" unconfirmed_email: Neapstiprināts e-pasts undo_sensitized: Atcelt uzspiestu atzīmēšanu kā jūtīgu @@ -229,7 +229,7 @@ lv: silence_account: Ierobežot Kontu suspend_account: Apturēt Kontu unassigned_report: Atcelt Pārskata Piešķiršanu - unblock_email_account: Atbloķēt e-pasta adresi + unblock_email_account: Atcelt e-pasta adreses liegumu unsensitive_account: Atsaukt uzspiestu konta atzīmēšanu kā jūtīgu unsilence_account: Atcelt Konta Ierobežošanu unsuspend_account: Atcelt konta apturēšanu @@ -252,7 +252,7 @@ lv: create_canonical_email_block_html: "%{name} liedza e-pasta adresi ar jaucējkodu %{target}" create_custom_emoji_html: "%{name} augšupielādēja jaunu emocijzīmi %{target}" create_domain_allow_html: "%{name} atļāva federāciju ar domēnu %{target}" - create_domain_block_html: "%{name} bloķēja domēnu %{target}" + create_domain_block_html: "%{name} liedza domēnu %{target}" create_email_domain_block_html: "%{name} liedza e-pasta domēnu %{target}" create_ip_block_html: "%{name} izveidoja nosacījumu priekš IP %{target}" create_unavailable_domain_html: "%{name} apturēja piegādi uz domēnu %{target}" @@ -262,7 +262,7 @@ lv: destroy_canonical_email_block_html: "%{name} atcēla e-pasta adreses liegumu ar jaucējvērtību %{target}" destroy_custom_emoji_html: "%{name} izdzēsa emocijzīmi %{target}" destroy_domain_allow_html: "%{name} neatļāva federāciju ar domēnu %{target}" - destroy_domain_block_html: "%{name} atbloķēja domēnu %{target}" + destroy_domain_block_html: "%{name} atcēla domēna %{target} liegšanu" destroy_email_domain_block_html: "%{name} atcēla e-pasta domēna %{target} liegumu" destroy_instance_html: "%{name} attīrija domēnu %{target}" destroy_ip_block_html: "%{name} izdzēsa nosacījumu priekš IP %{target}" @@ -288,7 +288,7 @@ lv: silence_account_html: "%{name} ierobežoja %{target} kontu" suspend_account_html: "%{name} apturēja %{target} kontu" unassigned_report_html: "%{name} nepiešķīra ziņojumu %{target}" - unblock_email_account_html: "%{name} atbloķēja %{target} e-pasta adresi" + unblock_email_account_html: "%{name} atcēla %{target} e-pasta adreses liegšanu" unsensitive_account_html: "%{name} atcēla %{target} informācijas nesēja atzīmēšanu kā jūtīgu" unsilence_account_html: "%{name} atcēla ierobežojumu %{target} kontam" unsuspend_account_html: "%{name} neapturēja %{target} kontu" @@ -412,12 +412,12 @@ lv: preamble_html: Tu gatavojies apturēt domēna %{domain} un tā apakšdomēnu darbību. remove_all_data: Tādējādi no tava servera tiks noņemts viss šī domēna kontu saturs, multivide un profila dati. stop_communication: Tavs serveris pārtrauks sazināties ar šiem serveriem. - title: Apstiprināt domēna %{domain} bloķēšanu + title: Apstiprināt domēna %{domain} liegšanu undo_relationships: Tādējādi tiks atsauktas jebkuras sekošanas attiecības starp šo un tavu serveru kontiem. - created_msg: Domēna bloķēšana tagad tiek apstrādāta - destroyed_msg: Domēna bloķēšana ir atsaukta + created_msg: Domēna liegšana tagad tiek apstrādāta + destroyed_msg: Domēna liegšana tika atsaukta domain: Domēns - edit: Labot domēna aizturēšanu + edit: Labot domēna liegšanu existing_domain_block: Tu jau esi noteicis stingrākus ierobežojumus %{name}. existing_domain_block_html: Tu jau esi noteicis stingrākus ierobežojumus %{name}, vispirms tev jāatbloķē. export: Eksportēt diff --git a/config/locales/pt-PT.yml b/config/locales/pt-PT.yml index 208a91eb531641..e420d0c2f929ce 100644 --- a/config/locales/pt-PT.yml +++ b/config/locales/pt-PT.yml @@ -848,6 +848,10 @@ pt-PT: all: Para toda a gente disabled: Para ninguém users: Para utilizadores locais que se encontrem autenticados + feed_access: + modes: + authenticated: Apesar utilizadores autenticados + public: Todos registrations: moderation_recommandation: Certifique-se de que dispõe de uma equipa de moderação adequada e reativa antes de abrir as inscrições a todos! preamble: Controle quem pode criar uma conta no seu servidor. @@ -1584,6 +1588,13 @@ pt-PT: expires_at: Expira uses: Utilizações title: Convidar pessoas + link_preview: + author_html: Por %{name} + potentially_sensitive_content: + action: Clicar para mostrar + confirm_visit: Tem a certeza que prentende abrir esta ligação? + hide_button: Esconder + label: Conteúdo potencialmente sensível lists: errors: limit: Atingiste o número máximo de listas permitido @@ -1894,6 +1905,9 @@ pt-PT: other: "%{count} vídeos" boosted_from_html: Impulsionado por %{acct_link} content_warning: 'Aviso de conteúdo: %{warning}' + content_warnings: + hide: Esconder publicação + show: Mostrar mais default_language: Igual ao idioma da interface disallowed_hashtags: one: 'continha uma #etiqueta proibida: %{tags}' diff --git a/config/locales/simple_form.et.yml b/config/locales/simple_form.et.yml index 603d00f26d053a..8fcdc5bb5b607c 100644 --- a/config/locales/simple_form.et.yml +++ b/config/locales/simple_form.et.yml @@ -283,12 +283,16 @@ et: content_cache_retention_period: Kaugsisu säilitamise aeg custom_css: Kohandatud CSS favicon: Favicon + local_live_feed_access: Ligipääs kohalike postituste voole + local_topic_feed_access: Ligipääs kohalike postitustele viitavale teemaviidete ja linkide voole mascot: Kohandatud maskott (kunagine) media_cache_retention_period: Meediapuhvri talletusperiood min_age: Vanuse alampiiri nõue peers_api_enabled: Avalda avastatud serverite loetelu API kaudu profile_directory: Luba kasutajate kataloog registrations_mode: Kes saab liituda + remote_live_feed_access: Ligipääs muude serverite postituste voole + remote_topic_feed_access: Ligipääs muude serverite postitustele viitavale teemaviidete ja linkide voole require_invite_text: Nõua liitumiseks põhjendust show_domain_blocks: Näita domeenikeelde show_domain_blocks_rationale: Näite domeenikeeldude põhjuseid diff --git a/config/locales/simple_form.lad.yml b/config/locales/simple_form.lad.yml index f11eb946e529b0..eaf7c9d9c859e8 100644 --- a/config/locales/simple_form.lad.yml +++ b/config/locales/simple_form.lad.yml @@ -202,13 +202,17 @@ lad: setting_auto_play_gif: Siempre reproduse los GIFs animados setting_boost_modal: Amostra ventana de konfirmasyon antes de repartajar setting_default_language: Lingua de publikasyones + setting_default_privacy: Vizibilita de puvlikasyones + setting_default_quote_policy: Ken puede sitar setting_default_sensitive: Syempre marka multimedia komo sensivles setting_delete_modal: Mostra dialogo de konfirmasyon antes de efasar una publikasyon + setting_disable_hover_cards: Dezaktiva vista previa del profil al pasar el kursor setting_disable_swiping: Inkapasita movimyentos de arresvalamiento setting_display_media: Vizualizasyon de multimedia setting_display_media_default: Predeterminado setting_display_media_hide_all: Eskonde todo setting_display_media_show_all: Amostra todo + setting_emoji_style: Estilo de emoji setting_expand_spoilers: Siempre espande las publikasyones markadas kon avertensyas de kontenido setting_hide_network: Eskonde tu red sosyala setting_reduce_motion: Reduse el movimyento en animasyones @@ -285,6 +289,7 @@ lad: follow_request: Alguno tiene solisitado segirte mention: Alguno te enmento pending_account: Muevo kuento nesesita revizyon + quote: Alguno te sita reblog: Alguno repartajo tu publikasyon report: Muevo raporto fue embiado software_updates: @@ -309,6 +314,7 @@ lad: changelog: Ke troko? text: Terminos de servisyo terms_of_service_generator: + choice_of_law: Legislasyon aplikavle domain: Domeno user: date_of_birth_1i: Diya From 28339cad6dbb2e6ba8d8a69f881536901e1ba686 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 16 Oct 2025 12:29:13 +0200 Subject: [PATCH 189/853] Update dependency rollup-plugin-visualizer to v6.0.5 (#36499) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 69908cafc72aa6..2246f4d045139f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11865,8 +11865,8 @@ __metadata: linkType: hard "rollup-plugin-visualizer@npm:^6.0.3": - version: 6.0.4 - resolution: "rollup-plugin-visualizer@npm:6.0.4" + version: 6.0.5 + resolution: "rollup-plugin-visualizer@npm:6.0.5" dependencies: open: "npm:^8.0.0" picomatch: "npm:^4.0.2" @@ -11882,7 +11882,7 @@ __metadata: optional: true bin: rollup-plugin-visualizer: dist/bin/cli.js - checksum: 10c0/e5d472bec0c863c9c3c46f55b303a9457e854bf1b654215e727a586da12897e2cfc30029f029c6c44dd8e9e61ce0d22f113a68ed8e5fe2256abeb58f265c0a89 + checksum: 10c0/3824626e97d5033fbb3aa1bbe93c8c17a8569bc47e33c941bde6b90404f2cae70b26fec1b623bd393c3e076338014196c91726ed2c96218edc67e1f21676f7ef languageName: node linkType: hard From 7530f06deea63a03e0ca05f777f0f1582372c305 Mon Sep 17 00:00:00 2001 From: Echo Date: Thu, 16 Oct 2025 14:46:17 +0200 Subject: [PATCH 190/853] Emoji: Fix autoplay incorrectly being applied (#36503) --- app/javascript/mastodon/components/emoji/context.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/mastodon/components/emoji/context.tsx b/app/javascript/mastodon/components/emoji/context.tsx index 9fda5714d97d4c..730ae743ed9769 100644 --- a/app/javascript/mastodon/components/emoji/context.tsx +++ b/app/javascript/mastodon/components/emoji/context.tsx @@ -63,7 +63,7 @@ export const AnimateEmojiProvider = polymorphicForwardRef< // If there's a parent context or GIFs autoplay, we don't need handlers. const parentContext = useContext(AnimateEmojiContext); - if (parentContext !== null || autoPlayGif === true) { + if (parentContext !== null) { return ( Date: Thu, 16 Oct 2025 15:15:16 +0200 Subject: [PATCH 191/853] Emoji: Update Twemoji to v16 (#36501) --- .../mastodon/features/emoji/emoji_data.json | 2 +- .../mastodon/features/emoji/emoji_map.json | 2 +- .../mastodon/features/emoji/emoji_picker.tsx | 2 +- lib/tasks/emojis.rake | 7 ++++--- public/emoji/1f1e8-1f1f6.svg | 1 + public/emoji/1f426-200d-2b1b.svg | 0 public/emoji/1f6dd.svg | 0 public/emoji/1f6de.svg | 0 public/emoji/1f6df.svg | 0 public/emoji/1f7f0.svg | 0 public/emoji/1f91d-1f3fb.svg | 0 public/emoji/1f91d-1f3fc.svg | 0 public/emoji/1f91d-1f3fd.svg | 0 public/emoji/1f91d-1f3fe.svg | 0 public/emoji/1f91d-1f3ff.svg | 0 public/emoji/1f9cc.svg | 0 public/emoji/1fa75.svg | 0 public/emoji/1fa76.svg | 0 public/emoji/1fa77.svg | 0 public/emoji/1fa7b.svg | 0 public/emoji/1fa7c.svg | 0 public/emoji/1fa88.svg | 0 public/emoji/1fa89.svg | 1 + public/emoji/1fa8f.svg | 1 + public/emoji/1faa9.svg | 0 public/emoji/1faaa.svg | 0 public/emoji/1faab.svg | 0 public/emoji/1faac.svg | 0 public/emoji/1fab7.svg | 0 public/emoji/1fab8.svg | 0 public/emoji/1fab9.svg | 0 public/emoji/1faba.svg | 0 public/emoji/1fabe.svg | 1 + public/emoji/1fac3-1f3fb.svg | 0 public/emoji/1fac3-1f3fc.svg | 0 public/emoji/1fac3-1f3fd.svg | 0 public/emoji/1fac3-1f3fe.svg | 0 public/emoji/1fac3-1f3ff.svg | 0 public/emoji/1fac3.svg | 0 public/emoji/1fac4-1f3fb.svg | 0 public/emoji/1fac4-1f3fc.svg | 0 public/emoji/1fac4-1f3fd.svg | 0 public/emoji/1fac4-1f3fe.svg | 0 public/emoji/1fac4-1f3ff.svg | 0 public/emoji/1fac4.svg | 0 public/emoji/1fac5-1f3fb.svg | 0 public/emoji/1fac5-1f3fc.svg | 0 public/emoji/1fac5-1f3fd.svg | 0 public/emoji/1fac5-1f3fe.svg | 0 public/emoji/1fac5-1f3ff.svg | 0 public/emoji/1fac5.svg | 0 public/emoji/1fac6.svg | 1 + public/emoji/1fad7.svg | 0 public/emoji/1fad8.svg | 0 public/emoji/1fad9.svg | 0 public/emoji/1fadc.svg | 1 + public/emoji/1fadf.svg | 1 + public/emoji/1fae0.svg | 0 public/emoji/1fae1.svg | 0 public/emoji/1fae2.svg | 0 public/emoji/1fae3.svg | 0 public/emoji/1fae4.svg | 0 public/emoji/1fae5.svg | 0 public/emoji/1fae6.svg | 0 public/emoji/1fae7.svg | 0 public/emoji/1fae9.svg | 1 + public/emoji/1faf0-1f3fb.svg | 0 public/emoji/1faf0-1f3fc.svg | 0 public/emoji/1faf0-1f3fd.svg | 0 public/emoji/1faf0-1f3fe.svg | 0 public/emoji/1faf0-1f3ff.svg | 0 public/emoji/1faf0.svg | 0 public/emoji/1faf1-1f3fb-200d-1faf2-1f3fc.svg | 0 public/emoji/1faf1-1f3fb-200d-1faf2-1f3fd.svg | 0 public/emoji/1faf1-1f3fb-200d-1faf2-1f3fe.svg | 0 public/emoji/1faf1-1f3fb-200d-1faf2-1f3ff.svg | 0 public/emoji/1faf1-1f3fb.svg | 0 public/emoji/1faf1-1f3fc-200d-1faf2-1f3fb.svg | 0 public/emoji/1faf1-1f3fc-200d-1faf2-1f3fd.svg | 0 public/emoji/1faf1-1f3fc-200d-1faf2-1f3fe.svg | 0 public/emoji/1faf1-1f3fc-200d-1faf2-1f3ff.svg | 0 public/emoji/1faf1-1f3fc.svg | 0 public/emoji/1faf1-1f3fd-200d-1faf2-1f3fb.svg | 0 public/emoji/1faf1-1f3fd-200d-1faf2-1f3fc.svg | 0 public/emoji/1faf1-1f3fd-200d-1faf2-1f3fe.svg | 0 public/emoji/1faf1-1f3fd-200d-1faf2-1f3ff.svg | 0 public/emoji/1faf1-1f3fd.svg | 0 public/emoji/1faf1-1f3fe-200d-1faf2-1f3fb.svg | 0 public/emoji/1faf1-1f3fe-200d-1faf2-1f3fc.svg | 0 public/emoji/1faf1-1f3fe-200d-1faf2-1f3fd.svg | 0 public/emoji/1faf1-1f3fe-200d-1faf2-1f3ff.svg | 0 public/emoji/1faf1-1f3fe.svg | 0 public/emoji/1faf1-1f3ff-200d-1faf2-1f3fb.svg | 0 public/emoji/1faf1-1f3ff-200d-1faf2-1f3fc.svg | 0 public/emoji/1faf1-1f3ff-200d-1faf2-1f3fd.svg | 0 public/emoji/1faf1-1f3ff-200d-1faf2-1f3fe.svg | 0 public/emoji/1faf1-1f3ff.svg | 0 public/emoji/1faf1.svg | 0 public/emoji/1faf2-1f3fb.svg | 0 public/emoji/1faf2-1f3fc.svg | 0 public/emoji/1faf2-1f3fd.svg | 0 public/emoji/1faf2-1f3fe.svg | 0 public/emoji/1faf2-1f3ff.svg | 0 public/emoji/1faf2.svg | 0 public/emoji/1faf3-1f3fb.svg | 0 public/emoji/1faf3-1f3fc.svg | 0 public/emoji/1faf3-1f3fd.svg | 0 public/emoji/1faf3-1f3fe.svg | 0 public/emoji/1faf3-1f3ff.svg | 0 public/emoji/1faf3.svg | 0 public/emoji/1faf4-1f3fb.svg | 0 public/emoji/1faf4-1f3fc.svg | 0 public/emoji/1faf4-1f3fd.svg | 0 public/emoji/1faf4-1f3fe.svg | 0 public/emoji/1faf4-1f3ff.svg | 0 public/emoji/1faf4.svg | 0 public/emoji/1faf5-1f3fb.svg | 0 public/emoji/1faf5-1f3fc.svg | 0 public/emoji/1faf5-1f3fd.svg | 0 public/emoji/1faf5-1f3fe.svg | 0 public/emoji/1faf5-1f3ff.svg | 0 public/emoji/1faf5.svg | 0 public/emoji/1faf6-1f3fb.svg | 0 public/emoji/1faf6-1f3fc.svg | 0 public/emoji/1faf6-1f3fd.svg | 0 public/emoji/1faf6-1f3fe.svg | 0 public/emoji/1faf6-1f3ff.svg | 0 public/emoji/1faf6.svg | 0 public/emoji/sheet_16_0.png | Bin 0 -> 1312532 bytes 129 files changed, 15 insertions(+), 6 deletions(-) create mode 100644 public/emoji/1f1e8-1f1f6.svg mode change 100755 => 100644 public/emoji/1f426-200d-2b1b.svg mode change 100755 => 100644 public/emoji/1f6dd.svg mode change 100755 => 100644 public/emoji/1f6de.svg mode change 100755 => 100644 public/emoji/1f6df.svg mode change 100755 => 100644 public/emoji/1f7f0.svg mode change 100755 => 100644 public/emoji/1f91d-1f3fb.svg mode change 100755 => 100644 public/emoji/1f91d-1f3fc.svg mode change 100755 => 100644 public/emoji/1f91d-1f3fd.svg mode change 100755 => 100644 public/emoji/1f91d-1f3fe.svg mode change 100755 => 100644 public/emoji/1f91d-1f3ff.svg mode change 100755 => 100644 public/emoji/1f9cc.svg mode change 100755 => 100644 public/emoji/1fa75.svg mode change 100755 => 100644 public/emoji/1fa76.svg mode change 100755 => 100644 public/emoji/1fa77.svg mode change 100755 => 100644 public/emoji/1fa7b.svg mode change 100755 => 100644 public/emoji/1fa7c.svg mode change 100755 => 100644 public/emoji/1fa88.svg create mode 100644 public/emoji/1fa89.svg create mode 100644 public/emoji/1fa8f.svg mode change 100755 => 100644 public/emoji/1faa9.svg mode change 100755 => 100644 public/emoji/1faaa.svg mode change 100755 => 100644 public/emoji/1faab.svg mode change 100755 => 100644 public/emoji/1faac.svg mode change 100755 => 100644 public/emoji/1fab7.svg mode change 100755 => 100644 public/emoji/1fab8.svg mode change 100755 => 100644 public/emoji/1fab9.svg mode change 100755 => 100644 public/emoji/1faba.svg create mode 100644 public/emoji/1fabe.svg mode change 100755 => 100644 public/emoji/1fac3-1f3fb.svg mode change 100755 => 100644 public/emoji/1fac3-1f3fc.svg mode change 100755 => 100644 public/emoji/1fac3-1f3fd.svg mode change 100755 => 100644 public/emoji/1fac3-1f3fe.svg mode change 100755 => 100644 public/emoji/1fac3-1f3ff.svg mode change 100755 => 100644 public/emoji/1fac3.svg mode change 100755 => 100644 public/emoji/1fac4-1f3fb.svg mode change 100755 => 100644 public/emoji/1fac4-1f3fc.svg mode change 100755 => 100644 public/emoji/1fac4-1f3fd.svg mode change 100755 => 100644 public/emoji/1fac4-1f3fe.svg mode change 100755 => 100644 public/emoji/1fac4-1f3ff.svg mode change 100755 => 100644 public/emoji/1fac4.svg mode change 100755 => 100644 public/emoji/1fac5-1f3fb.svg mode change 100755 => 100644 public/emoji/1fac5-1f3fc.svg mode change 100755 => 100644 public/emoji/1fac5-1f3fd.svg mode change 100755 => 100644 public/emoji/1fac5-1f3fe.svg mode change 100755 => 100644 public/emoji/1fac5-1f3ff.svg mode change 100755 => 100644 public/emoji/1fac5.svg create mode 100644 public/emoji/1fac6.svg mode change 100755 => 100644 public/emoji/1fad7.svg mode change 100755 => 100644 public/emoji/1fad8.svg mode change 100755 => 100644 public/emoji/1fad9.svg create mode 100644 public/emoji/1fadc.svg create mode 100644 public/emoji/1fadf.svg mode change 100755 => 100644 public/emoji/1fae0.svg mode change 100755 => 100644 public/emoji/1fae1.svg mode change 100755 => 100644 public/emoji/1fae2.svg mode change 100755 => 100644 public/emoji/1fae3.svg mode change 100755 => 100644 public/emoji/1fae4.svg mode change 100755 => 100644 public/emoji/1fae5.svg mode change 100755 => 100644 public/emoji/1fae6.svg mode change 100755 => 100644 public/emoji/1fae7.svg create mode 100644 public/emoji/1fae9.svg mode change 100755 => 100644 public/emoji/1faf0-1f3fb.svg mode change 100755 => 100644 public/emoji/1faf0-1f3fc.svg mode change 100755 => 100644 public/emoji/1faf0-1f3fd.svg mode change 100755 => 100644 public/emoji/1faf0-1f3fe.svg mode change 100755 => 100644 public/emoji/1faf0-1f3ff.svg mode change 100755 => 100644 public/emoji/1faf0.svg mode change 100755 => 100644 public/emoji/1faf1-1f3fb-200d-1faf2-1f3fc.svg mode change 100755 => 100644 public/emoji/1faf1-1f3fb-200d-1faf2-1f3fd.svg mode change 100755 => 100644 public/emoji/1faf1-1f3fb-200d-1faf2-1f3fe.svg mode change 100755 => 100644 public/emoji/1faf1-1f3fb-200d-1faf2-1f3ff.svg mode change 100755 => 100644 public/emoji/1faf1-1f3fb.svg mode change 100755 => 100644 public/emoji/1faf1-1f3fc-200d-1faf2-1f3fb.svg mode change 100755 => 100644 public/emoji/1faf1-1f3fc-200d-1faf2-1f3fd.svg mode change 100755 => 100644 public/emoji/1faf1-1f3fc-200d-1faf2-1f3fe.svg mode change 100755 => 100644 public/emoji/1faf1-1f3fc-200d-1faf2-1f3ff.svg mode change 100755 => 100644 public/emoji/1faf1-1f3fc.svg mode change 100755 => 100644 public/emoji/1faf1-1f3fd-200d-1faf2-1f3fb.svg mode change 100755 => 100644 public/emoji/1faf1-1f3fd-200d-1faf2-1f3fc.svg mode change 100755 => 100644 public/emoji/1faf1-1f3fd-200d-1faf2-1f3fe.svg mode change 100755 => 100644 public/emoji/1faf1-1f3fd-200d-1faf2-1f3ff.svg mode change 100755 => 100644 public/emoji/1faf1-1f3fd.svg mode change 100755 => 100644 public/emoji/1faf1-1f3fe-200d-1faf2-1f3fb.svg mode change 100755 => 100644 public/emoji/1faf1-1f3fe-200d-1faf2-1f3fc.svg mode change 100755 => 100644 public/emoji/1faf1-1f3fe-200d-1faf2-1f3fd.svg mode change 100755 => 100644 public/emoji/1faf1-1f3fe-200d-1faf2-1f3ff.svg mode change 100755 => 100644 public/emoji/1faf1-1f3fe.svg mode change 100755 => 100644 public/emoji/1faf1-1f3ff-200d-1faf2-1f3fb.svg mode change 100755 => 100644 public/emoji/1faf1-1f3ff-200d-1faf2-1f3fc.svg mode change 100755 => 100644 public/emoji/1faf1-1f3ff-200d-1faf2-1f3fd.svg mode change 100755 => 100644 public/emoji/1faf1-1f3ff-200d-1faf2-1f3fe.svg mode change 100755 => 100644 public/emoji/1faf1-1f3ff.svg mode change 100755 => 100644 public/emoji/1faf1.svg mode change 100755 => 100644 public/emoji/1faf2-1f3fb.svg mode change 100755 => 100644 public/emoji/1faf2-1f3fc.svg mode change 100755 => 100644 public/emoji/1faf2-1f3fd.svg mode change 100755 => 100644 public/emoji/1faf2-1f3fe.svg mode change 100755 => 100644 public/emoji/1faf2-1f3ff.svg mode change 100755 => 100644 public/emoji/1faf2.svg mode change 100755 => 100644 public/emoji/1faf3-1f3fb.svg mode change 100755 => 100644 public/emoji/1faf3-1f3fc.svg mode change 100755 => 100644 public/emoji/1faf3-1f3fd.svg mode change 100755 => 100644 public/emoji/1faf3-1f3fe.svg mode change 100755 => 100644 public/emoji/1faf3-1f3ff.svg mode change 100755 => 100644 public/emoji/1faf3.svg mode change 100755 => 100644 public/emoji/1faf4-1f3fb.svg mode change 100755 => 100644 public/emoji/1faf4-1f3fc.svg mode change 100755 => 100644 public/emoji/1faf4-1f3fd.svg mode change 100755 => 100644 public/emoji/1faf4-1f3fe.svg mode change 100755 => 100644 public/emoji/1faf4-1f3ff.svg mode change 100755 => 100644 public/emoji/1faf4.svg mode change 100755 => 100644 public/emoji/1faf5-1f3fb.svg mode change 100755 => 100644 public/emoji/1faf5-1f3fc.svg mode change 100755 => 100644 public/emoji/1faf5-1f3fd.svg mode change 100755 => 100644 public/emoji/1faf5-1f3fe.svg mode change 100755 => 100644 public/emoji/1faf5-1f3ff.svg mode change 100755 => 100644 public/emoji/1faf5.svg mode change 100755 => 100644 public/emoji/1faf6-1f3fb.svg mode change 100755 => 100644 public/emoji/1faf6-1f3fc.svg mode change 100755 => 100644 public/emoji/1faf6-1f3fd.svg mode change 100755 => 100644 public/emoji/1faf6-1f3fe.svg mode change 100755 => 100644 public/emoji/1faf6-1f3ff.svg mode change 100755 => 100644 public/emoji/1faf6.svg create mode 100644 public/emoji/sheet_16_0.png diff --git a/app/javascript/mastodon/features/emoji/emoji_data.json b/app/javascript/mastodon/features/emoji/emoji_data.json index 4d7a48692bec81..7ef1c9838b2849 100644 --- a/app/javascript/mastodon/features/emoji/emoji_data.json +++ b/app/javascript/mastodon/features/emoji/emoji_data.json @@ -1 +1 @@ -{"compressed":true,"categories":[{"id":"people","name":"Smileys & People","emojis":["grinning","smiley","smile","grin","laughing","sweat_smile","rolling_on_the_floor_laughing","joy","slightly_smiling_face","upside_down_face","melting_face","wink","blush","innocent","smiling_face_with_3_hearts","heart_eyes","star-struck","kissing_heart","kissing","relaxed","kissing_closed_eyes","kissing_smiling_eyes","smiling_face_with_tear","yum","stuck_out_tongue","stuck_out_tongue_winking_eye","zany_face","stuck_out_tongue_closed_eyes","money_mouth_face","hugging_face","face_with_hand_over_mouth","face_with_open_eyes_and_hand_over_mouth","face_with_peeking_eye","shushing_face","thinking_face","saluting_face","zipper_mouth_face","face_with_raised_eyebrow","neutral_face","expressionless","no_mouth","dotted_line_face","face_in_clouds","smirk","unamused","face_with_rolling_eyes","grimacing","face_exhaling","lying_face","shaking_face","head_shaking_horizontally","head_shaking_vertically","relieved","pensive","sleepy","drooling_face","sleeping","mask","face_with_thermometer","face_with_head_bandage","nauseated_face","face_vomiting","sneezing_face","hot_face","cold_face","woozy_face","dizzy_face","face_with_spiral_eyes","exploding_head","face_with_cowboy_hat","partying_face","disguised_face","sunglasses","nerd_face","face_with_monocle","confused","face_with_diagonal_mouth","worried","slightly_frowning_face","white_frowning_face","open_mouth","hushed","astonished","flushed","pleading_face","face_holding_back_tears","frowning","anguished","fearful","cold_sweat","disappointed_relieved","cry","sob","scream","confounded","persevere","disappointed","sweat","weary","tired_face","yawning_face","triumph","rage","angry","face_with_symbols_on_mouth","smiling_imp","imp","skull","skull_and_crossbones","hankey","clown_face","japanese_ogre","japanese_goblin","ghost","alien","space_invader","robot_face","smiley_cat","smile_cat","joy_cat","heart_eyes_cat","smirk_cat","kissing_cat","scream_cat","crying_cat_face","pouting_cat","see_no_evil","hear_no_evil","speak_no_evil","wave","raised_back_of_hand","raised_hand_with_fingers_splayed","hand","spock-hand","rightwards_hand","leftwards_hand","palm_down_hand","palm_up_hand","leftwards_pushing_hand","rightwards_pushing_hand","ok_hand","pinched_fingers","pinching_hand","v","crossed_fingers","hand_with_index_finger_and_thumb_crossed","i_love_you_hand_sign","the_horns","call_me_hand","point_left","point_right","point_up_2","middle_finger","point_down","point_up","index_pointing_at_the_viewer","+1","-1","fist","facepunch","left-facing_fist","right-facing_fist","clap","raised_hands","heart_hands","open_hands","palms_up_together","handshake","pray","writing_hand","nail_care","selfie","muscle","mechanical_arm","mechanical_leg","leg","foot","ear","ear_with_hearing_aid","nose","brain","anatomical_heart","lungs","tooth","bone","eyes","eye","tongue","lips","biting_lip","baby","child","boy","girl","adult","person_with_blond_hair","man","bearded_person","man_with_beard","woman_with_beard","red_haired_man","curly_haired_man","white_haired_man","bald_man","woman","red_haired_woman","red_haired_person","curly_haired_woman","curly_haired_person","white_haired_woman","white_haired_person","bald_woman","bald_person","blond-haired-woman","blond-haired-man","older_adult","older_man","older_woman","person_frowning","man-frowning","woman-frowning","person_with_pouting_face","man-pouting","woman-pouting","no_good","man-gesturing-no","woman-gesturing-no","ok_woman","man-gesturing-ok","woman-gesturing-ok","information_desk_person","man-tipping-hand","woman-tipping-hand","raising_hand","man-raising-hand","woman-raising-hand","deaf_person","deaf_man","deaf_woman","bow","man-bowing","woman-bowing","face_palm","man-facepalming","woman-facepalming","shrug","man-shrugging","woman-shrugging","health_worker","male-doctor","female-doctor","student","male-student","female-student","teacher","male-teacher","female-teacher","judge","male-judge","female-judge","farmer","male-farmer","female-farmer","cook","male-cook","female-cook","mechanic","male-mechanic","female-mechanic","factory_worker","male-factory-worker","female-factory-worker","office_worker","male-office-worker","female-office-worker","scientist","male-scientist","female-scientist","technologist","male-technologist","female-technologist","singer","male-singer","female-singer","artist","male-artist","female-artist","pilot","male-pilot","female-pilot","astronaut","male-astronaut","female-astronaut","firefighter","male-firefighter","female-firefighter","cop","male-police-officer","female-police-officer","sleuth_or_spy","male-detective","female-detective","guardsman","male-guard","female-guard","ninja","construction_worker","male-construction-worker","female-construction-worker","person_with_crown","prince","princess","man_with_turban","man-wearing-turban","woman-wearing-turban","man_with_gua_pi_mao","person_with_headscarf","person_in_tuxedo","man_in_tuxedo","woman_in_tuxedo","bride_with_veil","man_with_veil","woman_with_veil","pregnant_woman","pregnant_man","pregnant_person","breast-feeding","woman_feeding_baby","man_feeding_baby","person_feeding_baby","angel","santa","mrs_claus","mx_claus","superhero","male_superhero","female_superhero","supervillain","male_supervillain","female_supervillain","mage","male_mage","female_mage","fairy","male_fairy","female_fairy","vampire","male_vampire","female_vampire","merperson","merman","mermaid","elf","male_elf","female_elf","genie","male_genie","female_genie","zombie","male_zombie","female_zombie","troll","massage","man-getting-massage","woman-getting-massage","haircut","man-getting-haircut","woman-getting-haircut","walking","man-walking","woman-walking","person_walking_facing_right","woman_walking_facing_right","man_walking_facing_right","standing_person","man_standing","woman_standing","kneeling_person","man_kneeling","woman_kneeling","person_kneeling_facing_right","woman_kneeling_facing_right","man_kneeling_facing_right","person_with_probing_cane","person_with_white_cane_facing_right","man_with_probing_cane","man_with_white_cane_facing_right","woman_with_probing_cane","woman_with_white_cane_facing_right","person_in_motorized_wheelchair","person_in_motorized_wheelchair_facing_right","man_in_motorized_wheelchair","man_in_motorized_wheelchair_facing_right","woman_in_motorized_wheelchair","woman_in_motorized_wheelchair_facing_right","person_in_manual_wheelchair","person_in_manual_wheelchair_facing_right","man_in_manual_wheelchair","man_in_manual_wheelchair_facing_right","woman_in_manual_wheelchair","woman_in_manual_wheelchair_facing_right","runner","man-running","woman-running","person_running_facing_right","woman_running_facing_right","man_running_facing_right","dancer","man_dancing","man_in_business_suit_levitating","dancers","men-with-bunny-ears-partying","women-with-bunny-ears-partying","person_in_steamy_room","man_in_steamy_room","woman_in_steamy_room","person_climbing","man_climbing","woman_climbing","fencer","horse_racing","skier","snowboarder","golfer","man-golfing","woman-golfing","surfer","man-surfing","woman-surfing","rowboat","man-rowing-boat","woman-rowing-boat","swimmer","man-swimming","woman-swimming","person_with_ball","man-bouncing-ball","woman-bouncing-ball","weight_lifter","man-lifting-weights","woman-lifting-weights","bicyclist","man-biking","woman-biking","mountain_bicyclist","man-mountain-biking","woman-mountain-biking","person_doing_cartwheel","man-cartwheeling","woman-cartwheeling","wrestlers","man-wrestling","woman-wrestling","water_polo","man-playing-water-polo","woman-playing-water-polo","handball","man-playing-handball","woman-playing-handball","juggling","man-juggling","woman-juggling","person_in_lotus_position","man_in_lotus_position","woman_in_lotus_position","bath","sleeping_accommodation","people_holding_hands","two_women_holding_hands","man_and_woman_holding_hands","two_men_holding_hands","couplekiss","woman-kiss-man","man-kiss-man","woman-kiss-woman","couple_with_heart","woman-heart-man","man-heart-man","woman-heart-woman","man-woman-boy","man-woman-girl","man-woman-girl-boy","man-woman-boy-boy","man-woman-girl-girl","man-man-boy","man-man-girl","man-man-girl-boy","man-man-boy-boy","man-man-girl-girl","woman-woman-boy","woman-woman-girl","woman-woman-girl-boy","woman-woman-boy-boy","woman-woman-girl-girl","man-boy","man-boy-boy","man-girl","man-girl-boy","man-girl-girl","woman-boy","woman-boy-boy","woman-girl","woman-girl-boy","woman-girl-girl","speaking_head_in_silhouette","bust_in_silhouette","busts_in_silhouette","people_hugging","family","family_adult_adult_child","family_adult_adult_child_child","family_adult_child","family_adult_child_child","footprints","love_letter","cupid","gift_heart","sparkling_heart","heartpulse","heartbeat","revolving_hearts","two_hearts","heart_decoration","heavy_heart_exclamation_mark_ornament","broken_heart","heart_on_fire","mending_heart","heart","pink_heart","orange_heart","yellow_heart","green_heart","blue_heart","light_blue_heart","purple_heart","brown_heart","black_heart","grey_heart","white_heart","kiss","100","anger","boom","dizzy","sweat_drops","dash","hole","speech_balloon","eye-in-speech-bubble","left_speech_bubble","right_anger_bubble","thought_balloon","zzz"]},{"id":"nature","name":"Animals & Nature","emojis":["monkey_face","monkey","gorilla","orangutan","dog","dog2","guide_dog","service_dog","poodle","wolf","fox_face","raccoon","cat","cat2","black_cat","lion_face","tiger","tiger2","leopard","horse","moose","donkey","racehorse","unicorn_face","zebra_face","deer","bison","cow","ox","water_buffalo","cow2","pig","pig2","boar","pig_nose","ram","sheep","goat","dromedary_camel","camel","llama","giraffe_face","elephant","mammoth","rhinoceros","hippopotamus","mouse","mouse2","rat","hamster","rabbit","rabbit2","chipmunk","beaver","hedgehog","bat","bear","polar_bear","koala","panda_face","sloth","otter","skunk","kangaroo","badger","feet","turkey","chicken","rooster","hatching_chick","baby_chick","hatched_chick","bird","penguin","dove_of_peace","eagle","duck","swan","owl","dodo","feather","flamingo","peacock","parrot","wing","black_bird","goose","phoenix","frog","crocodile","turtle","lizard","snake","dragon_face","dragon","sauropod","t-rex","whale","whale2","dolphin","seal","fish","tropical_fish","blowfish","shark","octopus","shell","coral","jellyfish","snail","butterfly","bug","ant","bee","beetle","ladybug","cricket","cockroach","spider","spider_web","scorpion","mosquito","fly","worm","microbe","bouquet","cherry_blossom","white_flower","lotus","rosette","rose","wilted_flower","hibiscus","sunflower","blossom","tulip","hyacinth","seedling","potted_plant","evergreen_tree","deciduous_tree","palm_tree","cactus","ear_of_rice","herb","shamrock","four_leaf_clover","maple_leaf","fallen_leaf","leaves","empty_nest","nest_with_eggs","mushroom"]},{"id":"foods","name":"Food & Drink","emojis":["grapes","melon","watermelon","tangerine","lemon","lime","banana","pineapple","mango","apple","green_apple","pear","peach","cherries","strawberry","blueberries","kiwifruit","tomato","olive","coconut","avocado","eggplant","potato","carrot","corn","hot_pepper","bell_pepper","cucumber","leafy_green","broccoli","garlic","onion","peanuts","beans","chestnut","ginger_root","pea_pod","brown_mushroom","bread","croissant","baguette_bread","flatbread","pretzel","bagel","pancakes","waffle","cheese_wedge","meat_on_bone","poultry_leg","cut_of_meat","bacon","hamburger","fries","pizza","hotdog","sandwich","taco","burrito","tamale","stuffed_flatbread","falafel","egg","fried_egg","shallow_pan_of_food","stew","fondue","bowl_with_spoon","green_salad","popcorn","butter","salt","canned_food","bento","rice_cracker","rice_ball","rice","curry","ramen","spaghetti","sweet_potato","oden","sushi","fried_shrimp","fish_cake","moon_cake","dango","dumpling","fortune_cookie","takeout_box","crab","lobster","shrimp","squid","oyster","icecream","shaved_ice","ice_cream","doughnut","cookie","birthday","cake","cupcake","pie","chocolate_bar","candy","lollipop","custard","honey_pot","baby_bottle","glass_of_milk","coffee","teapot","tea","sake","champagne","wine_glass","cocktail","tropical_drink","beer","beers","clinking_glasses","tumbler_glass","pouring_liquid","cup_with_straw","bubble_tea","beverage_box","mate_drink","ice_cube","chopsticks","knife_fork_plate","fork_and_knife","spoon","hocho","jar","amphora"]},{"id":"activity","name":"Activities","emojis":["jack_o_lantern","christmas_tree","fireworks","sparkler","firecracker","sparkles","balloon","tada","confetti_ball","tanabata_tree","bamboo","dolls","flags","wind_chime","rice_scene","red_envelope","ribbon","gift","reminder_ribbon","admission_tickets","ticket","medal","trophy","sports_medal","first_place_medal","second_place_medal","third_place_medal","soccer","baseball","softball","basketball","volleyball","football","rugby_football","tennis","flying_disc","bowling","cricket_bat_and_ball","field_hockey_stick_and_ball","ice_hockey_stick_and_puck","lacrosse","table_tennis_paddle_and_ball","badminton_racquet_and_shuttlecock","boxing_glove","martial_arts_uniform","goal_net","golf","ice_skate","fishing_pole_and_fish","diving_mask","running_shirt_with_sash","ski","sled","curling_stone","dart","yo-yo","kite","gun","8ball","crystal_ball","magic_wand","video_game","joystick","slot_machine","game_die","jigsaw","teddy_bear","pinata","mirror_ball","nesting_dolls","spades","hearts","diamonds","clubs","chess_pawn","black_joker","mahjong","flower_playing_cards","performing_arts","frame_with_picture","art","thread","sewing_needle","yarn","knot"]},{"id":"places","name":"Travel & Places","emojis":["earth_africa","earth_americas","earth_asia","globe_with_meridians","world_map","japan","compass","snow_capped_mountain","mountain","volcano","mount_fuji","camping","beach_with_umbrella","desert","desert_island","national_park","stadium","classical_building","building_construction","bricks","rock","wood","hut","house_buildings","derelict_house_building","house","house_with_garden","office","post_office","european_post_office","hospital","bank","hotel","love_hotel","convenience_store","school","department_store","factory","japanese_castle","european_castle","wedding","tokyo_tower","statue_of_liberty","church","mosque","hindu_temple","synagogue","shinto_shrine","kaaba","fountain","tent","foggy","night_with_stars","cityscape","sunrise_over_mountains","sunrise","city_sunset","city_sunrise","bridge_at_night","hotsprings","carousel_horse","playground_slide","ferris_wheel","roller_coaster","barber","circus_tent","steam_locomotive","railway_car","bullettrain_side","bullettrain_front","train2","metro","light_rail","station","tram","monorail","mountain_railway","train","bus","oncoming_bus","trolleybus","minibus","ambulance","fire_engine","police_car","oncoming_police_car","taxi","oncoming_taxi","car","oncoming_automobile","blue_car","pickup_truck","truck","articulated_lorry","tractor","racing_car","racing_motorcycle","motor_scooter","manual_wheelchair","motorized_wheelchair","auto_rickshaw","bike","scooter","skateboard","roller_skate","busstop","motorway","railway_track","oil_drum","fuelpump","wheel","rotating_light","traffic_light","vertical_traffic_light","octagonal_sign","construction","anchor","ring_buoy","boat","canoe","speedboat","passenger_ship","ferry","motor_boat","ship","airplane","small_airplane","airplane_departure","airplane_arriving","parachute","seat","helicopter","suspension_railway","mountain_cableway","aerial_tramway","satellite","rocket","flying_saucer","bellhop_bell","luggage","hourglass","hourglass_flowing_sand","watch","alarm_clock","stopwatch","timer_clock","mantelpiece_clock","clock12","clock1230","clock1","clock130","clock2","clock230","clock3","clock330","clock4","clock430","clock5","clock530","clock6","clock630","clock7","clock730","clock8","clock830","clock9","clock930","clock10","clock1030","clock11","clock1130","new_moon","waxing_crescent_moon","first_quarter_moon","moon","full_moon","waning_gibbous_moon","last_quarter_moon","waning_crescent_moon","crescent_moon","new_moon_with_face","first_quarter_moon_with_face","last_quarter_moon_with_face","thermometer","sunny","full_moon_with_face","sun_with_face","ringed_planet","star","star2","stars","milky_way","cloud","partly_sunny","thunder_cloud_and_rain","mostly_sunny","barely_sunny","partly_sunny_rain","rain_cloud","snow_cloud","lightning","tornado","fog","wind_blowing_face","cyclone","rainbow","closed_umbrella","umbrella","umbrella_with_rain_drops","umbrella_on_ground","zap","snowflake","snowman","snowman_without_snow","comet","fire","droplet","ocean"]},{"id":"objects","name":"Objects","emojis":["eyeglasses","dark_sunglasses","goggles","lab_coat","safety_vest","necktie","shirt","jeans","scarf","gloves","coat","socks","dress","kimono","sari","one-piece_swimsuit","briefs","shorts","bikini","womans_clothes","folding_hand_fan","purse","handbag","pouch","shopping_bags","school_satchel","thong_sandal","mans_shoe","athletic_shoe","hiking_boot","womans_flat_shoe","high_heel","sandal","ballet_shoes","boot","hair_pick","crown","womans_hat","tophat","mortar_board","billed_cap","military_helmet","helmet_with_white_cross","prayer_beads","lipstick","ring","gem","mute","speaker","sound","loud_sound","loudspeaker","mega","postal_horn","bell","no_bell","musical_score","musical_note","notes","studio_microphone","level_slider","control_knobs","microphone","headphones","radio","saxophone","accordion","guitar","musical_keyboard","trumpet","violin","banjo","drum_with_drumsticks","long_drum","maracas","flute","iphone","calling","phone","telephone_receiver","pager","fax","battery","low_battery","electric_plug","computer","desktop_computer","printer","keyboard","three_button_mouse","trackball","minidisc","floppy_disk","cd","dvd","abacus","movie_camera","film_frames","film_projector","clapper","tv","camera","camera_with_flash","video_camera","vhs","mag","mag_right","candle","bulb","flashlight","izakaya_lantern","diya_lamp","notebook_with_decorative_cover","closed_book","book","green_book","blue_book","orange_book","books","notebook","ledger","page_with_curl","scroll","page_facing_up","newspaper","rolled_up_newspaper","bookmark_tabs","bookmark","label","moneybag","coin","yen","dollar","euro","pound","money_with_wings","credit_card","receipt","chart","email","e-mail","incoming_envelope","envelope_with_arrow","outbox_tray","inbox_tray","package","mailbox","mailbox_closed","mailbox_with_mail","mailbox_with_no_mail","postbox","ballot_box_with_ballot","pencil2","black_nib","lower_left_fountain_pen","lower_left_ballpoint_pen","lower_left_paintbrush","lower_left_crayon","memo","briefcase","file_folder","open_file_folder","card_index_dividers","date","calendar","spiral_note_pad","spiral_calendar_pad","card_index","chart_with_upwards_trend","chart_with_downwards_trend","bar_chart","clipboard","pushpin","round_pushpin","paperclip","linked_paperclips","straight_ruler","triangular_ruler","scissors","card_file_box","file_cabinet","wastebasket","lock","unlock","lock_with_ink_pen","closed_lock_with_key","key","old_key","hammer","axe","pick","hammer_and_pick","hammer_and_wrench","dagger_knife","crossed_swords","bomb","boomerang","bow_and_arrow","shield","carpentry_saw","wrench","screwdriver","nut_and_bolt","gear","compression","scales","probing_cane","link","broken_chain","chains","hook","toolbox","magnet","ladder","alembic","test_tube","petri_dish","dna","microscope","telescope","satellite_antenna","syringe","drop_of_blood","pill","adhesive_bandage","crutch","stethoscope","x-ray","door","elevator","mirror","window","bed","couch_and_lamp","chair","toilet","plunger","shower","bathtub","mouse_trap","razor","lotion_bottle","safety_pin","broom","basket","roll_of_paper","bucket","soap","bubbles","toothbrush","sponge","fire_extinguisher","shopping_trolley","smoking","coffin","headstone","funeral_urn","nazar_amulet","hamsa","moyai","placard","identification_card"]},{"id":"symbols","name":"Symbols","emojis":["atm","put_litter_in_its_place","potable_water","wheelchair","mens","womens","restroom","baby_symbol","wc","passport_control","customs","baggage_claim","left_luggage","warning","children_crossing","no_entry","no_entry_sign","no_bicycles","no_smoking","do_not_litter","non-potable_water","no_pedestrians","no_mobile_phones","underage","radioactive_sign","biohazard_sign","arrow_up","arrow_upper_right","arrow_right","arrow_lower_right","arrow_down","arrow_lower_left","arrow_left","arrow_upper_left","arrow_up_down","left_right_arrow","leftwards_arrow_with_hook","arrow_right_hook","arrow_heading_up","arrow_heading_down","arrows_clockwise","arrows_counterclockwise","back","end","on","soon","top","place_of_worship","atom_symbol","om_symbol","star_of_david","wheel_of_dharma","yin_yang","latin_cross","orthodox_cross","star_and_crescent","peace_symbol","menorah_with_nine_branches","six_pointed_star","khanda","aries","taurus","gemini","cancer","leo","virgo","libra","scorpius","sagittarius","capricorn","aquarius","pisces","ophiuchus","twisted_rightwards_arrows","repeat","repeat_one","arrow_forward","fast_forward","black_right_pointing_double_triangle_with_vertical_bar","black_right_pointing_triangle_with_double_vertical_bar","arrow_backward","rewind","black_left_pointing_double_triangle_with_vertical_bar","arrow_up_small","arrow_double_up","arrow_down_small","arrow_double_down","double_vertical_bar","black_square_for_stop","black_circle_for_record","eject","cinema","low_brightness","high_brightness","signal_strength","wireless","vibration_mode","mobile_phone_off","female_sign","male_sign","transgender_symbol","heavy_multiplication_x","heavy_plus_sign","heavy_minus_sign","heavy_division_sign","heavy_equals_sign","infinity","bangbang","interrobang","question","grey_question","grey_exclamation","exclamation","wavy_dash","currency_exchange","heavy_dollar_sign","medical_symbol","recycle","fleur_de_lis","trident","name_badge","beginner","o","white_check_mark","ballot_box_with_check","heavy_check_mark","x","negative_squared_cross_mark","curly_loop","loop","part_alternation_mark","eight_spoked_asterisk","eight_pointed_black_star","sparkle","copyright","registered","tm","hash","keycap_star","zero","one","two","three","four","five","six","seven","eight","nine","keycap_ten","capital_abcd","abcd","1234","symbols","abc","a","ab","b","cl","cool","free","information_source","id","m","new","ng","o2","ok","parking","sos","up","vs","koko","sa","u6708","u6709","u6307","ideograph_advantage","u5272","u7121","u7981","accept","u7533","u5408","u7a7a","congratulations","secret","u55b6","u6e80","red_circle","large_orange_circle","large_yellow_circle","large_green_circle","large_blue_circle","large_purple_circle","large_brown_circle","black_circle","white_circle","large_red_square","large_orange_square","large_yellow_square","large_green_square","large_blue_square","large_purple_square","large_brown_square","black_large_square","white_large_square","black_medium_square","white_medium_square","black_medium_small_square","white_medium_small_square","black_small_square","white_small_square","large_orange_diamond","large_blue_diamond","small_orange_diamond","small_blue_diamond","small_red_triangle","small_red_triangle_down","diamond_shape_with_a_dot_inside","radio_button","white_square_button","black_square_button"]},{"id":"flags","name":"Flags","emojis":["checkered_flag","triangular_flag_on_post","crossed_flags","waving_black_flag","waving_white_flag","rainbow-flag","transgender_flag","pirate_flag","flag-ac","flag-ad","flag-ae","flag-af","flag-ag","flag-ai","flag-al","flag-am","flag-ao","flag-aq","flag-ar","flag-as","flag-at","flag-au","flag-aw","flag-ax","flag-az","flag-ba","flag-bb","flag-bd","flag-be","flag-bf","flag-bg","flag-bh","flag-bi","flag-bj","flag-bl","flag-bm","flag-bn","flag-bo","flag-bq","flag-br","flag-bs","flag-bt","flag-bv","flag-bw","flag-by","flag-bz","flag-ca","flag-cc","flag-cd","flag-cf","flag-cg","flag-ch","flag-ci","flag-ck","flag-cl","flag-cm","cn","flag-co","flag-cp","flag-cr","flag-cu","flag-cv","flag-cw","flag-cx","flag-cy","flag-cz","de","flag-dg","flag-dj","flag-dk","flag-dm","flag-do","flag-dz","flag-ea","flag-ec","flag-ee","flag-eg","flag-eh","flag-er","es","flag-et","flag-eu","flag-fi","flag-fj","flag-fk","flag-fm","flag-fo","fr","flag-ga","gb","flag-gd","flag-ge","flag-gf","flag-gg","flag-gh","flag-gi","flag-gl","flag-gm","flag-gn","flag-gp","flag-gq","flag-gr","flag-gs","flag-gt","flag-gu","flag-gw","flag-gy","flag-hk","flag-hm","flag-hn","flag-hr","flag-ht","flag-hu","flag-ic","flag-id","flag-ie","flag-il","flag-im","flag-in","flag-io","flag-iq","flag-ir","flag-is","it","flag-je","flag-jm","flag-jo","jp","flag-ke","flag-kg","flag-kh","flag-ki","flag-km","flag-kn","flag-kp","kr","flag-kw","flag-ky","flag-kz","flag-la","flag-lb","flag-lc","flag-li","flag-lk","flag-lr","flag-ls","flag-lt","flag-lu","flag-lv","flag-ly","flag-ma","flag-mc","flag-md","flag-me","flag-mf","flag-mg","flag-mh","flag-mk","flag-ml","flag-mm","flag-mn","flag-mo","flag-mp","flag-mq","flag-mr","flag-ms","flag-mt","flag-mu","flag-mv","flag-mw","flag-mx","flag-my","flag-mz","flag-na","flag-nc","flag-ne","flag-nf","flag-ng","flag-ni","flag-nl","flag-no","flag-np","flag-nr","flag-nu","flag-nz","flag-om","flag-pa","flag-pe","flag-pf","flag-pg","flag-ph","flag-pk","flag-pl","flag-pm","flag-pn","flag-pr","flag-ps","flag-pt","flag-pw","flag-py","flag-qa","flag-re","flag-ro","flag-rs","ru","flag-rw","flag-sa","flag-sb","flag-sc","flag-sd","flag-se","flag-sg","flag-sh","flag-si","flag-sj","flag-sk","flag-sl","flag-sm","flag-sn","flag-so","flag-sr","flag-ss","flag-st","flag-sv","flag-sx","flag-sy","flag-sz","flag-ta","flag-tc","flag-td","flag-tf","flag-tg","flag-th","flag-tj","flag-tk","flag-tl","flag-tm","flag-tn","flag-to","flag-tr","flag-tt","flag-tv","flag-tw","flag-tz","flag-ua","flag-ug","flag-um","flag-un","us","flag-uy","flag-uz","flag-va","flag-vc","flag-ve","flag-vg","flag-vi","flag-vn","flag-vu","flag-wf","flag-ws","flag-xk","flag-ye","flag-yt","flag-za","flag-zm","flag-zw","flag-england","flag-scotland","flag-wales"]}],"emojis":{"grinning":{"a":"Grinning Face","b":"1F600","f":true,"k":[32,46],"j":["grinning_face","face","smile","happy","joy",":D","grin"],"m":":D"},"smiley":{"a":"Smiling Face with Open Mouth","b":"1F603","f":true,"k":[32,49],"j":["grinning_face_with_big_eyes","face","happy","joy","haha",":D",":)","smile","funny"],"l":["=)","=-)"],"m":":)"},"smile":{"a":"Smiling Face with Open Mouth and Smiling Eyes","b":"1F604","f":true,"k":[32,50],"j":["grinning_face_with_smiling_eyes","face","happy","joy","funny","haha","laugh","like",":D",":)"],"l":["C:","c:",":D",":-D"],"m":":)"},"grin":{"a":"Grinning Face with Smiling Eyes","b":"1F601","f":true,"k":[32,47],"j":["beaming_face_with_smiling_eyes","face","happy","smile","joy","kawaii"]},"laughing":{"a":"Smiling Face with Open Mouth and Tightly-Closed Eyes","b":"1F606","f":true,"k":[32,52],"j":["grinning_squinting_face","happy","joy","lol","satisfied","haha","face","glad","XD","laugh"],"l":[":>",":->"]},"sweat_smile":{"a":"Smiling Face with Open Mouth and Cold Sweat","b":"1F605","f":true,"k":[32,51],"j":["grinning_face_with_sweat","face","hot","happy","laugh","sweat","smile","relief"]},"rolling_on_the_floor_laughing":{"a":"Rolling On the Floor Laughing","b":"1F923","f":true,"k":[40,54],"j":["face","rolling","floor","laughing","lol","haha","rofl"]},"joy":{"a":"Face with Tears Of Joy","b":"1F602","f":true,"k":[32,48],"j":["face_with_tears_of_joy","face","cry","tears","weep","happy","happytears","haha"]},"slightly_smiling_face":{"a":"Slightly Smiling Face","b":"1F642","f":true,"k":[33,55],"j":["face","smile"],"l":[":)","(:",":-)"]},"upside_down_face":{"a":"Upside-Down Face","b":"1F643","f":true,"k":[33,56],"j":["face","flipped","silly","smile"]},"melting_face":{"a":"Melting Face","b":"1FAE0","f":true,"k":[56,30],"j":["melting face","hot","heat"]},"wink":{"a":"Winking Face","b":"1F609","f":true,"k":[32,55],"j":["winking_face","face","happy","mischievous","secret",";)","smile","eye"],"l":[";)",";-)"],"m":";)"},"blush":{"a":"Smiling Face with Smiling Eyes","b":"1F60A","f":true,"k":[32,56],"j":["smiling_face_with_smiling_eyes","face","smile","happy","flushed","crush","embarrassed","shy","joy"],"m":":)"},"innocent":{"a":"Smiling Face with Halo","b":"1F607","f":true,"k":[32,53],"j":["smiling_face_with_halo","face","angel","heaven","halo"]},"smiling_face_with_3_hearts":{"a":"Smiling Face with Smiling Eyes and Three Hearts","b":"1F970","f":true,"k":[44,32],"j":["smiling_face_with_hearts","face","love","like","affection","valentines","infatuation","crush","hearts","adore"]},"heart_eyes":{"a":"Smiling Face with Heart-Shaped Eyes","b":"1F60D","f":true,"k":[32,59],"j":["smiling_face_with_heart_eyes","face","love","like","affection","valentines","infatuation","crush","heart"]},"star-struck":{"a":"Grinning Face with Star Eyes","b":"1F929","f":true,"k":[41,15],"j":["star_struck","face","smile","starry","eyes","grinning"]},"kissing_heart":{"a":"Face Throwing a Kiss","b":"1F618","f":true,"k":[33,8],"j":["face_blowing_a_kiss","face","love","like","affection","valentines","infatuation","kiss"],"l":[":*",":-*"]},"kissing":{"a":"Kissing Face","b":"1F617","f":true,"k":[33,7],"j":["kissing_face","love","like","face","3","valentines","infatuation","kiss"]},"relaxed":{"a":"White Smiling Face","b":"263A-FE0F","f":true,"k":[58,33],"c":"263A"},"kissing_closed_eyes":{"a":"Kissing Face with Closed Eyes","b":"1F61A","f":true,"k":[33,10],"j":["kissing_face_with_closed_eyes","face","love","like","affection","valentines","infatuation","kiss"]},"kissing_smiling_eyes":{"a":"Kissing Face with Smiling Eyes","b":"1F619","f":true,"k":[33,9],"j":["kissing_face_with_smiling_eyes","face","affection","valentines","infatuation","kiss"]},"smiling_face_with_tear":{"a":"Smiling Face with Tear","b":"1F972","f":true,"k":[44,34],"j":["smiling face with tear","sad","cry","pretend"]},"yum":{"a":"Face Savouring Delicious Food","b":"1F60B","f":true,"k":[32,57],"j":["face_savoring_food","happy","joy","tongue","smile","face","silly","yummy","nom","delicious","savouring"]},"stuck_out_tongue":{"a":"Face with Stuck-Out Tongue","b":"1F61B","f":true,"k":[33,11],"j":["face_with_tongue","face","prank","childish","playful","mischievous","smile","tongue"],"l":[":p",":-p",":P",":-P",":b",":-b"],"m":":p"},"stuck_out_tongue_winking_eye":{"a":"Face with Stuck-Out Tongue and Winking Eye","b":"1F61C","f":true,"k":[33,12],"j":["winking_face_with_tongue","face","prank","childish","playful","mischievous","smile","wink","tongue"],"l":[";p",";-p",";b",";-b",";P",";-P"],"m":";p"},"zany_face":{"a":"Grinning Face with One Large and One Small Eye","b":"1F92A","f":true,"k":[41,16],"j":["face","goofy","crazy"]},"stuck_out_tongue_closed_eyes":{"a":"Face with Stuck-Out Tongue and Tightly-Closed Eyes","b":"1F61D","f":true,"k":[33,13],"j":["squinting_face_with_tongue","face","prank","playful","mischievous","smile","tongue"]},"money_mouth_face":{"a":"Money-Mouth Face","b":"1F911","f":true,"k":[39,38],"j":["face","rich","dollar","money"]},"hugging_face":{"a":"Hugging Face","b":"1F917","f":true,"k":[39,44],"j":["face","smile","hug"]},"face_with_hand_over_mouth":{"a":"Smiling Face with Smiling Eyes and Hand Covering Mouth","b":"1F92D","f":true,"k":[41,19],"j":["face","whoops","shock","surprise"]},"face_with_open_eyes_and_hand_over_mouth":{"a":"Face with Open Eyes and Hand Over Mouth","b":"1FAE2","f":true,"k":[56,32],"j":["face with open eyes and hand over mouth","silence","secret","shock","surprise"]},"face_with_peeking_eye":{"a":"Face with Peeking Eye","b":"1FAE3","f":true,"k":[56,33],"j":["face with peeking eye","scared","frightening","embarrassing","shy"]},"shushing_face":{"a":"Face with Finger Covering Closed Lips","b":"1F92B","f":true,"k":[41,17],"j":["face","quiet","shhh"]},"thinking_face":{"a":"Thinking Face","b":"1F914","f":true,"k":[39,41],"j":["face","hmmm","think","consider"]},"saluting_face":{"a":"Saluting Face","b":"1FAE1","f":true,"k":[56,31],"j":["saluting face","respect","salute"]},"zipper_mouth_face":{"a":"Zipper-Mouth Face","b":"1F910","f":true,"k":[39,37],"j":["face","sealed","zipper","secret"]},"face_with_raised_eyebrow":{"a":"Face with One Eyebrow Raised","b":"1F928","f":true,"k":[41,14],"j":["face","distrust","scepticism","disapproval","disbelief","surprise","suspicious"]},"neutral_face":{"a":"Neutral Face","b":"1F610","f":true,"k":[33,0],"j":["indifference","meh",":|","neutral"],"l":[":|",":-|"]},"expressionless":{"a":"Expressionless Face","b":"1F611","f":true,"k":[33,1],"j":["expressionless_face","face","indifferent","-_-","meh","deadpan"]},"no_mouth":{"a":"Face Without Mouth","b":"1F636","f":true,"k":[33,41],"j":["face_without_mouth","face"]},"dotted_line_face":{"a":"Dotted Line Face","b":"1FAE5","f":true,"k":[56,35],"j":["dotted line face","invisible","lonely","isolation","depression"]},"face_in_clouds":{"a":"Face In Clouds","b":"1F636-200D-1F32B-FE0F","f":true,"k":[33,40],"c":"1F636-200D-1F32B","j":["face_without_mouth","face"]},"smirk":{"a":"Smirking Face","b":"1F60F","f":true,"k":[32,61],"j":["smirking_face","face","smile","mean","prank","smug","sarcasm"]},"unamused":{"a":"Unamused Face","b":"1F612","f":true,"k":[33,2],"j":["unamused_face","indifference","bored","straight face","serious","sarcasm","unimpressed","skeptical","dubious","ugh","side_eye"],"m":":("},"face_with_rolling_eyes":{"a":"Face with Rolling Eyes","b":"1F644","f":true,"k":[33,57],"j":["face","eyeroll","frustrated"]},"grimacing":{"a":"Grimacing Face","b":"1F62C","f":true,"k":[33,28],"j":["grimacing_face","face","grimace","teeth"]},"face_exhaling":{"a":"Face Exhaling","b":"1F62E-200D-1F4A8","f":true,"k":[33,30],"j":["face_with_open_mouth","face","surprise","impressed","wow","whoa",":O"]},"lying_face":{"a":"Lying Face","b":"1F925","f":true,"k":[40,56],"j":["face","lie","pinocchio"]},"shaking_face":{"a":"Shaking Face","b":"1FAE8","f":true,"k":[56,38],"j":["shaking face","dizzy","shock","blurry","earthquake"]},"head_shaking_horizontally":{"a":"Head Shaking Horizontally","b":"1F642-200D-2194-FE0F","f":true,"k":[33,53],"c":"1F642-200D-2194","j":["slightly_smiling_face","face","smile"]},"head_shaking_vertically":{"a":"Head Shaking Vertically","b":"1F642-200D-2195-FE0F","f":true,"k":[33,54],"c":"1F642-200D-2195","j":["slightly_smiling_face","face","smile"]},"relieved":{"a":"Relieved Face","b":"1F60C","f":true,"k":[32,58],"j":["relieved_face","face","relaxed","phew","massage","happiness"]},"pensive":{"a":"Pensive Face","b":"1F614","f":true,"k":[33,4],"j":["pensive_face","face","sad","depressed","upset"]},"sleepy":{"a":"Sleepy Face","b":"1F62A","f":true,"k":[33,26],"j":["sleepy_face","face","tired","rest","nap"]},"drooling_face":{"a":"Drooling Face","b":"1F924","f":true,"k":[40,55],"j":["face"]},"sleeping":{"a":"Sleeping Face","b":"1F634","f":true,"k":[33,37],"j":["sleeping_face","face","tired","sleepy","night","zzz"]},"mask":{"a":"Face with Medical Mask","b":"1F637","f":true,"k":[33,42],"j":["face_with_medical_mask","face","sick","ill","disease","covid"]},"face_with_thermometer":{"a":"Face with Thermometer","b":"1F912","f":true,"k":[39,39],"j":["sick","temperature","thermometer","cold","fever","covid"]},"face_with_head_bandage":{"a":"Face with Head-Bandage","b":"1F915","f":true,"k":[39,42],"j":["injured","clumsy","bandage","hurt"]},"nauseated_face":{"a":"Nauseated Face","b":"1F922","f":true,"k":[40,53],"j":["face","vomit","gross","green","sick","throw up","ill"]},"face_vomiting":{"a":"Face with Open Mouth Vomiting","b":"1F92E","f":true,"k":[41,20],"j":["face","sick"]},"sneezing_face":{"a":"Sneezing Face","b":"1F927","f":true,"k":[41,13],"j":["face","gesundheit","sneeze","sick","allergy"]},"hot_face":{"a":"Overheated Face","b":"1F975","f":true,"k":[44,37],"j":["face","feverish","heat","red","sweating"]},"cold_face":{"a":"Freezing Face","b":"1F976","f":true,"k":[44,38],"j":["face","blue","freezing","frozen","frostbite","icicles"]},"woozy_face":{"a":"Face with Uneven Eyes and Wavy Mouth","b":"1F974","f":true,"k":[44,36],"j":["face","dizzy","intoxicated","tipsy","wavy"]},"dizzy_face":{"a":"Dizzy Face","b":"1F635","f":true,"k":[33,39],"j":["spent","unconscious","xox","dizzy"]},"face_with_spiral_eyes":{"a":"Face with Spiral Eyes","b":"1F635-200D-1F4AB","f":true,"k":[33,38],"j":["dizzy_face","spent","unconscious","xox","dizzy"]},"exploding_head":{"a":"Shocked Face with Exploding Head","b":"1F92F","f":true,"k":[41,21],"j":["face","shocked","mind","blown"]},"face_with_cowboy_hat":{"a":"Face with Cowboy Hat","b":"1F920","f":true,"k":[40,51],"j":["cowboy_hat_face","face","cowgirl","hat"]},"partying_face":{"a":"Face with Party Horn and Party Hat","b":"1F973","f":true,"k":[44,35],"j":["face","celebration","woohoo"]},"disguised_face":{"a":"Disguised Face","b":"1F978","f":true,"k":[44,45],"j":["disguised face","pretent","brows","glasses","moustache"]},"sunglasses":{"a":"Smiling Face with Sunglasses","b":"1F60E","f":true,"k":[32,60],"j":["smiling_face_with_sunglasses","face","cool","smile","summer","beach","sunglass"],"l":["8)"]},"nerd_face":{"a":"Nerd Face","b":"1F913","f":true,"k":[39,40],"j":["face","nerdy","geek","dork"]},"face_with_monocle":{"a":"Face with Monocle","b":"1F9D0","f":true,"k":[47,61],"j":["face","stuffy","wealthy"]},"confused":{"a":"Confused Face","b":"1F615","f":true,"k":[33,5],"j":["confused_face","face","indifference","huh","weird","hmmm",":/"],"l":[":\\",":-\\",":/",":-/"]},"face_with_diagonal_mouth":{"a":"Face with Diagonal Mouth","b":"1FAE4","f":true,"k":[56,34],"j":["face with diagonal mouth","skeptic","confuse","frustrated","indifferent"]},"worried":{"a":"Worried Face","b":"1F61F","f":true,"k":[33,15],"j":["worried_face","face","concern","nervous",":("]},"slightly_frowning_face":{"a":"Slightly Frowning Face","b":"1F641","f":true,"k":[33,52],"j":["face","frowning","disappointed","sad","upset"]},"white_frowning_face":{"a":"Frowning Face","b":"2639-FE0F","f":true,"k":[58,32],"c":"2639"},"open_mouth":{"a":"Face with Open Mouth","b":"1F62E","f":true,"k":[33,31],"j":["face_with_open_mouth","face","surprise","impressed","wow","whoa",":O"],"l":[":o",":-o",":O",":-O"]},"hushed":{"a":"Hushed Face","b":"1F62F","f":true,"k":[33,32],"j":["hushed_face","face","woo","shh"]},"astonished":{"a":"Astonished Face","b":"1F632","f":true,"k":[33,35],"j":["astonished_face","face","xox","surprised","poisoned"]},"flushed":{"a":"Flushed Face","b":"1F633","f":true,"k":[33,36],"j":["flushed_face","face","blush","shy","flattered"]},"pleading_face":{"a":"Face with Pleading Eyes","b":"1F97A","f":true,"k":[44,47],"j":["face","begging","mercy","cry","tears","sad","grievance"]},"face_holding_back_tears":{"a":"Face Holding Back Tears","b":"1F979","f":true,"k":[44,46],"j":["face holding back tears","touched","gratitude","cry"]},"frowning":{"a":"Frowning Face with Open Mouth","b":"1F626","f":true,"k":[33,22],"j":["frowning_face_with_open_mouth","face","aw","what"]},"anguished":{"a":"Anguished Face","b":"1F627","f":true,"k":[33,23],"j":["anguished_face","face","stunned","nervous"],"l":["D:"]},"fearful":{"a":"Fearful Face","b":"1F628","f":true,"k":[33,24],"j":["fearful_face","face","scared","terrified","nervous"]},"cold_sweat":{"a":"Face with Open Mouth and Cold Sweat","b":"1F630","f":true,"k":[33,33],"j":["anxious_face_with_sweat","face","nervous","sweat"]},"disappointed_relieved":{"a":"Disappointed But Relieved Face","b":"1F625","f":true,"k":[33,21],"j":["sad_but_relieved_face","face","phew","sweat","nervous"]},"cry":{"a":"Crying Face","b":"1F622","f":true,"k":[33,18],"j":["crying_face","face","tears","sad","depressed","upset",":'("],"l":[":'("],"m":":'("},"sob":{"a":"Loudly Crying Face","b":"1F62D","f":true,"k":[33,29],"j":["loudly_crying_face","sobbing","face","cry","tears","sad","upset","depressed"],"m":":'("},"scream":{"a":"Face Screaming In Fear","b":"1F631","f":true,"k":[33,34],"j":["face_screaming_in_fear","face","munch","scared","omg"]},"confounded":{"a":"Confounded Face","b":"1F616","f":true,"k":[33,6],"j":["confounded_face","face","confused","sick","unwell","oops",":S"]},"persevere":{"a":"Persevering Face","b":"1F623","f":true,"k":[33,19],"j":["persevering_face","face","sick","no","upset","oops"]},"disappointed":{"a":"Disappointed Face","b":"1F61E","f":true,"k":[33,14],"j":["disappointed_face","face","sad","upset","depressed",":("],"l":["):",":(",":-("],"m":":("},"sweat":{"a":"Face with Cold Sweat","b":"1F613","f":true,"k":[33,3],"j":["downcast_face_with_sweat","face","hot","sad","tired","exercise"]},"weary":{"a":"Weary Face","b":"1F629","f":true,"k":[33,25],"j":["weary_face","face","tired","sleepy","sad","frustrated","upset"]},"tired_face":{"a":"Tired Face","b":"1F62B","f":true,"k":[33,27],"j":["sick","whine","upset","frustrated"]},"yawning_face":{"a":"Yawning Face","b":"1F971","f":true,"k":[44,33],"j":["tired","sleepy"]},"triumph":{"a":"Face with Look Of Triumph","b":"1F624","f":true,"k":[33,20],"j":["face_with_steam_from_nose","face","gas","phew","proud","pride"]},"rage":{"a":"Pouting Face","b":"1F621","f":true,"k":[33,17],"j":["pouting_face","angry","mad","hate","despise"]},"angry":{"a":"Angry Face","b":"1F620","f":true,"k":[33,16],"j":["angry_face","mad","face","annoyed","frustrated"],"l":[">:(",">:-("]},"face_with_symbols_on_mouth":{"a":"Serious Face with Symbols Covering Mouth","b":"1F92C","f":true,"k":[41,18],"j":["face","swearing","cursing","cussing","profanity","expletive"]},"smiling_imp":{"a":"Smiling Face with Horns","b":"1F608","f":true,"k":[32,54],"j":["smiling_face_with_horns","devil","horns"]},"imp":{"a":"Imp","b":"1F47F","f":true,"k":[25,41],"j":["angry_face_with_horns","devil","angry","horns"]},"skull":{"a":"Skull","b":"1F480","f":true,"k":[25,42],"j":["dead","skeleton","creepy","death","dead"]},"skull_and_crossbones":{"a":"Skull and Crossbones","b":"2620-FE0F","f":true,"k":[58,24],"c":"2620"},"hankey":{"a":"Pile Of Poo","b":"1F4A9","f":true,"k":[28,25],"j":["pile_of_poo","shitface","fail","turd","shit"]},"clown_face":{"a":"Clown Face","b":"1F921","f":true,"k":[40,52],"j":["face"]},"japanese_ogre":{"a":"Japanese Ogre","b":"1F479","f":true,"k":[25,30],"j":["ogre","monster","red","mask","halloween","scary","creepy","devil","demon"]},"japanese_goblin":{"a":"Japanese Goblin","b":"1F47A","f":true,"k":[25,31],"j":["goblin","red","evil","mask","monster","scary","creepy"]},"ghost":{"a":"Ghost","b":"1F47B","f":true,"k":[25,32],"j":["halloween","spooky","scary"]},"alien":{"a":"Extraterrestrial Alien","b":"1F47D","f":true,"k":[25,39],"j":["UFO","paul","weird","outer_space"]},"space_invader":{"a":"Alien Monster","b":"1F47E","f":true,"k":[25,40],"j":["alien_monster","game","arcade","play"]},"robot_face":{"a":"Robot Face","b":"1F916","f":true,"k":[39,43],"j":["robot","computer","machine","bot"]},"smiley_cat":{"a":"Smiling Cat Face with Open Mouth","b":"1F63A","f":true,"k":[33,45],"j":["grinning_cat","animal","cats","happy","smile"]},"smile_cat":{"a":"Grinning Cat Face with Smiling Eyes","b":"1F638","f":true,"k":[33,43],"j":["grinning_cat_with_smiling_eyes","animal","cats","smile"]},"joy_cat":{"a":"Cat Face with Tears Of Joy","b":"1F639","f":true,"k":[33,44],"j":["cat_with_tears_of_joy","animal","cats","haha","happy","tears"]},"heart_eyes_cat":{"a":"Smiling Cat Face with Heart-Shaped Eyes","b":"1F63B","f":true,"k":[33,46],"j":["smiling_cat_with_heart_eyes","animal","love","like","affection","cats","valentines","heart"]},"smirk_cat":{"a":"Cat Face with Wry Smile","b":"1F63C","f":true,"k":[33,47],"j":["cat_with_wry_smile","animal","cats","smirk"]},"kissing_cat":{"a":"Kissing Cat Face with Closed Eyes","b":"1F63D","f":true,"k":[33,48],"j":["animal","cats","kiss"]},"scream_cat":{"a":"Weary Cat Face","b":"1F640","f":true,"k":[33,51],"j":["weary_cat","animal","cats","munch","scared","scream"]},"crying_cat_face":{"a":"Crying Cat Face","b":"1F63F","f":true,"k":[33,50],"j":["crying_cat","animal","tears","weep","sad","cats","upset","cry"]},"pouting_cat":{"a":"Pouting Cat Face","b":"1F63E","f":true,"k":[33,49],"j":["animal","cats"]},"see_no_evil":{"a":"See-No-Evil Monkey","b":"1F648","f":true,"k":[34,50],"j":["see_no_evil_monkey","monkey","animal","nature","haha"]},"hear_no_evil":{"a":"Hear-No-Evil Monkey","b":"1F649","f":true,"k":[34,51],"j":["hear_no_evil_monkey","animal","monkey","nature"]},"speak_no_evil":{"a":"Speak-No-Evil Monkey","b":"1F64A","f":true,"k":[34,52],"j":["speak_no_evil_monkey","monkey","animal","nature","omg"]},"love_letter":{"a":"Love Letter","b":"1F48C","f":true,"k":[27,8],"j":["email","like","affection","envelope","valentines"]},"cupid":{"a":"Heart with Arrow","b":"1F498","f":true,"k":[28,8],"j":["heart_with_arrow","love","like","heart","affection","valentines"]},"gift_heart":{"a":"Heart with Ribbon","b":"1F49D","f":true,"k":[28,13],"j":["heart_with_ribbon","love","valentines"]},"sparkling_heart":{"a":"Sparkling Heart","b":"1F496","f":true,"k":[28,6],"j":["love","like","affection","valentines"]},"heartpulse":{"a":"Growing Heart","b":"1F497","f":true,"k":[28,7],"j":["growing_heart","like","love","affection","valentines","pink"]},"heartbeat":{"a":"Beating Heart","b":"1F493","f":true,"k":[28,3],"j":["beating_heart","love","like","affection","valentines","pink","heart"]},"revolving_hearts":{"a":"Revolving Hearts","b":"1F49E","f":true,"k":[28,14],"j":["love","like","affection","valentines"]},"two_hearts":{"a":"Two Hearts","b":"1F495","f":true,"k":[28,5],"j":["love","like","affection","valentines","heart"]},"heart_decoration":{"a":"Heart Decoration","b":"1F49F","f":true,"k":[28,15],"j":["purple-square","love","like"]},"heavy_heart_exclamation_mark_ornament":{"a":"Heart Exclamation","b":"2763-FE0F","f":true,"k":[60,35],"c":"2763"},"broken_heart":{"a":"Broken Heart","b":"1F494","f":true,"k":[28,4],"j":["sad","sorry","break","heart","heartbreak"],"l":["",":->"]},"sweat_smile":{"a":"Smiling Face with Open Mouth and Cold Sweat","b":"1F605","f":true,"k":[32,52],"j":["grinning_face_with_sweat","face","hot","happy","laugh","sweat","smile","relief"]},"rolling_on_the_floor_laughing":{"a":"Rolling On the Floor Laughing","b":"1F923","f":true,"k":[40,55],"j":["face","rolling","floor","laughing","lol","haha","rofl"]},"joy":{"a":"Face with Tears Of Joy","b":"1F602","f":true,"k":[32,49],"j":["face_with_tears_of_joy","face","cry","tears","weep","happy","happytears","haha"]},"slightly_smiling_face":{"a":"Slightly Smiling Face","b":"1F642","f":true,"k":[33,56],"j":["face","smile"],"l":[":)","(:",":-)"]},"upside_down_face":{"a":"Upside-Down Face","b":"1F643","f":true,"k":[33,57],"j":["face","flipped","silly","smile"]},"melting_face":{"a":"Melting Face","b":"1FAE0","f":true,"k":[56,37],"j":["melting face","hot","heat"]},"wink":{"a":"Winking Face","b":"1F609","f":true,"k":[32,56],"j":["winking_face","face","happy","mischievous","secret",";)","smile","eye"],"l":[";)",";-)"],"m":";)"},"blush":{"a":"Smiling Face with Smiling Eyes","b":"1F60A","f":true,"k":[32,57],"j":["smiling_face_with_smiling_eyes","face","smile","happy","flushed","crush","embarrassed","shy","joy"],"m":":)"},"innocent":{"a":"Smiling Face with Halo","b":"1F607","f":true,"k":[32,54],"j":["smiling_face_with_halo","face","angel","heaven","halo"]},"smiling_face_with_3_hearts":{"a":"Smiling Face with Smiling Eyes and Three Hearts","b":"1F970","f":true,"k":[44,33],"j":["smiling_face_with_hearts","face","love","like","affection","valentines","infatuation","crush","hearts","adore"]},"heart_eyes":{"a":"Smiling Face with Heart-Shaped Eyes","b":"1F60D","f":true,"k":[32,60],"j":["smiling_face_with_heart_eyes","face","love","like","affection","valentines","infatuation","crush","heart"]},"star-struck":{"a":"Grinning Face with Star Eyes","b":"1F929","f":true,"k":[41,16],"j":["star_struck","face","smile","starry","eyes","grinning"]},"kissing_heart":{"a":"Face Throwing a Kiss","b":"1F618","f":true,"k":[33,9],"j":["face_blowing_a_kiss","face","love","like","affection","valentines","infatuation","kiss"],"l":[":*",":-*"]},"kissing":{"a":"Kissing Face","b":"1F617","f":true,"k":[33,8],"j":["kissing_face","love","like","face","3","valentines","infatuation","kiss"]},"relaxed":{"a":"White Smiling Face","b":"263A-FE0F","f":true,"k":[58,41],"c":"263A"},"kissing_closed_eyes":{"a":"Kissing Face with Closed Eyes","b":"1F61A","f":true,"k":[33,11],"j":["kissing_face_with_closed_eyes","face","love","like","affection","valentines","infatuation","kiss"]},"kissing_smiling_eyes":{"a":"Kissing Face with Smiling Eyes","b":"1F619","f":true,"k":[33,10],"j":["kissing_face_with_smiling_eyes","face","affection","valentines","infatuation","kiss"]},"smiling_face_with_tear":{"a":"Smiling Face with Tear","b":"1F972","f":true,"k":[44,35],"j":["smiling face with tear","sad","cry","pretend"]},"yum":{"a":"Face Savouring Delicious Food","b":"1F60B","f":true,"k":[32,58],"j":["face_savoring_food","happy","joy","tongue","smile","face","silly","yummy","nom","delicious","savouring"]},"stuck_out_tongue":{"a":"Face with Stuck-Out Tongue","b":"1F61B","f":true,"k":[33,12],"j":["face_with_tongue","face","prank","childish","playful","mischievous","smile","tongue"],"l":[":p",":-p",":P",":-P",":b",":-b"],"m":":p"},"stuck_out_tongue_winking_eye":{"a":"Face with Stuck-Out Tongue and Winking Eye","b":"1F61C","f":true,"k":[33,13],"j":["winking_face_with_tongue","face","prank","childish","playful","mischievous","smile","wink","tongue"],"l":[";p",";-p",";b",";-b",";P",";-P"],"m":";p"},"zany_face":{"a":"Grinning Face with One Large and One Small Eye","b":"1F92A","f":true,"k":[41,17],"j":["face","goofy","crazy"]},"stuck_out_tongue_closed_eyes":{"a":"Face with Stuck-Out Tongue and Tightly-Closed Eyes","b":"1F61D","f":true,"k":[33,14],"j":["squinting_face_with_tongue","face","prank","playful","mischievous","smile","tongue"]},"money_mouth_face":{"a":"Money-Mouth Face","b":"1F911","f":true,"k":[39,39],"j":["face","rich","dollar","money"]},"hugging_face":{"a":"Hugging Face","b":"1F917","f":true,"k":[39,45],"j":["face","smile","hug"]},"face_with_hand_over_mouth":{"a":"Smiling Face with Smiling Eyes and Hand Covering Mouth","b":"1F92D","f":true,"k":[41,20],"j":["face","whoops","shock","surprise"]},"face_with_open_eyes_and_hand_over_mouth":{"a":"Face with Open Eyes and Hand Over Mouth","b":"1FAE2","f":true,"k":[56,39],"j":["face with open eyes and hand over mouth","silence","secret","shock","surprise"]},"face_with_peeking_eye":{"a":"Face with Peeking Eye","b":"1FAE3","f":true,"k":[56,40],"j":["face with peeking eye","scared","frightening","embarrassing","shy"]},"shushing_face":{"a":"Face with Finger Covering Closed Lips","b":"1F92B","f":true,"k":[41,18],"j":["face","quiet","shhh"]},"thinking_face":{"a":"Thinking Face","b":"1F914","f":true,"k":[39,42],"j":["face","hmmm","think","consider"]},"saluting_face":{"a":"Saluting Face","b":"1FAE1","f":true,"k":[56,38],"j":["saluting face","respect","salute"]},"zipper_mouth_face":{"a":"Zipper-Mouth Face","b":"1F910","f":true,"k":[39,38],"j":["face","sealed","zipper","secret"]},"face_with_raised_eyebrow":{"a":"Face with One Eyebrow Raised","b":"1F928","f":true,"k":[41,15],"j":["face","distrust","scepticism","disapproval","disbelief","surprise","suspicious"]},"neutral_face":{"a":"Neutral Face","b":"1F610","f":true,"k":[33,1],"j":["indifference","meh",":|","neutral"],"l":[":|",":-|"]},"expressionless":{"a":"Expressionless Face","b":"1F611","f":true,"k":[33,2],"j":["expressionless_face","face","indifferent","-_-","meh","deadpan"]},"no_mouth":{"a":"Face Without Mouth","b":"1F636","f":true,"k":[33,42],"j":["face_without_mouth","face"]},"dotted_line_face":{"a":"Dotted Line Face","b":"1FAE5","f":true,"k":[56,42],"j":["dotted line face","invisible","lonely","isolation","depression"]},"face_in_clouds":{"a":"Face In Clouds","b":"1F636-200D-1F32B-FE0F","f":true,"k":[33,41],"c":"1F636-200D-1F32B","j":["face_without_mouth","face"]},"smirk":{"a":"Smirking Face","b":"1F60F","f":true,"k":[33,0],"j":["smirking_face","face","smile","mean","prank","smug","sarcasm"]},"unamused":{"a":"Unamused Face","b":"1F612","f":true,"k":[33,3],"j":["unamused_face","indifference","bored","straight face","serious","sarcasm","unimpressed","skeptical","dubious","ugh","side_eye"],"m":":("},"face_with_rolling_eyes":{"a":"Face with Rolling Eyes","b":"1F644","f":true,"k":[33,58],"j":["face","eyeroll","frustrated"]},"grimacing":{"a":"Grimacing Face","b":"1F62C","f":true,"k":[33,29],"j":["grimacing_face","face","grimace","teeth"]},"face_exhaling":{"a":"Face Exhaling","b":"1F62E-200D-1F4A8","f":true,"k":[33,31],"j":["face_with_open_mouth","face","surprise","impressed","wow","whoa",":O"]},"lying_face":{"a":"Lying Face","b":"1F925","f":true,"k":[40,57],"j":["face","lie","pinocchio"]},"shaking_face":{"a":"Shaking Face","b":"1FAE8","f":true,"k":[56,45],"j":["shaking face","dizzy","shock","blurry","earthquake"]},"head_shaking_horizontally":{"a":"Head Shaking Horizontally","b":"1F642-200D-2194-FE0F","f":true,"k":[33,54],"c":"1F642-200D-2194","j":["slightly_smiling_face","face","smile"]},"head_shaking_vertically":{"a":"Head Shaking Vertically","b":"1F642-200D-2195-FE0F","f":true,"k":[33,55],"c":"1F642-200D-2195","j":["slightly_smiling_face","face","smile"]},"relieved":{"a":"Relieved Face","b":"1F60C","f":true,"k":[32,59],"j":["relieved_face","face","relaxed","phew","massage","happiness"]},"pensive":{"a":"Pensive Face","b":"1F614","f":true,"k":[33,5],"j":["pensive_face","face","sad","depressed","upset"]},"sleepy":{"a":"Sleepy Face","b":"1F62A","f":true,"k":[33,27],"j":["sleepy_face","face","tired","rest","nap"]},"drooling_face":{"a":"Drooling Face","b":"1F924","f":true,"k":[40,56],"j":["face"]},"sleeping":{"a":"Sleeping Face","b":"1F634","f":true,"k":[33,38],"j":["sleeping_face","face","tired","sleepy","night","zzz"]},"face_with_bags_under_eyes":{"a":"Face with Bags Under Eyes","b":"1FAE9","f":true,"k":[56,46]},"mask":{"a":"Face with Medical Mask","b":"1F637","f":true,"k":[33,43],"j":["face_with_medical_mask","face","sick","ill","disease","covid"]},"face_with_thermometer":{"a":"Face with Thermometer","b":"1F912","f":true,"k":[39,40],"j":["sick","temperature","thermometer","cold","fever","covid"]},"face_with_head_bandage":{"a":"Face with Head-Bandage","b":"1F915","f":true,"k":[39,43],"j":["injured","clumsy","bandage","hurt"]},"nauseated_face":{"a":"Nauseated Face","b":"1F922","f":true,"k":[40,54],"j":["face","vomit","gross","green","sick","throw up","ill"]},"face_vomiting":{"a":"Face with Open Mouth Vomiting","b":"1F92E","f":true,"k":[41,21],"j":["face","sick"]},"sneezing_face":{"a":"Sneezing Face","b":"1F927","f":true,"k":[41,14],"j":["face","gesundheit","sneeze","sick","allergy"]},"hot_face":{"a":"Overheated Face","b":"1F975","f":true,"k":[44,38],"j":["face","feverish","heat","red","sweating"]},"cold_face":{"a":"Freezing Face","b":"1F976","f":true,"k":[44,39],"j":["face","blue","freezing","frozen","frostbite","icicles"]},"woozy_face":{"a":"Face with Uneven Eyes and Wavy Mouth","b":"1F974","f":true,"k":[44,37],"j":["face","dizzy","intoxicated","tipsy","wavy"]},"dizzy_face":{"a":"Dizzy Face","b":"1F635","f":true,"k":[33,40],"j":["spent","unconscious","xox","dizzy"]},"face_with_spiral_eyes":{"a":"Face with Spiral Eyes","b":"1F635-200D-1F4AB","f":true,"k":[33,39],"j":["dizzy_face","spent","unconscious","xox","dizzy"]},"exploding_head":{"a":"Shocked Face with Exploding Head","b":"1F92F","f":true,"k":[41,22],"j":["face","shocked","mind","blown"]},"face_with_cowboy_hat":{"a":"Face with Cowboy Hat","b":"1F920","f":true,"k":[40,52],"j":["cowboy_hat_face","face","cowgirl","hat"]},"partying_face":{"a":"Face with Party Horn and Party Hat","b":"1F973","f":true,"k":[44,36],"j":["face","celebration","woohoo"]},"disguised_face":{"a":"Disguised Face","b":"1F978","f":true,"k":[44,46],"j":["disguised face","pretent","brows","glasses","moustache"]},"sunglasses":{"a":"Smiling Face with Sunglasses","b":"1F60E","f":true,"k":[32,61],"j":["smiling_face_with_sunglasses","face","cool","smile","summer","beach","sunglass"],"l":["8)"]},"nerd_face":{"a":"Nerd Face","b":"1F913","f":true,"k":[39,41],"j":["face","nerdy","geek","dork"]},"face_with_monocle":{"a":"Face with Monocle","b":"1F9D0","f":true,"k":[48,0],"j":["face","stuffy","wealthy"]},"confused":{"a":"Confused Face","b":"1F615","f":true,"k":[33,6],"j":["confused_face","face","indifference","huh","weird","hmmm",":/"],"l":[":\\",":-\\",":/",":-/"]},"face_with_diagonal_mouth":{"a":"Face with Diagonal Mouth","b":"1FAE4","f":true,"k":[56,41],"j":["face with diagonal mouth","skeptic","confuse","frustrated","indifferent"]},"worried":{"a":"Worried Face","b":"1F61F","f":true,"k":[33,16],"j":["worried_face","face","concern","nervous",":("]},"slightly_frowning_face":{"a":"Slightly Frowning Face","b":"1F641","f":true,"k":[33,53],"j":["face","frowning","disappointed","sad","upset"]},"white_frowning_face":{"a":"Frowning Face","b":"2639-FE0F","f":true,"k":[58,40],"c":"2639"},"open_mouth":{"a":"Face with Open Mouth","b":"1F62E","f":true,"k":[33,32],"j":["face_with_open_mouth","face","surprise","impressed","wow","whoa",":O"],"l":[":o",":-o",":O",":-O"]},"hushed":{"a":"Hushed Face","b":"1F62F","f":true,"k":[33,33],"j":["hushed_face","face","woo","shh"]},"astonished":{"a":"Astonished Face","b":"1F632","f":true,"k":[33,36],"j":["astonished_face","face","xox","surprised","poisoned"]},"flushed":{"a":"Flushed Face","b":"1F633","f":true,"k":[33,37],"j":["flushed_face","face","blush","shy","flattered"]},"pleading_face":{"a":"Face with Pleading Eyes","b":"1F97A","f":true,"k":[44,48],"j":["face","begging","mercy","cry","tears","sad","grievance"]},"face_holding_back_tears":{"a":"Face Holding Back Tears","b":"1F979","f":true,"k":[44,47],"j":["face holding back tears","touched","gratitude","cry"]},"frowning":{"a":"Frowning Face with Open Mouth","b":"1F626","f":true,"k":[33,23],"j":["frowning_face_with_open_mouth","face","aw","what"]},"anguished":{"a":"Anguished Face","b":"1F627","f":true,"k":[33,24],"j":["anguished_face","face","stunned","nervous"],"l":["D:"]},"fearful":{"a":"Fearful Face","b":"1F628","f":true,"k":[33,25],"j":["fearful_face","face","scared","terrified","nervous"]},"cold_sweat":{"a":"Face with Open Mouth and Cold Sweat","b":"1F630","f":true,"k":[33,34],"j":["anxious_face_with_sweat","face","nervous","sweat"]},"disappointed_relieved":{"a":"Disappointed But Relieved Face","b":"1F625","f":true,"k":[33,22],"j":["sad_but_relieved_face","face","phew","sweat","nervous"]},"cry":{"a":"Crying Face","b":"1F622","f":true,"k":[33,19],"j":["crying_face","face","tears","sad","depressed","upset",":'("],"l":[":'("],"m":":'("},"sob":{"a":"Loudly Crying Face","b":"1F62D","f":true,"k":[33,30],"j":["loudly_crying_face","sobbing","face","cry","tears","sad","upset","depressed"],"m":":'("},"scream":{"a":"Face Screaming In Fear","b":"1F631","f":true,"k":[33,35],"j":["face_screaming_in_fear","face","munch","scared","omg"]},"confounded":{"a":"Confounded Face","b":"1F616","f":true,"k":[33,7],"j":["confounded_face","face","confused","sick","unwell","oops",":S"]},"persevere":{"a":"Persevering Face","b":"1F623","f":true,"k":[33,20],"j":["persevering_face","face","sick","no","upset","oops"]},"disappointed":{"a":"Disappointed Face","b":"1F61E","f":true,"k":[33,15],"j":["disappointed_face","face","sad","upset","depressed",":("],"l":["):",":(",":-("],"m":":("},"sweat":{"a":"Face with Cold Sweat","b":"1F613","f":true,"k":[33,4],"j":["downcast_face_with_sweat","face","hot","sad","tired","exercise"]},"weary":{"a":"Weary Face","b":"1F629","f":true,"k":[33,26],"j":["weary_face","face","tired","sleepy","sad","frustrated","upset"]},"tired_face":{"a":"Tired Face","b":"1F62B","f":true,"k":[33,28],"j":["sick","whine","upset","frustrated"]},"yawning_face":{"a":"Yawning Face","b":"1F971","f":true,"k":[44,34],"j":["tired","sleepy"]},"triumph":{"a":"Face with Look Of Triumph","b":"1F624","f":true,"k":[33,21],"j":["face_with_steam_from_nose","face","gas","phew","proud","pride"]},"rage":{"a":"Pouting Face","b":"1F621","f":true,"k":[33,18],"j":["pouting_face","angry","mad","hate","despise"]},"angry":{"a":"Angry Face","b":"1F620","f":true,"k":[33,17],"j":["angry_face","mad","face","annoyed","frustrated"],"l":[">:(",">:-("]},"face_with_symbols_on_mouth":{"a":"Serious Face with Symbols Covering Mouth","b":"1F92C","f":true,"k":[41,19],"j":["face","swearing","cursing","cussing","profanity","expletive"]},"smiling_imp":{"a":"Smiling Face with Horns","b":"1F608","f":true,"k":[32,55],"j":["smiling_face_with_horns","devil","horns"]},"imp":{"a":"Imp","b":"1F47F","f":true,"k":[25,42],"j":["angry_face_with_horns","devil","angry","horns"]},"skull":{"a":"Skull","b":"1F480","f":true,"k":[25,43],"j":["dead","skeleton","creepy","death","dead"]},"skull_and_crossbones":{"a":"Skull and Crossbones","b":"2620-FE0F","f":true,"k":[58,32],"c":"2620"},"hankey":{"a":"Pile Of Poo","b":"1F4A9","f":true,"k":[28,26],"j":["pile_of_poo","shitface","fail","turd","shit"]},"clown_face":{"a":"Clown Face","b":"1F921","f":true,"k":[40,53],"j":["face"]},"japanese_ogre":{"a":"Japanese Ogre","b":"1F479","f":true,"k":[25,31],"j":["ogre","monster","red","mask","halloween","scary","creepy","devil","demon"]},"japanese_goblin":{"a":"Japanese Goblin","b":"1F47A","f":true,"k":[25,32],"j":["goblin","red","evil","mask","monster","scary","creepy"]},"ghost":{"a":"Ghost","b":"1F47B","f":true,"k":[25,33],"j":["halloween","spooky","scary"]},"alien":{"a":"Extraterrestrial Alien","b":"1F47D","f":true,"k":[25,40],"j":["UFO","paul","weird","outer_space"]},"space_invader":{"a":"Alien Monster","b":"1F47E","f":true,"k":[25,41],"j":["alien_monster","game","arcade","play"]},"robot_face":{"a":"Robot Face","b":"1F916","f":true,"k":[39,44],"j":["robot","computer","machine","bot"]},"smiley_cat":{"a":"Smiling Cat Face with Open Mouth","b":"1F63A","f":true,"k":[33,46],"j":["grinning_cat","animal","cats","happy","smile"]},"smile_cat":{"a":"Grinning Cat Face with Smiling Eyes","b":"1F638","f":true,"k":[33,44],"j":["grinning_cat_with_smiling_eyes","animal","cats","smile"]},"joy_cat":{"a":"Cat Face with Tears Of Joy","b":"1F639","f":true,"k":[33,45],"j":["cat_with_tears_of_joy","animal","cats","haha","happy","tears"]},"heart_eyes_cat":{"a":"Smiling Cat Face with Heart-Shaped Eyes","b":"1F63B","f":true,"k":[33,47],"j":["smiling_cat_with_heart_eyes","animal","love","like","affection","cats","valentines","heart"]},"smirk_cat":{"a":"Cat Face with Wry Smile","b":"1F63C","f":true,"k":[33,48],"j":["cat_with_wry_smile","animal","cats","smirk"]},"kissing_cat":{"a":"Kissing Cat Face with Closed Eyes","b":"1F63D","f":true,"k":[33,49],"j":["animal","cats","kiss"]},"scream_cat":{"a":"Weary Cat Face","b":"1F640","f":true,"k":[33,52],"j":["weary_cat","animal","cats","munch","scared","scream"]},"crying_cat_face":{"a":"Crying Cat Face","b":"1F63F","f":true,"k":[33,51],"j":["crying_cat","animal","tears","weep","sad","cats","upset","cry"]},"pouting_cat":{"a":"Pouting Cat Face","b":"1F63E","f":true,"k":[33,50],"j":["animal","cats"]},"see_no_evil":{"a":"See-No-Evil Monkey","b":"1F648","f":true,"k":[34,51],"j":["see_no_evil_monkey","monkey","animal","nature","haha"]},"hear_no_evil":{"a":"Hear-No-Evil Monkey","b":"1F649","f":true,"k":[34,52],"j":["hear_no_evil_monkey","animal","monkey","nature"]},"speak_no_evil":{"a":"Speak-No-Evil Monkey","b":"1F64A","f":true,"k":[34,53],"j":["speak_no_evil_monkey","monkey","animal","nature","omg"]},"love_letter":{"a":"Love Letter","b":"1F48C","f":true,"k":[27,9],"j":["email","like","affection","envelope","valentines"]},"cupid":{"a":"Heart with Arrow","b":"1F498","f":true,"k":[28,9],"j":["heart_with_arrow","love","like","heart","affection","valentines"]},"gift_heart":{"a":"Heart with Ribbon","b":"1F49D","f":true,"k":[28,14],"j":["heart_with_ribbon","love","valentines"]},"sparkling_heart":{"a":"Sparkling Heart","b":"1F496","f":true,"k":[28,7],"j":["love","like","affection","valentines"]},"heartpulse":{"a":"Growing Heart","b":"1F497","f":true,"k":[28,8],"j":["growing_heart","like","love","affection","valentines","pink"]},"heartbeat":{"a":"Beating Heart","b":"1F493","f":true,"k":[28,4],"j":["beating_heart","love","like","affection","valentines","pink","heart"]},"revolving_hearts":{"a":"Revolving Hearts","b":"1F49E","f":true,"k":[28,15],"j":["love","like","affection","valentines"]},"two_hearts":{"a":"Two Hearts","b":"1F495","f":true,"k":[28,6],"j":["love","like","affection","valentines","heart"]},"heart_decoration":{"a":"Heart Decoration","b":"1F49F","f":true,"k":[28,16],"j":["purple-square","love","like"]},"heavy_heart_exclamation_mark_ornament":{"a":"Heart Exclamation","b":"2763-FE0F","f":true,"k":[60,43],"c":"2763"},"broken_heart":{"a":"Broken Heart","b":"1F494","f":true,"k":[28,5],"j":["sad","sorry","break","heart","heartbreak"],"l":[" `${assetHost}/emoji/sheet_15_1.png`; +const backgroundImageFnDefault = () => `${assetHost}/emoji/sheet_16_0.png`; const Emoji = ({ set = 'twitter', diff --git a/lib/tasks/emojis.rake b/lib/tasks/emojis.rake index 330101f555a88c..bf43aee439b708 100644 --- a/lib/tasks/emojis.rake +++ b/lib/tasks/emojis.rake @@ -48,6 +48,7 @@ def get_image(row, emoji_base, fallback, compressed) if path.exist? Vips::Image.new_from_file(path.to_s, dpi: 64) else + puts "Missing emoji: #{row['b'] || row['unified']}" fallback end end @@ -59,7 +60,7 @@ end namespace :emojis do desc 'Generate a unicode to filename mapping' task :generate do - source = 'http://www.unicode.org/Public/emoji/15.1/emoji-test.txt' + source = 'http://www.unicode.org/Public/emoji/16.0/emoji-test.txt' codes = [] dest = Rails.root.join('app', 'javascript', 'mastodon', 'features', 'emoji', 'emoji_map.json') @@ -120,7 +121,7 @@ namespace :emojis do desc 'Generate the JSON emoji data' task :generate_json do - data_source = 'https://raw.githubusercontent.com/iamcal/emoji-data/refs/tags/v15.1.2/emoji.json' + data_source = 'https://raw.githubusercontent.com/iamcal/emoji-data/refs/tags/v16.0.0/emoji.json' keyword_source = 'https://raw.githubusercontent.com/muan/emojilib/refs/tags/v3.0.12/dist/emoji-en-US.json' data_dest = Rails.root.join('app', 'javascript', 'mastodon', 'features', 'emoji', 'emoji_data.json') @@ -224,6 +225,6 @@ namespace :emojis do end joined = Vips::Image.arrayjoin(comp.flatten, across: size, hspacing: 34, halign: :centre, vspacing: 34, valign: :centre) - joined.write_to_file(emoji_base.join('sheet_15_1.png').to_s, palette: true, dither: 0, Q: 100) + joined.write_to_file(emoji_base.join('sheet_16_0.png').to_s, palette: true, dither: 0, Q: 100) end end diff --git a/public/emoji/1f1e8-1f1f6.svg b/public/emoji/1f1e8-1f1f6.svg new file mode 100644 index 00000000000000..06294f8625c4c6 --- /dev/null +++ b/public/emoji/1f1e8-1f1f6.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1f426-200d-2b1b.svg b/public/emoji/1f426-200d-2b1b.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1f6dd.svg b/public/emoji/1f6dd.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1f6de.svg b/public/emoji/1f6de.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1f6df.svg b/public/emoji/1f6df.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1f7f0.svg b/public/emoji/1f7f0.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1f91d-1f3fb.svg b/public/emoji/1f91d-1f3fb.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1f91d-1f3fc.svg b/public/emoji/1f91d-1f3fc.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1f91d-1f3fd.svg b/public/emoji/1f91d-1f3fd.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1f91d-1f3fe.svg b/public/emoji/1f91d-1f3fe.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1f91d-1f3ff.svg b/public/emoji/1f91d-1f3ff.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1f9cc.svg b/public/emoji/1f9cc.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fa75.svg b/public/emoji/1fa75.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fa76.svg b/public/emoji/1fa76.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fa77.svg b/public/emoji/1fa77.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fa7b.svg b/public/emoji/1fa7b.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fa7c.svg b/public/emoji/1fa7c.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fa88.svg b/public/emoji/1fa88.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fa89.svg b/public/emoji/1fa89.svg new file mode 100644 index 00000000000000..aa360815080c31 --- /dev/null +++ b/public/emoji/1fa89.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1fa8f.svg b/public/emoji/1fa8f.svg new file mode 100644 index 00000000000000..1a80ea2dc26eaa --- /dev/null +++ b/public/emoji/1fa8f.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1faa9.svg b/public/emoji/1faa9.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faaa.svg b/public/emoji/1faaa.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faab.svg b/public/emoji/1faab.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faac.svg b/public/emoji/1faac.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fab7.svg b/public/emoji/1fab7.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fab8.svg b/public/emoji/1fab8.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fab9.svg b/public/emoji/1fab9.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faba.svg b/public/emoji/1faba.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fabe.svg b/public/emoji/1fabe.svg new file mode 100644 index 00000000000000..3b9b6bfa121947 --- /dev/null +++ b/public/emoji/1fabe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1fac3-1f3fb.svg b/public/emoji/1fac3-1f3fb.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fac3-1f3fc.svg b/public/emoji/1fac3-1f3fc.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fac3-1f3fd.svg b/public/emoji/1fac3-1f3fd.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fac3-1f3fe.svg b/public/emoji/1fac3-1f3fe.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fac3-1f3ff.svg b/public/emoji/1fac3-1f3ff.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fac3.svg b/public/emoji/1fac3.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fac4-1f3fb.svg b/public/emoji/1fac4-1f3fb.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fac4-1f3fc.svg b/public/emoji/1fac4-1f3fc.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fac4-1f3fd.svg b/public/emoji/1fac4-1f3fd.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fac4-1f3fe.svg b/public/emoji/1fac4-1f3fe.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fac4-1f3ff.svg b/public/emoji/1fac4-1f3ff.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fac4.svg b/public/emoji/1fac4.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fac5-1f3fb.svg b/public/emoji/1fac5-1f3fb.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fac5-1f3fc.svg b/public/emoji/1fac5-1f3fc.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fac5-1f3fd.svg b/public/emoji/1fac5-1f3fd.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fac5-1f3fe.svg b/public/emoji/1fac5-1f3fe.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fac5-1f3ff.svg b/public/emoji/1fac5-1f3ff.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fac5.svg b/public/emoji/1fac5.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fac6.svg b/public/emoji/1fac6.svg new file mode 100644 index 00000000000000..be06881146cfb0 --- /dev/null +++ b/public/emoji/1fac6.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1fad7.svg b/public/emoji/1fad7.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fad8.svg b/public/emoji/1fad8.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fad9.svg b/public/emoji/1fad9.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fadc.svg b/public/emoji/1fadc.svg new file mode 100644 index 00000000000000..9922df663e20f1 --- /dev/null +++ b/public/emoji/1fadc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1fadf.svg b/public/emoji/1fadf.svg new file mode 100644 index 00000000000000..1b9de852b53ae9 --- /dev/null +++ b/public/emoji/1fadf.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1fae0.svg b/public/emoji/1fae0.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fae1.svg b/public/emoji/1fae1.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fae2.svg b/public/emoji/1fae2.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fae3.svg b/public/emoji/1fae3.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fae4.svg b/public/emoji/1fae4.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fae5.svg b/public/emoji/1fae5.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fae6.svg b/public/emoji/1fae6.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fae7.svg b/public/emoji/1fae7.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1fae9.svg b/public/emoji/1fae9.svg new file mode 100644 index 00000000000000..7ec75458cca8fb --- /dev/null +++ b/public/emoji/1fae9.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1faf0-1f3fb.svg b/public/emoji/1faf0-1f3fb.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf0-1f3fc.svg b/public/emoji/1faf0-1f3fc.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf0-1f3fd.svg b/public/emoji/1faf0-1f3fd.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf0-1f3fe.svg b/public/emoji/1faf0-1f3fe.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf0-1f3ff.svg b/public/emoji/1faf0-1f3ff.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf0.svg b/public/emoji/1faf0.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf1-1f3fb-200d-1faf2-1f3fc.svg b/public/emoji/1faf1-1f3fb-200d-1faf2-1f3fc.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf1-1f3fb-200d-1faf2-1f3fd.svg b/public/emoji/1faf1-1f3fb-200d-1faf2-1f3fd.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf1-1f3fb-200d-1faf2-1f3fe.svg b/public/emoji/1faf1-1f3fb-200d-1faf2-1f3fe.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf1-1f3fb-200d-1faf2-1f3ff.svg b/public/emoji/1faf1-1f3fb-200d-1faf2-1f3ff.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf1-1f3fb.svg b/public/emoji/1faf1-1f3fb.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf1-1f3fc-200d-1faf2-1f3fb.svg b/public/emoji/1faf1-1f3fc-200d-1faf2-1f3fb.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf1-1f3fc-200d-1faf2-1f3fd.svg b/public/emoji/1faf1-1f3fc-200d-1faf2-1f3fd.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf1-1f3fc-200d-1faf2-1f3fe.svg b/public/emoji/1faf1-1f3fc-200d-1faf2-1f3fe.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf1-1f3fc-200d-1faf2-1f3ff.svg b/public/emoji/1faf1-1f3fc-200d-1faf2-1f3ff.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf1-1f3fc.svg b/public/emoji/1faf1-1f3fc.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf1-1f3fd-200d-1faf2-1f3fb.svg b/public/emoji/1faf1-1f3fd-200d-1faf2-1f3fb.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf1-1f3fd-200d-1faf2-1f3fc.svg b/public/emoji/1faf1-1f3fd-200d-1faf2-1f3fc.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf1-1f3fd-200d-1faf2-1f3fe.svg b/public/emoji/1faf1-1f3fd-200d-1faf2-1f3fe.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf1-1f3fd-200d-1faf2-1f3ff.svg b/public/emoji/1faf1-1f3fd-200d-1faf2-1f3ff.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf1-1f3fd.svg b/public/emoji/1faf1-1f3fd.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf1-1f3fe-200d-1faf2-1f3fb.svg b/public/emoji/1faf1-1f3fe-200d-1faf2-1f3fb.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf1-1f3fe-200d-1faf2-1f3fc.svg b/public/emoji/1faf1-1f3fe-200d-1faf2-1f3fc.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf1-1f3fe-200d-1faf2-1f3fd.svg b/public/emoji/1faf1-1f3fe-200d-1faf2-1f3fd.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf1-1f3fe-200d-1faf2-1f3ff.svg b/public/emoji/1faf1-1f3fe-200d-1faf2-1f3ff.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf1-1f3fe.svg b/public/emoji/1faf1-1f3fe.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf1-1f3ff-200d-1faf2-1f3fb.svg b/public/emoji/1faf1-1f3ff-200d-1faf2-1f3fb.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf1-1f3ff-200d-1faf2-1f3fc.svg b/public/emoji/1faf1-1f3ff-200d-1faf2-1f3fc.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf1-1f3ff-200d-1faf2-1f3fd.svg b/public/emoji/1faf1-1f3ff-200d-1faf2-1f3fd.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf1-1f3ff-200d-1faf2-1f3fe.svg b/public/emoji/1faf1-1f3ff-200d-1faf2-1f3fe.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf1-1f3ff.svg b/public/emoji/1faf1-1f3ff.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf1.svg b/public/emoji/1faf1.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf2-1f3fb.svg b/public/emoji/1faf2-1f3fb.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf2-1f3fc.svg b/public/emoji/1faf2-1f3fc.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf2-1f3fd.svg b/public/emoji/1faf2-1f3fd.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf2-1f3fe.svg b/public/emoji/1faf2-1f3fe.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf2-1f3ff.svg b/public/emoji/1faf2-1f3ff.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf2.svg b/public/emoji/1faf2.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf3-1f3fb.svg b/public/emoji/1faf3-1f3fb.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf3-1f3fc.svg b/public/emoji/1faf3-1f3fc.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf3-1f3fd.svg b/public/emoji/1faf3-1f3fd.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf3-1f3fe.svg b/public/emoji/1faf3-1f3fe.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf3-1f3ff.svg b/public/emoji/1faf3-1f3ff.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf3.svg b/public/emoji/1faf3.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf4-1f3fb.svg b/public/emoji/1faf4-1f3fb.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf4-1f3fc.svg b/public/emoji/1faf4-1f3fc.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf4-1f3fd.svg b/public/emoji/1faf4-1f3fd.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf4-1f3fe.svg b/public/emoji/1faf4-1f3fe.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf4-1f3ff.svg b/public/emoji/1faf4-1f3ff.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf4.svg b/public/emoji/1faf4.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf5-1f3fb.svg b/public/emoji/1faf5-1f3fb.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf5-1f3fc.svg b/public/emoji/1faf5-1f3fc.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf5-1f3fd.svg b/public/emoji/1faf5-1f3fd.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf5-1f3fe.svg b/public/emoji/1faf5-1f3fe.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf5-1f3ff.svg b/public/emoji/1faf5-1f3ff.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf5.svg b/public/emoji/1faf5.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf6-1f3fb.svg b/public/emoji/1faf6-1f3fb.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf6-1f3fc.svg b/public/emoji/1faf6-1f3fc.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf6-1f3fd.svg b/public/emoji/1faf6-1f3fd.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf6-1f3fe.svg b/public/emoji/1faf6-1f3fe.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf6-1f3ff.svg b/public/emoji/1faf6-1f3ff.svg old mode 100755 new mode 100644 diff --git a/public/emoji/1faf6.svg b/public/emoji/1faf6.svg old mode 100755 new mode 100644 diff --git a/public/emoji/sheet_16_0.png b/public/emoji/sheet_16_0.png new file mode 100644 index 0000000000000000000000000000000000000000..f8945ba5e235566fdbe6b77d7fd7af89bf2da9ac GIT binary patch literal 1312532 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ℜ>eRAjrO1;Y zMy_e{=d4uS;yIUB_|dA#d>J`tfLN&Gg}^6I2jElqt6fkBjE_18kE2)+QfU3MZJg1;fsPeYujLy=ee48 z%p8wn6Yb;x-v&Gte>p+gKzVlj%8odbLaIS73byluCzmRFH?aC@Vln_->A!+j^3>AI zgH`kD5KOR^D;*&YXvFfE8@YV!o)RtLjLl~?)8_mQB!(c`=Cg)0gP(%nrfq|b^ea>Q zN@Uu4!~l8URp{|<`kgZTQ9LrfLeagrcKeqjCE90MF^bPge4wc9Vd`AV|raWMIJhpCEHHw7?#?8^i_| z(QM@!YY@E!(oZdpF0qL$qp@<9C*cw+TQ#;iN+dB-F8SF_3Y)*SGi-nVCGX?O*F%lXHmS0HxynFexBKMOu$s zh(689Tas0CN0;BE5|)3uyh)f}{^NYgk9;FAQhNO2@dzYcYJe<&nUq49^X8Qh0hmCl zq*mDXYCArYk8!QG&$q_=J*cdIG1r@Ui@t{TPLReA2zzrVlklr9wj>^%R7p8JD)Uf3 z4oDuJv=H#sHvET$_1AMnQ(pbISICsa+7AcA85C3QSd)iVa>}3Y4x5{`$HpJ-tMdK9 z#kZ4(WGm+ZscY|{Rg63P52t>T9OrLYM zUJj~nNt@BCD0(6prO||PQ?&Sc$4uRs#=%=3MefM+ivGs*(pccr)hkB;?7j33YRCqo z+T|~cy?7z(xwZUoqIITx#1cm_u|0dHmDe}zOlm2S=;RU}C>X>bev)_1s0*V&#%4 zm8Y=5tNF;Y6GbA*@~#7QPS~^*SFeqUFB`)pzkW7gEzQA0h{N)TidF-ReC?^FOqtxf zdrIq*v?VTUd!-BQCk|>m3S@8x`T3dJpBu;9c=)~ack!f-64UQ4V|`uY34vN7Z}|FS zi6Gj)qm{N7a9-2eIqK0a>?)0}Eo2*}hH6XYRbWGeqZBy*xEFI!nOq1P$Emh15D0wR zq!`OE9^RC;b~E$WHmxm2+{Qbtwq-#kw`yfn>mD-up>NcsuQ9a5yH!Vf>i>;s!RF7)_8xRmJZVCNR*WL@z>W0P%B#*`!_7xL z3)HqKo@s{oEicmHJto@T&euMdts_SicEJzc2(rcye-QGmAtK2 z(RAXoFRD^65H~Qogcx5cN$@OR`lrvrg%jsbQLEwF#iHU{p6c*mS(t{8)UrZ=l4EB#0sLjvJw=Nf=j!_)dfBjM5PF?YLsT==&bJ<>${k0-D51 zXS#CMHZ?Sl&ZCvnGmjq${^0($Ty#!z?d}vGhyMKtN<_8f2dCCn|2L<#Bx#U|1m8;3 zH#5}r`=Im_7Jv|z^#;t&9tf=u$)kjaMF?U^ChfugAy6-iXi{+3>GpQIF{Q!ZZYav)(@dQyZeE56HJm_g+EeH)?P{EG)uhcZHAK!F_a z&0odl*6d=E)yB8rC5UUy_wT(J-#>5o%zG9M-=l+wc8Y)L=b7 z1!nAQ>Sc=CO44IxYz1y|=09ZWHXoEH9V(?dziC<4o}3!p#po#>n}K zpU)x1K9nUFtOAcoWPe&AEPUqKeAf6Bz4bsm9=ducA)DB>w%gegeHMiB`a*Ox3m{ea zPqxk9S|e$hE+e(ds3rt3eLjgwvQ1H@{08>_Vfn%7rz;uH0t4Rm-tW8MP5p+RhZG1| zI64^OveCik8=NyP@0O6n?z~CyZTVfAn_}P?>9~|+O|`ecg1i|-me@J)Z}}o{ zf>x`2l8EgkzZM8@2x3oEv-fpH1;%y7ubo&KGgmivbS~*L2&%wA5`}^bfZ>3MPfdz{ zh-o0|D!4^w65D;E>*OW^cpr?35AxQl-OO&*x$FXGX`d3d?I@!2id;7jE6S$zWvyK7dXeZXj zE^-^oGd2PfI%x_gVs-24RRV4FtXHoHp9Ny{<=xVBxO7 zgZ#QL-M5b9*I-xRNOHaF^DRbpkGGfEd(p0j{ugE7MPj@bzo=Ef%-1&+w8KiRzhTgp z;>bZlV(aHZD7Jf9wD|N->D+H_29?tYSU09W{Y_$W_`xMO%Ub5BK=zd6=OJnCw_b{ArlXuEUkShyu9!d`+Araj5Irh|AO2Ub@sD?!VJJecPaBhu zn#L{93U}K`ke|=ovXQF#I7uo!6DsR1PHV760VpQbgQDStaItDMZEZ0rXJVrEz*|?E2b-7rk)WzeuP^~db z3s4Dc3o8b}nfycId=U}jav#;t#B964J3P@FzG7}UrZeNh)w8GP3ibT}HuFYS;$-I^(#z8m1!B08=F#wxUG+8-Q09O1{*0g!i`- zG4EUT_cZWhKKWEJXO-O_5&5p^?eR{R3F>EbFDViS;jZT^idTS%uyzVN@^#%o4ogo4 zr~Y_2(rt$IVkH_sN|tN2dcN)D*;JQs0Z~DkN()f+?23p;fxQ|+vBwTo3i|L)%_FSC zWyuJb*1;$2H>@QPW`LkUZ7}$3+{p0y7 z8Ow3DC3Lk$ zA)zALm(sVot}Coo@<8<>gi(X!f+8a$5Nx=hH$CKGb_vl}u+w|vddf}wk(M^^S#cQa zF9QUjv9qJSl|>%}&U~$4VPdINI-W6-@nU>Ye}B$n_>D_k`XA0fNaLeG_N47p&~y1e zSk$FGPM8CqeEt_~vdA(~M4aF+CXK&V`n3jO3htm!pPUwQ9b`y_x%4+0nm4Pfslicj z2=#^y$2%Cj58!tmG_?u8d!Mv&2Q5Y44)TAY=%jKg-})scXCkqn!#>-Intn;dj6z=6 zNAL)>mj4hd5P|CnG<-gF1yxlA6kk|dSJS>7FciR z%gCgkl}*x>90_pov}NK>bkQN~Z(1h$Jp8W+Ea<7I*XF4?6B6e>>ZCF2e4GiwYBc#d z(htMW-AWy782@9w62<5}gS+r_OeXoTgTC!aEFVa}h`|XjutfR0GPK#`MvrD60?6g; z3JxHlzN5q1F02-&3uhF<6+1w2+VX7lJm!CX6waTCM^<8zCQK@)e7Ps``b@#_#K8i`f5%{dMB3VRbm zq<$ehUAbc)wn-4V*-og!p?VpowQ%KRhdv1y#5~E7uy7z zmNk(b7Ctew9rMdRa9Uh$cGn)c^zZgeyQWIy4s(ltU)maXbe63k(dNgNY1G#uB*x^D z!;Tz68YM)v#_vLw6{P?Yl8(oI)6CrQFft7%pV~!rxwM(@q}xCIF?J%wHp4*KONt(2 zW4(V!<2ADDSOf}Z4aq^x6>MA$(7-czl_}(}j|?k_l#aw-++Q}Q@#Olx&RA;@ z%Sewap2vp|+SPKfN*V`gBA(Nr07o~xXDmK3aV_n3!q<= znm$pWT%` zPbyc>|3MTYwfN}1sH%QeQuV@mFeY)r=;%t&kwvL-Y_ISYrHvf-dKX35;WssW4nytst#;@miTZURha08($pbX(gI0 z2>y#oQ)65_!s(8yOG-KrDr*HnWeA361A~>f&e-ET$yrp~h9bgUg*GL_0A%+PD!}b} zSNcIttsT@)HVAZN~}Pa<{xzd-4g3BBCj-r^Exa1Ga}7EyT;He>uc5m%VzQFwL_ zzCX*vU3@6*R%gs(wCn|jvh4J2nwL@pz+ZmQVl$G}FGX`EAG%O*&{N$C|It;4ubHU8hk>3tXjth7D#O4S$BwUKCgz@$H%SPm^ta`n!YEx7=NJ>Aaclr|XZ-QIN+EN&58Qw8su=Mo>A44u`d)ZZI8>iFIXHB?V>!CkLLL}>nFl%dJ+YGvk<_xkRO{to%C_3LG^JkgiZ60pip)fZ+9s&Cf3b+db*Gm9}J8NEQKaU=L}R& zG$Br-eTBkN0Y5M?owI%XAoQ_3z>!k%2Uj~CyUx?zqnUSs)LnMhR}#ihS(#V)bBE6Z zo%nz{;C=c8yr1?Ak#wb2-M)E-m%Nn0b+utumg0n!wfQ?9!_+oo0IbAEv%eht0mdGX ztgVu;&07g`R@3t}%cA9xq9!J`tb}+xf!M^{PG1i@%z7 zdfETVoZd9YeAEoNVS8XMkp1?&-M7{x+3EVl2!sf%5r%RudVa0C_R#hI(#S$`KO8bg zEe!;5_qs_wF+ue(y{5w2vzJl1@YLE9=?Eu6<$}n9KE_9li-hipzQ&V9?^rWj{&!yr zHQOnzuIpK^$s^>3)G>j;9cG^=nwg0JA%L1)bLkD$~}zTWOgvQyszLzP-Iv=pES@mbm) z*vl&wJ6W}@O$5!&BnKfR!GUt#9v4_ma7|)+-;7;cHkP1CKzq^|orK@{O{_PI1|?xw za=+pDi!zStf|mX2dQ)rV+2h7_2C)=VRB>JjmF#ddji_%@!NJPe*(J9vVmVlOUSTKr zZ8^W4H_EbjhE@1ux;_TVNBi0ddqnZLsrmO9`;gR9G5@@V2Lio zFp;2@;DXT4OcbJy8R($541y!AwRTf>4)M4vNP3!_h5RYb&de>vuE%eG&;p??W=NTk@) z>p7d(4Xz^~WP2Mn^sKvzmDx8g{y_k;3XPXOb#mOu9L<^-1?~G8=G8(3i$)r}$g8BAvK(?yvUwe`5 z@P8M`kU35V6C+2>%-Y_DPnQpZOl!AxbVeK9bOBV5Wgikl3g}uAP0Y1)aO59qDJ)kl zwVRA<8x4*EcyQU7-+$k@N0Fa>u}D>1$vVAVR93BNdWNR066}gevO}Yob@VB$%sa#V zUz-~mP+k>`Ynk)!=pcjHCpp_VomzQlHtZikQc$FS8KWMWv+4!qT~RH2doo846OT`S zZNHe1tYsJ*i;5aQP7m=(OI_MnxXPV&{BC0MxUl&1v=D~Gk?ASNg!2_uWJ1F`LV5A^ zcuFXqY--~X?<3)e@DaTwpo)sMdcmoqk*e+o;cKEZmu?W?K=?4%H+AHt{2{=`}|MsdPv{)FsK!FT_ zs$@Ua$T|#7DX8d9x+Ee&%q;LxaHwI+0I>5ftG6Dp2rz+#F3S43lT91Qw0O1*)|K=` zX^}7rB`EcnNA{WuNlu!nc?%a?af1I5FX<-(-EOkOZA*$YhuGCt5p5T8m1e(3Jf+IEUxafs zv2KgVk9kN05mR|+8Du3xYcwVhlTXI9F@cq%Zb&dDfdx!8AZyM!il8Si^Zteo z2KNlkF1PukeQ3HRH{`Jz!7c^$(jx#1%q+^{B`-U@<#x1zkPM$cP|AtduSh_>=Dsy9 zM`Ppdb|Js7Eza)x8M;^?)|x6-F$k2PSqNo7nm`F-<(~{RXcDVtj?NTn7

V3)(}N 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

7^1Ir&!}C$YIHmRJKeUQq95)2l~fEaJtUZu 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 X>xN$!r;5~{)gj|L&VN@E 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

7sZ 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

wJ>Y&ci8?VG&YS?&ZT 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%0D%-O4sR?mi!nD`oV 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

I(J=d#y@vDfcVW7d25&Cr3s_E1P;#Jmz@P0W3P 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%0DW-nyifONfA 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 z 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%0A3DRb!uh^(~H>Rcd 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

Pd#q;Qya?1L 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⋘88E45m&j$~Axwa; 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 literal 0 HcmV?d00001 diff --git a/app/javascript/images/archetypes/previews/replier.jpg b/app/javascript/images/archetypes/previews/replier.jpg new file mode 100644 index 0000000000000000000000000000000000000000..086ee599798fc4a0c9eb4563f6b3214368d14914 GIT binary patch literal 174922 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�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ξ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≻dQI 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 z

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 z z0`>MKgVljs*54xiON%eHOJjX~ohQHk@k7mF5cZSLX&Iv4YI=9I(-sL>cPp@4k@3oA zM9etpe_~V|oQf}|A}0D4&V62;oJM1k+0PfI-lcuADQ4uk=269zDectBW0Z4nSSDIc zT0!K20y-bZp+OejZh&xGBu48wjnyFkq?1EzoT|#kIR4y9i2M-FJ8#!e+x)H`_PH4z zUT<=KO+m8NrMT$a;@OfJ@zwLD{}ja@4(D)IDdzj|?;+fFR|G}XWO8}_RP#tC?-@({ z`i=97yb7Klc#a^kC=#sWdnfw)BOKMXQu1r?1EHjp;3N2|LC9|#$q5ro-5hAVUX-GA zMdg>P2Bx>Arp{M_$lo9CSiRlf>iOh%TiDtD2bg`%{^#j%0A@<$t7Xj`)WZNGop-sX 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�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Ӽ@1%?D9Ibn~Vbzn+p{eH5IV? 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�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 YscJ|v+urc7vR2yxiZB6T*rX5t*@sfgx&QzG literal 0 HcmV?d00001 diff --git a/app/javascript/images/archetypes/previews/pollster.jpg b/app/javascript/images/archetypes/previews/pollster.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c53e541867154233978ec36ea87401d13f3cf107 GIT binary patch literal 168732 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 mIY1UY)vWJl(M_p=6-89FBpGq Date: Thu, 11 Dec 2025 17:35:35 +0100 Subject: [PATCH 747/853] Change wrapstodon 2025 to allow unlisted posts in top statuses (#37206) --- app/lib/annual_report/top_statuses.rb | 8 ++++---- spec/lib/annual_report/top_statuses_spec.rb | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/lib/annual_report/top_statuses.rb b/app/lib/annual_report/top_statuses.rb index 4dcc31892bbf23..06c53e2a487f32 100644 --- a/app/lib/annual_report/top_statuses.rb +++ b/app/lib/annual_report/top_statuses.rb @@ -5,14 +5,14 @@ def generate { top_statuses: { by_reblogs: status_identifier(most_reblogged_status), - by_favourites: status_identifier(most_favourited_status), - by_replies: status_identifier(most_replied_status), + by_favourites: nil, + by_replies: nil, }, } end def eligible? - report_statuses.public_visibility.exists? + report_statuses.distributable_visibility.exists? end private @@ -43,7 +43,7 @@ def most_replied_status def base_scope report_statuses - .public_visibility + .distributable_visibility .joins(:status_stat) end end diff --git a/spec/lib/annual_report/top_statuses_spec.rb b/spec/lib/annual_report/top_statuses_spec.rb index af29df1f651a0b..24fa2139ce25d2 100644 --- a/spec/lib/annual_report/top_statuses_spec.rb +++ b/spec/lib/annual_report/top_statuses_spec.rb @@ -40,8 +40,8 @@ .to include( top_statuses: include( by_reblogs: reblogged_status.id.to_s, - by_favourites: favourited_status.id.to_s, - by_replies: replied_status.id.to_s + by_favourites: nil, + by_replies: nil ) ) end From d730f6b0c5cfb18894d1a9e34d0aa2556dda3c62 Mon Sep 17 00:00:00 2001 From: Emelia Smith Date: Thu, 11 Dec 2025 17:40:22 +0100 Subject: [PATCH 748/853] Add spec for client_credentials being used with /api/v1/apps/verify_credentials (#37195) --- spec/requests/api/v1/apps/credentials_spec.rb | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/spec/requests/api/v1/apps/credentials_spec.rb b/spec/requests/api/v1/apps/credentials_spec.rb index 8c0292d8c3e92b..09363362d62b11 100644 --- a/spec/requests/api/v1/apps/credentials_spec.rb +++ b/spec/requests/api/v1/apps/credentials_spec.rb @@ -75,6 +75,33 @@ end end + context 'with client credentials' do + let(:application) { Fabricate(:application, scopes: 'read admin:write') } + let(:token) { Fabricate(:client_credentials_token, application: application, scopes: 'read admin:write') } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + it 'returns http success and returns app information' do + subject + + expect(response).to have_http_status(200) + expect(response.content_type) + .to start_with('application/json') + + expect(response.parsed_body).to match( + a_hash_including( + id: token.application.id.to_s, + name: token.application.name, + website: token.application.website, + scopes: token.application.scopes.map(&:to_s), + redirect_uris: token.application.redirect_uris, + # Deprecated properties as of 4.3: + redirect_uri: token.application.redirect_uri.split.first, + vapid_key: Rails.configuration.x.vapid.public_key + ) + ) + end + end + context 'without an oauth token' do let(:headers) { {} } From c06eb371e6601c740c5998aa4c7e492f336e00eb Mon Sep 17 00:00:00 2001 From: diondiondion Date: Thu, 11 Dec 2025 18:06:26 +0100 Subject: [PATCH 749/853] Add Wrapstodon footer links (#37207) --- .../annual_report/shared_page.module.scss | 23 ++++++++++++++++--- .../features/annual_report/shared_page.tsx | 23 +++++++++++++++++++ app/javascript/mastodon/locales/en.json | 2 ++ app/views/wrapstodon/show.html.haml | 1 + 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/app/javascript/mastodon/features/annual_report/shared_page.module.scss b/app/javascript/mastodon/features/annual_report/shared_page.module.scss index 954f5bc8f9d124..b29ab517070e04 100644 --- a/app/javascript/mastodon/features/annual_report/shared_page.module.scss +++ b/app/javascript/mastodon/features/annual_report/shared_page.module.scss @@ -13,12 +13,13 @@ $mobile-breakpoint: 540px; } .footer { - text-align: center; - margin-top: 2rem; display: flex; flex-direction: column; - gap: 0.75rem; align-items: center; + gap: 0.75rem; + margin-top: 2rem; + font-size: 16px; + text-align: center; color: var(--color-text-secondary); } @@ -26,3 +27,19 @@ $mobile-breakpoint: 540px; width: 2rem; opacity: 0.6; } + +.nav { + display: flex; + flex-wrap: wrap; + gap: 12px; + + a:any-link { + color: inherit; + text-decoration: underline; + text-underline-offset: 0.2em; + } + + a:hover { + color: var(--color-text-primary); + } +} diff --git a/app/javascript/mastodon/features/annual_report/shared_page.tsx b/app/javascript/mastodon/features/annual_report/shared_page.tsx index 6ec533983c4f1b..ebf01da7f1d39b 100644 --- a/app/javascript/mastodon/features/annual_report/shared_page.tsx +++ b/app/javascript/mastodon/features/annual_report/shared_page.tsx @@ -3,6 +3,7 @@ import type { FC } from 'react'; import { FormattedMessage } from 'react-intl'; import { IconLogo } from '@/mastodon/components/logo'; +import { me } from '@/mastodon/initial_state'; import { AnnualReport } from './index'; import classes from './shared_page.module.scss'; @@ -18,6 +19,28 @@ export const WrapstodonSharedPage: FC = () => { defaultMessage='Generated with {heart} by the Mastodon team' values={{ heart: '♥' }} /> + ); diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index d01900a4e86217..0d46b446a7ab24 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -117,7 +117,9 @@ "annual_report.announcement.action_view": "View my Wrapstodon", "annual_report.announcement.description": "Discover more about your engagement on Mastodon over the past year.", "annual_report.announcement.title": "Wrapstodon {year} has arrived", + "annual_report.shared_page.donate": "Donate", "annual_report.shared_page.footer": "Generated with {heart} by the Mastodon team", + "annual_report.shared_page.sign_up": "Sign up", "annual_report.summary.archetype.booster.desc_public": "{name} stayed on the hunt for posts to boost, amplifying other creators with perfect aim.", "annual_report.summary.archetype.booster.desc_self": "You stayed on the hunt for posts to boost, amplifying other creators with perfect aim.", "annual_report.summary.archetype.booster.name": "The Archer", diff --git a/app/views/wrapstodon/show.html.haml b/app/views/wrapstodon/show.html.haml index ed1e64d4665298..519c862d3f4db8 100644 --- a/app/views/wrapstodon/show.html.haml +++ b/app/views/wrapstodon/show.html.haml @@ -11,6 +11,7 @@ = render 'og_description', account: @account = render 'og_image', report: @generated_annual_report + = render_initial_state = vite_typescript_tag 'wrapstodon.tsx', crossorigin: 'anonymous' - content_for :html_classes, 'theme-dark' From 5e0db46b2a542c29c050a221643bd6e550ecd7df Mon Sep 17 00:00:00 2001 From: diondiondion Date: Thu, 11 Dec 2025 12:40:53 +0100 Subject: [PATCH 750/853] [Glitch] Wrapstodon design QA tweaks Port 5651900b890ba5f1c36add6080b26640c5948086 to glitch-soc Signed-off-by: Claire --- .../status/intercept_status_clicks.tsx | 45 +++++++++++++ .../annual_report/highlighted_post.tsx | 26 +++++++- .../features/annual_report/index.module.scss | 64 ++++++++++++------- .../glitch/features/annual_report/index.tsx | 7 +- .../features/annual_report/share_button.tsx | 23 +++++-- ...age.module.css => shared_page.module.scss} | 10 ++- .../features/annual_report/shared_page.tsx | 2 +- 7 files changed, 141 insertions(+), 36 deletions(-) create mode 100644 app/javascript/flavours/glitch/components/status/intercept_status_clicks.tsx rename app/javascript/flavours/glitch/features/annual_report/{shared_page.module.css => shared_page.module.scss} (62%) diff --git a/app/javascript/flavours/glitch/components/status/intercept_status_clicks.tsx b/app/javascript/flavours/glitch/components/status/intercept_status_clicks.tsx new file mode 100644 index 00000000000000..b0dbc3c693848c --- /dev/null +++ b/app/javascript/flavours/glitch/components/status/intercept_status_clicks.tsx @@ -0,0 +1,45 @@ +import { useCallback, useRef } from 'react'; + +export const InterceptStatusClicks: React.FC<{ + onPreventedClick: ( + clickedArea: 'account' | 'post', + event: React.MouseEvent, + ) => void; + children: React.ReactNode; +}> = ({ onPreventedClick, children }) => { + const wrapperRef = useRef(null); + + const handleClick = useCallback( + (e: React.MouseEvent) => { + const clickTarget = e.target as Element; + const allowedElementsSelector = + '.video-player, .audio-player, .media-gallery, .content-warning'; + const allowedElements = wrapperRef.current?.querySelectorAll( + allowedElementsSelector, + ); + const isTargetClickAllowed = + allowedElements && + Array.from(allowedElements).some((element) => { + return clickTarget === element || element.contains(clickTarget); + }); + + if (!isTargetClickAllowed) { + e.preventDefault(); + e.stopPropagation(); + + const wasAccountAreaClicked = !!clickTarget.closest( + 'a.status__display-name', + ); + + onPreventedClick(wasAccountAreaClicked ? 'account' : 'post', e); + } + }, + [onPreventedClick], + ); + + return ( +
+ {children} +
+ ); +}; diff --git a/app/javascript/flavours/glitch/features/annual_report/highlighted_post.tsx b/app/javascript/flavours/glitch/features/annual_report/highlighted_post.tsx index 9ca64d40ba6047..9e03c7e327d5f2 100644 --- a/app/javascript/flavours/glitch/features/annual_report/highlighted_post.tsx +++ b/app/javascript/flavours/glitch/features/annual_report/highlighted_post.tsx @@ -4,10 +4,14 @@ @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call */ +import type { ComponentPropsWithoutRef } from 'react'; +import { useCallback } from 'react'; + import { FormattedMessage } from 'react-intl'; import classNames from 'classnames'; +import { InterceptStatusClicks } from 'flavours/glitch/components/status/intercept_status_clicks'; import { StatusQuoteManager } from 'flavours/glitch/components/status_quoted'; import type { TopStatuses } from 'flavours/glitch/models/annual_report'; import { makeGetStatus } from 'flavours/glitch/selectors'; @@ -29,6 +33,24 @@ export const HighlightedPost: React.FC<{ statusId ? getStatus(state, { id: statusId }) : undefined, ); + const handleClick = useCallback< + ComponentPropsWithoutRef['onPreventedClick'] + >( + (clickedArea) => { + const link: string = + clickedArea === 'account' + ? status.getIn(['account', 'url']) + : status.get('url'); + + if (context === 'standalone') { + window.location.href = link; + } else { + window.open(link, '_blank'); + } + }, + [status, context], + ); + if (!status) { return
; } @@ -72,7 +94,9 @@ export const HighlightedPost: React.FC<{ {context === 'modal' &&

{label}

}
- + + +
); }; diff --git a/app/javascript/flavours/glitch/features/annual_report/index.module.scss b/app/javascript/flavours/glitch/features/annual_report/index.module.scss index 95ebb727298550..7471e6282a1c84 100644 --- a/app/javascript/flavours/glitch/features/annual_report/index.module.scss +++ b/app/javascript/flavours/glitch/features/annual_report/index.module.scss @@ -21,7 +21,8 @@ $mobile-breakpoint: 540px; scrollbar-color: var(--color-text-secondary) var(--color-bg-secondary); @media (width < $mobile-breakpoint) { - padding-inline: 10px; + padding-top: 0; + padding-inline: 0; } .loading-indicator .circular-progress { @@ -50,37 +51,51 @@ $mobile-breakpoint: 540px; } .wrapper { + --gradient-strength: 0.4; + + box-sizing: border-box; position: relative; max-width: 600px; padding: 24px; + padding-top: 40px; contain: layout; flex: 0 0 auto; - pointer-events: auto; + pointer-events: all; color: var(--color-text-primary); background: var(--color-bg-primary); background: - radial-gradient(at 40% 87%, #240c9a99 0, transparent 50%), - radial-gradient(at 19% 10%, #6b0c9a99 0, transparent 50%), - radial-gradient(at 90% 27%, #9a0c8299 0, transparent 50%), - radial-gradient(at 16% 95%, #1e948299 0, transparent 50%), - radial-gradient(at 80% 91%, #16dae499 0, transparent 50%) + radial-gradient( + at 10% 27%, + rgba(83, 12, 154, var(--gradient-strength)) 0, + transparent 50% + ), + radial-gradient( + at 91% 10%, + rgba(30, 24, 223, var(--gradient-strength)) 0, + transparent 25% + ), + radial-gradient( + at 10% 91%, + rgba(22, 218, 228, var(--gradient-strength)) 0, + transparent 40% + ), + radial-gradient( + at 75% 87%, + rgba(37, 31, 217, var(--gradient-strength)) 0, + transparent 20% + ), + radial-gradient( + at 84% 60%, + rgba(95, 30, 148, var(--gradient-strength)) 0, + transparent 40% + ) var(--color-bg-primary); border-radius: 40px; @media (width < $mobile-breakpoint) { padding-inline: 12px; padding-bottom: 12px; - border-radius: 28px; - } - - &::after { - content: ''; - position: absolute; - inset: 0; - z-index: -1; - background: inherit; - border-radius: inherit; - filter: blur(20px); + border-radius: 0; } } @@ -92,7 +107,7 @@ $mobile-breakpoint: 540px; font-family: silkscreen-wrapstodon, monospace; font-size: 28px; line-height: 1; - margin-bottom: 8px; + margin-bottom: 4px; padding-inline: 40px; // Prevent overlap with close button @media (width < $mobile-breakpoint) { @@ -116,7 +131,7 @@ $mobile-breakpoint: 540px; .box { position: relative; - padding: 16px; + padding: 24px; border-radius: 16px; background: rgb(from var(--color-bg-primary) r g b / 60%); box-shadow: inset 0 0 0 1px rgb(from var(--color-text-primary) r g b / 40%); @@ -150,7 +165,6 @@ $mobile-breakpoint: 540px; flex-direction: column; justify-content: center; gap: 8px; - padding: 16px; font-size: 14px; text-align: center; text-wrap: balance; @@ -164,6 +178,10 @@ $mobile-breakpoint: 540px; text-transform: uppercase; color: #c2c8ff; font-weight: 500; + + &:last-child { + margin-bottom: -3px; + } } .statLarge { @@ -185,7 +203,7 @@ $mobile-breakpoint: 540px; .mostBoostedPost { padding: 0; - padding-top: 8px; + padding-top: 24px; overflow: hidden; } @@ -260,7 +278,7 @@ $mobile-breakpoint: 540px; display: flex; flex-direction: column; align-items: center; - gap: 12px; + gap: 16px; p { max-width: 460px; diff --git a/app/javascript/flavours/glitch/features/annual_report/index.tsx b/app/javascript/flavours/glitch/features/annual_report/index.tsx index d5133b3cb35607..b1d7fc55853913 100644 --- a/app/javascript/flavours/glitch/features/annual_report/index.tsx +++ b/app/javascript/flavours/glitch/features/annual_report/index.tsx @@ -1,7 +1,7 @@ import { useCallback, useEffect, useState } from 'react'; import type { FC } from 'react'; -import { defineMessage, useIntl } from 'react-intl'; +import { useIntl } from 'react-intl'; import { useLocation } from 'react-router'; @@ -23,11 +23,6 @@ import { NewPosts } from './new_posts'; const moduleClassNames = classNames.bind(styles); -export const shareMessage = defineMessage({ - id: 'annual_report.summary.share_message', - defaultMessage: 'I got the {archetype} archetype!', -}); - export const AnnualReport: FC<{ context?: 'modal' | 'standalone' }> = ({ context = 'standalone', }) => { diff --git a/app/javascript/flavours/glitch/features/annual_report/share_button.tsx b/app/javascript/flavours/glitch/features/annual_report/share_button.tsx index 497d15d1e85db1..652c8af913dcbf 100644 --- a/app/javascript/flavours/glitch/features/annual_report/share_button.tsx +++ b/app/javascript/flavours/glitch/features/annual_report/share_button.tsx @@ -1,7 +1,7 @@ import { useCallback } from 'react'; import type { FC } from 'react'; -import { useIntl } from 'react-intl'; +import { defineMessages, useIntl } from 'react-intl'; import { resetCompose, focusCompose } from '@/flavours/glitch/actions/compose'; import { closeModal } from '@/flavours/glitch/actions/modal'; @@ -9,9 +9,19 @@ import { Button } from '@/flavours/glitch/components/button'; import type { AnnualReport as AnnualReportData } from '@/flavours/glitch/models/annual_report'; import { useAppDispatch } from '@/flavours/glitch/store'; -import { shareMessage } from '.'; import { archetypeNames } from './archetype'; +const messages = defineMessages({ + share_message: { + id: 'annual_report.summary.share_message', + defaultMessage: 'I got the {archetype} archetype!', + }, + share_on_mastodon: { + id: 'annual_report.summary.share_on_mastodon', + defaultMessage: 'Share on Mastodon', + }, +}); + export const ShareButton: FC<{ report: AnnualReportData }> = ({ report }) => { const intl = useIntl(); const dispatch = useAppDispatch(); @@ -21,7 +31,7 @@ export const ShareButton: FC<{ report: AnnualReportData }> = ({ report }) => { archetypeNames[report.data.archetype], ); const shareLines = [ - intl.formatMessage(shareMessage, { + intl.formatMessage(messages.share_message, { archetype: archetypeName, }), ]; @@ -37,5 +47,10 @@ export const ShareButton: FC<{ report: AnnualReportData }> = ({ report }) => { dispatch(closeModal({ modalType: 'ANNUAL_REPORT', ignoreFocus: false })); }, [report, intl, dispatch]); - return ) : ( - )} + {state === 'eligible' && ( + + )}
); }; diff --git a/app/javascript/mastodon/features/annual_report/announcement/styles.module.scss b/app/javascript/mastodon/features/annual_report/announcement/styles.module.scss index 1c3d033b2bde46..b96ca2e6797396 100644 --- a/app/javascript/mastodon/features/annual_report/announcement/styles.module.scss +++ b/app/javascript/mastodon/features/annual_report/announcement/styles.module.scss @@ -15,6 +15,7 @@ radial-gradient(at 16% 95%, #1e948299 0, transparent 50%) var(--color-bg-primary); border-bottom: 1px solid var(--color-border-primary); + position: relative; h2 { font-size: 20px; @@ -26,4 +27,11 @@ p { margin-bottom: 20px; } + + .closeButton { + position: absolute; + bottom: 8px; + right: 8px; + margin-inline: 0; + } } diff --git a/app/javascript/mastodon/features/annual_report/timeline.tsx b/app/javascript/mastodon/features/annual_report/timeline.tsx index ee46d204031dcb..4280c2a98aa8b4 100644 --- a/app/javascript/mastodon/features/annual_report/timeline.tsx +++ b/app/javascript/mastodon/features/annual_report/timeline.tsx @@ -2,6 +2,7 @@ import { useCallback } from 'react'; import type { FC } from 'react'; import { openModal } from '@/mastodon/actions/modal'; +import { useDismissible } from '@/mastodon/hooks/useDismissible'; import { generateReport, selectWrapstodonYear, @@ -19,21 +20,26 @@ export const AnnualReportTimeline: FC = () => { void dispatch(generateReport()); }, [dispatch]); + const { wasDismissed, dismiss } = useDismissible( + `annual_report_announcement_${year}`, + ); + const handleOpen = useCallback(() => { dispatch(openModal({ modalType: 'ANNUAL_REPORT', modalProps: {} })); - }, [dispatch]); + dismiss(); + }, [dismiss, dispatch]); - if (!year || !state || state === 'ineligible') { + if (!year || wasDismissed || !state || state === 'ineligible') { return null; } return ( ); }; diff --git a/app/javascript/mastodon/features/home_timeline/components/critical_update_banner.tsx b/app/javascript/mastodon/features/home_timeline/components/critical_update_banner.tsx index d0dd2b6acda66f..b57231132f9be3 100644 --- a/app/javascript/mastodon/features/home_timeline/components/critical_update_banner.tsx +++ b/app/javascript/mastodon/features/home_timeline/components/critical_update_banner.tsx @@ -1,26 +1,34 @@ +import type { FC } from 'react'; + import { FormattedMessage } from 'react-intl'; -export const CriticalUpdateBanner = () => ( -
-
-

+import { criticalUpdatesPending } from '@/mastodon/initial_state'; + +export const CriticalUpdateBanner: FC = () => { + if (!criticalUpdatesPending) { + return null; + } + return ( +
+
-

-

- {' '} - +

- -

+ id='home.pending_critical_update.body' + defaultMessage='Please update your Mastodon server as soon as possible!' + />{' '} + + + +

+
-
-); + ); +}; diff --git a/app/javascript/mastodon/features/home_timeline/index.jsx b/app/javascript/mastodon/features/home_timeline/index.jsx index 8c5555fd49e01b..893e2c08cabf38 100644 --- a/app/javascript/mastodon/features/home_timeline/index.jsx +++ b/app/javascript/mastodon/features/home_timeline/index.jsx @@ -15,7 +15,6 @@ import { fetchAnnouncements, toggleShowAnnouncements } from 'mastodon/actions/an import { IconWithBadge } from 'mastodon/components/icon_with_badge'; import { NotSignedInIndicator } from 'mastodon/components/not_signed_in_indicator'; import { identityContextPropShape, withIdentity } from 'mastodon/identity_context'; -import { criticalUpdatesPending } from 'mastodon/initial_state'; import { withBreakpoint } from 'mastodon/features/ui/hooks/useBreakpoint'; import { addColumn, removeColumn, moveColumn } from '../../actions/columns'; @@ -27,6 +26,7 @@ import StatusListContainer from '../ui/containers/status_list_container'; import { ColumnSettings } from './components/column_settings'; import { CriticalUpdateBanner } from './components/critical_update_banner'; import { Announcements } from './components/announcements'; +import { AnnualReportTimeline } from '../annual_report/timeline'; const messages = defineMessages({ title: { id: 'column.home', defaultMessage: 'Home' }, @@ -127,7 +127,10 @@ class HomeTimeline extends PureComponent { const { intl, hasUnread, columnId, multiColumn, hasAnnouncements, unreadAnnouncements, showAnnouncements, matchesBreakpoint } = this.props; const pinned = !!columnId; const { signedIn } = this.props.identity; - const banners = []; + const banners = [ + , + + ]; let announcementsButton; @@ -145,10 +148,6 @@ class HomeTimeline extends PureComponent { ); } - if (criticalUpdatesPending) { - banners.push(); - } - return ( + !!( + state.settings as ImmutableMap< + 'dismissed_banners', + ImmutableMap + > + ).getIn(['dismissed_banners', id], false), + ); + + const wasDismissed = !!bannerSettings.get(id) || dismissed; + + const dispatch = useAppDispatch(); + + const dismiss = useCallback(() => { + bannerSettings.set(id, true); + dispatch(changeSetting(['dismissed_banners', id], true)); + }, [id, dispatch]); + + useEffect(() => { + // Store legacy localStorage setting on server + if (wasDismissed && !dismissed) { + dispatch(changeSetting(['dismissed_banners', id], true)); + } + }, [id, dispatch, wasDismissed, dismissed]); + + return { + wasDismissed, + dismiss, + }; +} diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index 0d46b446a7ab24..e91af0c904905a 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -114,6 +114,7 @@ "alt_text_modal.done": "Done", "announcement.announcement": "Announcement", "annual_report.announcement.action_build": "Build my Wrapstodon", + "annual_report.announcement.action_dismiss": "No thanks", "annual_report.announcement.action_view": "View my Wrapstodon", "annual_report.announcement.description": "Discover more about your engagement on Mastodon over the past year.", "annual_report.announcement.title": "Wrapstodon {year} has arrived", diff --git a/app/javascript/mastodon/reducers/slices/annual_report.ts b/app/javascript/mastodon/reducers/slices/annual_report.ts index 3ad18f8ec1ec06..e242fdbf9a466f 100644 --- a/app/javascript/mastodon/reducers/slices/annual_report.ts +++ b/app/javascript/mastodon/reducers/slices/annual_report.ts @@ -5,8 +5,6 @@ import { importFetchedAccounts, importFetchedStatuses, } from '@/mastodon/actions/importer'; -import { insertIntoTimeline } from '@/mastodon/actions/timelines'; -import { timelineDelete } from '@/mastodon/actions/timelines_typed'; import type { ApiAnnualReportState } from '@/mastodon/api/annual_report'; import { apiGetAnnualReport, @@ -21,8 +19,6 @@ import { createDataLoadingThunk, } from '../../store/typed_functions'; -export const TIMELINE_WRAPSTODON = 'inline-wrapstodon'; - interface AnnualReportState { state?: ApiAnnualReportState; report?: AnnualReport; @@ -64,37 +60,12 @@ export const selectWrapstodonYear = createAppSelector( // This kicks everything off, and is called after fetching the server info. export const checkAnnualReport = createAppThunk( `${annualReportSlice.name}/checkAnnualReport`, - async (_arg: unknown, { dispatch, getState }) => { + (_arg: unknown, { dispatch, getState }) => { const year = selectWrapstodonYear(getState()); if (!year) { return; } - const state = await dispatch(fetchReportState()); - if ( - state.meta.requestStatus === 'fulfilled' && - state.payload !== 'ineligible' - ) { - dispatch(insertIntoTimeline('home', TIMELINE_WRAPSTODON, 1)); - } - }, -); - -export const reinsertAnnualReport = createAppThunk( - `${annualReportSlice.name}/reinsertAnnualReport`, - (_arg: unknown, { dispatch, getState }) => { - dispatch( - timelineDelete({ - statusId: TIMELINE_WRAPSTODON, - accountId: '', - references: [], - reblogOf: null, - }), - ); - const { state } = getState().annualReport; - if (!state || state === 'ineligible') { - return; - } - dispatch(insertIntoTimeline('home', TIMELINE_WRAPSTODON, 1)); + void dispatch(fetchReportState()); }, ); diff --git a/app/javascript/mastodon/utils/types.ts b/app/javascript/mastodon/utils/types.ts index 24b9ee180f17fe..eb45881ee47ca8 100644 --- a/app/javascript/mastodon/utils/types.ts +++ b/app/javascript/mastodon/utils/types.ts @@ -14,3 +14,9 @@ export type SomeRequired = T & Required>; export type SomeOptional = Pick> & Partial>; + +export type OmitValueType = { + [K in keyof T as T[K] extends V ? never : K]: T[K]; +}; + +export type AnyFunction = (...args: never) => unknown; From 571c93c563e81cbb838d74fe45dda37f3b18a254 Mon Sep 17 00:00:00 2001 From: diondiondion Date: Fri, 12 Dec 2025 10:43:34 +0100 Subject: [PATCH 756/853] Change Wrapstodon 'About' link to point to joinmastodon.org (#37216) --- .../mastodon/features/annual_report/shared_page.tsx | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/app/javascript/mastodon/features/annual_report/shared_page.tsx b/app/javascript/mastodon/features/annual_report/shared_page.tsx index ebf01da7f1d39b..7884890cc75cc8 100644 --- a/app/javascript/mastodon/features/annual_report/shared_page.tsx +++ b/app/javascript/mastodon/features/annual_report/shared_page.tsx @@ -20,11 +20,8 @@ export const WrapstodonSharedPage: FC = () => { values={{ heart: '♥' }} />
); }; diff --git a/app/javascript/mastodon/features/annual_report/nav_item.tsx b/app/javascript/mastodon/features/annual_report/nav_item.tsx new file mode 100644 index 00000000000000..bc293a794777e5 --- /dev/null +++ b/app/javascript/mastodon/features/annual_report/nav_item.tsx @@ -0,0 +1,55 @@ +import { useCallback } from 'react'; +import type { FC } from 'react'; + +import { FormattedMessage } from 'react-intl'; + +import classNames from 'classnames'; + +import IconPlanet from '@/images/icons/icon_planet.svg?react'; +import { openModal } from '@/mastodon/actions/modal'; +import { Icon } from '@/mastodon/components/icon'; +import { selectWrapstodonYear } from '@/mastodon/reducers/slices/annual_report'; +import { + createAppSelector, + useAppDispatch, + useAppSelector, +} from '@/mastodon/store'; + +import classes from './index.module.scss'; + +const selectReportModalOpen = createAppSelector( + [(state) => state.modal.getIn(['stack', 0, 'modalType'])], + (modalType) => modalType === 'ANNUAL_REPORT', +); + +export const AnnualReportNavItem: FC = () => { + const { state } = useAppSelector((state) => state.annualReport); + const year = useAppSelector(selectWrapstodonYear); + const active = useAppSelector(selectReportModalOpen); + + const dispatch = useAppDispatch(); + const handleClick = useCallback(() => { + dispatch(openModal({ modalType: 'ANNUAL_REPORT', modalProps: {} })); + }, [dispatch]); + + if (!year || !state || state === 'ineligible') { + return null; + } + + return ( + + ); +}; diff --git a/app/javascript/mastodon/features/navigation_panel/index.tsx b/app/javascript/mastodon/features/navigation_panel/index.tsx index 5b5af7a4e580dc..0dbe94cc21e415 100644 --- a/app/javascript/mastodon/features/navigation_panel/index.tsx +++ b/app/javascript/mastodon/features/navigation_panel/index.tsx @@ -46,6 +46,8 @@ import { canViewFeed } from 'mastodon/permissions'; import { selectUnreadNotificationGroupsCount } from 'mastodon/selectors/notifications'; import { useAppSelector, useAppDispatch } from 'mastodon/store'; +import { AnnualReportNavItem } from '../annual_report/nav_item'; + import { DisabledAccountBanner } from './components/disabled_account_banner'; import { FollowedTagsPanel } from './components/followed_tags_panel'; import { ListPanel } from './components/list_panel'; @@ -294,6 +296,8 @@ export const NavigationPanel: React.FC<{ multiColumn?: boolean }> = ({ + +
diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index e91af0c904905a..b4ea6dbeb9396e 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -118,6 +118,7 @@ "annual_report.announcement.action_view": "View my Wrapstodon", "annual_report.announcement.description": "Discover more about your engagement on Mastodon over the past year.", "annual_report.announcement.title": "Wrapstodon {year} has arrived", + "annual_report.nav_item.badge": "New", "annual_report.shared_page.donate": "Donate", "annual_report.shared_page.footer": "Generated with {heart} by the Mastodon team", "annual_report.shared_page.sign_up": "Sign up", diff --git a/stylelint.config.js b/stylelint.config.js index b1f34b7f19061b..9ccee477484b60 100644 --- a/stylelint.config.js +++ b/stylelint.config.js @@ -31,7 +31,7 @@ module.exports = { }, overrides: [ { - 'files': ['app/javascript/styles/entrypoints/mailer.scss'], + files: ['app/javascript/styles/entrypoints/mailer.scss'], rules: { 'property-no-unknown': [ true, @@ -42,5 +42,14 @@ module.exports = { ], }, }, + { + files: ['app/javascript/**/*.module.scss'], + rules: { + 'selector-pseudo-class-no-unknown': [ + true, + { ignorePseudoClasses: ['global'] }, + ] + } + }, ], }; From 8748f0812d17eb602eefca840d134d1da7a9b9ab Mon Sep 17 00:00:00 2001 From: diondiondion Date: Fri, 12 Dec 2025 11:20:32 +0100 Subject: [PATCH 758/853] Convert Settings class to TS (#37218) --- app/javascript/mastodon/actions/search.ts | 2 +- .../mastodon/features/audio/index.tsx | 4 +- app/javascript/mastodon/settings.js | 51 --------------- app/javascript/mastodon/settings.ts | 65 +++++++++++++++++++ 4 files changed, 68 insertions(+), 54 deletions(-) delete mode 100644 app/javascript/mastodon/settings.js create mode 100644 app/javascript/mastodon/settings.ts diff --git a/app/javascript/mastodon/actions/search.ts b/app/javascript/mastodon/actions/search.ts index 1e57c307157d41..4f21a53b4d8230 100644 --- a/app/javascript/mastodon/actions/search.ts +++ b/app/javascript/mastodon/actions/search.ts @@ -144,7 +144,7 @@ export const hydrateSearch = createAppAsyncThunk( 'search/hydrate', (_args, { dispatch, getState }) => { const me = getState().meta.get('me') as string; - const history = searchHistory.get(me) as RecentSearch[] | null; + const history = searchHistory.get(me); if (history !== null) { dispatch(updateSearchHistory(history)); diff --git a/app/javascript/mastodon/features/audio/index.tsx b/app/javascript/mastodon/features/audio/index.tsx index c16fd9eab15a0d..fa0d976377cc30 100644 --- a/app/javascript/mastodon/features/audio/index.tsx +++ b/app/javascript/mastodon/features/audio/index.tsx @@ -41,8 +41,8 @@ const persistVolume = (volume: number, muted: boolean) => { }; const restoreVolume = (audio: HTMLAudioElement) => { - const volume = (playerSettings.get('volume') as number | undefined) ?? 0.5; - const muted = (playerSettings.get('muted') as boolean | undefined) ?? false; + const volume = playerSettings.get('volume') ?? 0.5; + const muted = playerSettings.get('muted') ?? false; audio.volume = volume; audio.muted = muted; diff --git a/app/javascript/mastodon/settings.js b/app/javascript/mastodon/settings.js deleted file mode 100644 index f4883dc406cdb5..00000000000000 --- a/app/javascript/mastodon/settings.js +++ /dev/null @@ -1,51 +0,0 @@ -export default class Settings { - - constructor(keyBase = null) { - this.keyBase = keyBase; - } - - generateKey(id) { - return this.keyBase ? [this.keyBase, `id${id}`].join('.') : id; - } - - set(id, data) { - const key = this.generateKey(id); - try { - const encodedData = JSON.stringify(data); - localStorage.setItem(key, encodedData); - return data; - } catch { - return null; - } - } - - get(id) { - const key = this.generateKey(id); - try { - const rawData = localStorage.getItem(key); - return JSON.parse(rawData); - } catch { - return null; - } - } - - remove(id) { - const data = this.get(id); - if (data) { - const key = this.generateKey(id); - try { - localStorage.removeItem(key); - } catch { - // ignore if the key is not found - } - } - return data; - } - -} - -export const pushNotificationsSetting = new Settings('mastodon_push_notification_data'); -export const tagHistory = new Settings('mastodon_tag_history'); -export const bannerSettings = new Settings('mastodon_banner_settings'); -export const searchHistory = new Settings('mastodon_search_history'); -export const playerSettings = new Settings('mastodon_player'); diff --git a/app/javascript/mastodon/settings.ts b/app/javascript/mastodon/settings.ts new file mode 100644 index 00000000000000..24bf1a257379ec --- /dev/null +++ b/app/javascript/mastodon/settings.ts @@ -0,0 +1,65 @@ +import type { RecentSearch } from './models/search'; + +export class Settings> { + keyBase: string | null; + + constructor(keyBase: string | null = null) { + this.keyBase = keyBase; + } + + private generateKey(id: string | number | symbol): string { + const idStr = typeof id === 'string' ? id : String(id); + return this.keyBase ? [this.keyBase, `id${idStr}`].join('.') : idStr; + } + + set(id: K, data: T[K]): T[K] | null { + const key = this.generateKey(id); + try { + const encodedData = JSON.stringify(data); + localStorage.setItem(key, encodedData); + return data; + } catch { + return null; + } + } + + get(id: K): T[K] | null { + const key = this.generateKey(id); + try { + const rawData = localStorage.getItem(key); + if (rawData === null) return null; + return JSON.parse(rawData) as T[K]; + } catch { + return null; + } + } + + remove(id: K): T[K] | null { + const data = this.get(id); + if (data !== null) { + const key = this.generateKey(id); + try { + localStorage.removeItem(key); + } catch { + // ignore if the key is not found + } + } + return data; + } +} + +export const pushNotificationsSetting = new Settings< + Record +>('mastodon_push_notification_data'); +export const tagHistory = new Settings>( + 'mastodon_tag_history', +); +export const bannerSettings = new Settings>( + 'mastodon_banner_settings', +); +export const searchHistory = new Settings>( + 'mastodon_search_history', +); +export const playerSettings = new Settings<{ volume: number; muted: boolean }>( + 'mastodon_player', +); From b72b5075848e65cb7eebb5e64ece59ed0e77be57 Mon Sep 17 00:00:00 2001 From: diondiondion Date: Fri, 12 Dec 2025 12:03:00 +0100 Subject: [PATCH 759/853] Remember revealed archetype on future Wrapstodon visits (#37219) --- .../mastodon/features/annual_report/archetype.tsx | 11 ++++++++++- app/javascript/mastodon/features/video/index.tsx | 4 ++-- app/javascript/mastodon/settings.ts | 3 +++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/app/javascript/mastodon/features/annual_report/archetype.tsx b/app/javascript/mastodon/features/annual_report/archetype.tsx index 660a1cf29dcfa6..56eef212bb912e 100644 --- a/app/javascript/mastodon/features/annual_report/archetype.tsx +++ b/app/javascript/mastodon/features/annual_report/archetype.tsx @@ -12,11 +12,13 @@ import replier from '@/images/archetypes/replier.png'; import space_elements from '@/images/archetypes/space_elements.png'; import { Avatar } from '@/mastodon/components/avatar'; import { Button } from '@/mastodon/components/button'; +import { me } from '@/mastodon/initial_state'; import type { Account } from '@/mastodon/models/account'; import type { AnnualReport, Archetype as ArchetypeData, } from '@/mastodon/models/annual_report'; +import { wrapstodonSettings } from '@/mastodon/settings'; import styles from './index.module.scss'; import { ShareButton } from './share_button'; @@ -117,9 +119,16 @@ export const Archetype: React.FC<{ const wrapperRef = useRef(null); const isSelfView = context === 'modal'; - const [isRevealed, setIsRevealed] = useState(!isSelfView); + const [isRevealed, setIsRevealed] = useState( + () => + !isSelfView || + (me ? (wrapstodonSettings.get(me)?.archetypeRevealed ?? false) : true), + ); const reveal = useCallback(() => { setIsRevealed(true); + if (me) { + wrapstodonSettings.set(me, { archetypeRevealed: true }); + } wrapperRef.current?.focus(); }, []); diff --git a/app/javascript/mastodon/features/video/index.tsx b/app/javascript/mastodon/features/video/index.tsx index aa03e3d2e9d7eb..6721b5c96a281f 100644 --- a/app/javascript/mastodon/features/video/index.tsx +++ b/app/javascript/mastodon/features/video/index.tsx @@ -139,8 +139,8 @@ const persistVolume = (volume: number, muted: boolean) => { }; const restoreVolume = (video: HTMLVideoElement) => { - const volume = (playerSettings.get('volume') as number | undefined) ?? 0.5; - const muted = (playerSettings.get('muted') as boolean | undefined) ?? false; + const volume = playerSettings.get('volume') ?? 0.5; + const muted = playerSettings.get('muted') ?? false; video.volume = volume; video.muted = muted; diff --git a/app/javascript/mastodon/settings.ts b/app/javascript/mastodon/settings.ts index 24bf1a257379ec..87c67a6e04a466 100644 --- a/app/javascript/mastodon/settings.ts +++ b/app/javascript/mastodon/settings.ts @@ -63,3 +63,6 @@ export const searchHistory = new Settings>( export const playerSettings = new Settings<{ volume: number; muted: boolean }>( 'mastodon_player', ); +export const wrapstodonSettings = new Settings< + Record +>('wrapstodon'); From 1e67567d8fc07d7830ad1464fd359730106a1357 Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 12 Dec 2025 13:42:43 +0100 Subject: [PATCH 760/853] Change HTTP Signature verification status from 401 to 503 on temporary failure to get remote actor (#37221) --- app/controllers/concerns/signature_verification.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/controllers/concerns/signature_verification.rb b/app/controllers/concerns/signature_verification.rb index 2bdd3558643526..1e83ab9c69b6b7 100644 --- a/app/controllers/concerns/signature_verification.rb +++ b/app/controllers/concerns/signature_verification.rb @@ -72,10 +72,13 @@ def signed_request_actor rescue Mastodon::SignatureVerificationError => e fail_with! e.message rescue *Mastodon::HTTP_CONNECTION_ERRORS => e + @signature_verification_failure_code ||= 503 fail_with! "Failed to fetch remote data: #{e.message}" rescue Mastodon::UnexpectedResponseError + @signature_verification_failure_code ||= 503 fail_with! 'Failed to fetch remote data (got unexpected reply from server)' rescue Stoplight::Error::RedLight + @signature_verification_failure_code ||= 503 fail_with! 'Fetching attempt skipped because of recent connection failure' end From 3cc4b59b41bf296cf4e92190f6b66eecfb2b82ce Mon Sep 17 00:00:00 2001 From: David Roetzel Date: Fri, 12 Dec 2025 14:09:55 +0100 Subject: [PATCH 761/853] First draft of API to add items to a collection (#37222) --- .../v1_alpha/collection_items_controller.rb | 41 ++++++++++++++ .../rest/collection_item_serializer.rb | 6 +- config/routes/api.rb | 4 +- .../api/v1_alpha/collection_items_spec.rb | 55 +++++++++++++++++++ .../rest/collection_item_serializer_spec.rb | 2 + 5 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 app/controllers/api/v1_alpha/collection_items_controller.rb create mode 100644 spec/requests/api/v1_alpha/collection_items_spec.rb diff --git a/app/controllers/api/v1_alpha/collection_items_controller.rb b/app/controllers/api/v1_alpha/collection_items_controller.rb new file mode 100644 index 00000000000000..cc2e5cdef12d74 --- /dev/null +++ b/app/controllers/api/v1_alpha/collection_items_controller.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +class Api::V1Alpha::CollectionItemsController < Api::BaseController + include Authorization + + before_action :check_feature_enabled + + before_action -> { doorkeeper_authorize! :write, :'write:collections' } + + before_action :require_user! + + before_action :set_collection + before_action :set_account, only: [:create] + + after_action :verify_authorized + + def create + authorize @collection, :update? + authorize @account, :feature? + + @item = AddAccountToCollectionService.new.call(@collection, @account) + + render json: @item, serializer: REST::CollectionItemSerializer + end + + private + + def set_collection + @collection = Collection.find(params[:collection_id]) + end + + def set_account + return render(json: { error: '`account_id` parameter is missing' }, status: 422) if params[:account_id].blank? + + @account = Account.find(params[:account_id]) + end + + def check_feature_enabled + raise ActionController::RoutingError unless Mastodon::Feature.collections_enabled? + end +end diff --git a/app/serializers/rest/collection_item_serializer.rb b/app/serializers/rest/collection_item_serializer.rb index c0acc87bfd4e02..d35a8fdef28622 100644 --- a/app/serializers/rest/collection_item_serializer.rb +++ b/app/serializers/rest/collection_item_serializer.rb @@ -3,7 +3,11 @@ class REST::CollectionItemSerializer < ActiveModel::Serializer delegate :accepted?, to: :object - attributes :position, :state + attributes :id, :position, :state belongs_to :account, serializer: REST::AccountSerializer, if: :accepted? + + def id + object.id.to_s + end end diff --git a/config/routes/api.rb b/config/routes/api.rb index ad58e8744fa87e..563191614c6079 100644 --- a/config/routes/api.rb +++ b/config/routes/api.rb @@ -12,7 +12,9 @@ resources :async_refreshes, only: :show - resources :collections, only: [:show, :create, :update, :destroy] + resources :collections, only: [:show, :create, :update, :destroy] do + resources :items, only: [:create], controller: 'collection_items' + end end # JSON / REST API diff --git a/spec/requests/api/v1_alpha/collection_items_spec.rb b/spec/requests/api/v1_alpha/collection_items_spec.rb new file mode 100644 index 00000000000000..880fd5d47d1b0b --- /dev/null +++ b/spec/requests/api/v1_alpha/collection_items_spec.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Api::V1Alpha::CollectionItems', feature: :collections do + include_context 'with API authentication', oauth_scopes: 'read:collections write:collections' + + describe 'POST /api/v1_alpha/collections/:collection_id/items' do + subject do + post "/api/v1_alpha/collections/#{collection.id}/items", headers: headers, params: params + end + + let(:collection) { Fabricate(:collection, account: user.account) } + let(:params) { {} } + + it_behaves_like 'forbidden for wrong scope', 'read' + + context 'when user is owner of the collection' do + context 'with valid params' do + let(:other_account) { Fabricate(:account) } + let(:params) { { account_id: other_account.id } } + + it 'creates a collection item and returns http success' do + expect do + subject + end.to change(collection.collection_items, :count).by(1) + + expect(response).to have_http_status(200) + end + end + + context 'with invalid params' do + it 'returns http unprocessable content' do + expect do + subject + end.to_not change(CollectionItem, :count) + + expect(response).to have_http_status(422) + end + end + end + + context 'when user is not the owner of the collection' do + let(:collection) { Fabricate(:collection) } + let(:other_account) { Fabricate(:account) } + let(:params) { { account_id: other_account.id } } + + it 'returns http forbidden' do + subject + + expect(response).to have_http_status(403) + end + end + end +end diff --git a/spec/serializers/rest/collection_item_serializer_spec.rb b/spec/serializers/rest/collection_item_serializer_spec.rb index bcb7458c4de259..b12553ec034b8c 100644 --- a/spec/serializers/rest/collection_item_serializer_spec.rb +++ b/spec/serializers/rest/collection_item_serializer_spec.rb @@ -7,6 +7,7 @@ let(:collection_item) do Fabricate(:collection_item, + id: 2342, state:, position: 4) end @@ -17,6 +18,7 @@ it 'includes the relevant attributes including the account' do expect(subject) .to include( + 'id' => '2342', 'account' => an_instance_of(Hash), 'state' => 'accepted', 'position' => 4 From 6821b707960e2f0a639069665865b08df8bc672f Mon Sep 17 00:00:00 2001 From: diondiondion Date: Fri, 12 Dec 2025 14:39:56 +0100 Subject: [PATCH 762/853] Add secondary Wrapstodon share button (#37224) --- .../features/annual_report/index.module.scss | 15 +++++- .../features/annual_report/share_button.tsx | 48 +++++++++++++++++-- app/javascript/mastodon/locales/en.json | 2 + 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/app/javascript/mastodon/features/annual_report/index.module.scss b/app/javascript/mastodon/features/annual_report/index.module.scss index 375b2e211e70b4..024518d72f75fe 100644 --- a/app/javascript/mastodon/features/annual_report/index.module.scss +++ b/app/javascript/mastodon/features/annual_report/index.module.scss @@ -174,7 +174,7 @@ $mobile-breakpoint: 540px; .title { text-transform: uppercase; - color: #c2c8ff; + color: var(--color-text-brand-soft); font-weight: 500; &:last-child { @@ -333,6 +333,19 @@ $mobile-breakpoint: 540px; mix-blend-mode: screen; } +.shareButtonWrapper { + display: flex; + flex-direction: column; + gap: 10px; +} + +.secondaryShareButton { + // Extra selector is needed to override color + &:global(.button) { + color: var(--color-text-primary); + } +} + .navItemBadge { background: var(--color-bg-brand-soft); } diff --git a/app/javascript/mastodon/features/annual_report/share_button.tsx b/app/javascript/mastodon/features/annual_report/share_button.tsx index 80c2809adf2a93..16dd834f4a17e0 100644 --- a/app/javascript/mastodon/features/annual_report/share_button.tsx +++ b/app/javascript/mastodon/features/annual_report/share_button.tsx @@ -3,6 +3,7 @@ import type { FC } from 'react'; import { defineMessages, useIntl } from 'react-intl'; +import { showAlert } from '@/mastodon/actions/alerts'; import { resetCompose, focusCompose } from '@/mastodon/actions/compose'; import { closeModal } from '@/mastodon/actions/modal'; import { Button } from '@/mastodon/components/button'; @@ -10,6 +11,7 @@ import type { AnnualReport as AnnualReportData } from '@/mastodon/models/annual_ import { useAppDispatch } from '@/mastodon/store'; import { archetypeNames } from './archetype'; +import styles from './index.module.scss'; const messages = defineMessages({ share_message: { @@ -20,11 +22,24 @@ const messages = defineMessages({ id: 'annual_report.summary.share_on_mastodon', defaultMessage: 'Share on Mastodon', }, + share_elsewhere: { + id: 'annual_report.summary.share_elsewhere', + defaultMessage: 'Share elsewhere', + }, + copy_link: { + id: 'annual_report.summary.copy_link', + defaultMessage: 'Copy link', + }, + copied: { + id: 'copy_icon_button.copied', + defaultMessage: 'Copied to clipboard', + }, }); export const ShareButton: FC<{ report: AnnualReportData }> = ({ report }) => { const intl = useIntl(); const dispatch = useAppDispatch(); + const handleShareClick = useCallback(() => { // Generate the share message. const archetypeName = intl.formatMessage( @@ -47,10 +62,35 @@ export const ShareButton: FC<{ report: AnnualReportData }> = ({ report }) => { dispatch(closeModal({ modalType: 'ANNUAL_REPORT', ignoreFocus: false })); }, [report, intl, dispatch]); + const supportsNativeShare = 'share' in navigator; + + const handleSecondaryShare = useCallback(() => { + if (report.schema_version === 2 && report.share_url) { + if (supportsNativeShare) { + void navigator.share({ + url: report.share_url, + }); + } else { + void navigator.clipboard.writeText(report.share_url); + dispatch(showAlert({ message: messages.copied })); + } + } + }, [report, supportsNativeShare, dispatch]); + return ( -
); }; diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index b4ea6dbeb9396e..bafbb3fafdac73 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -143,6 +143,7 @@ "annual_report.summary.archetype.title_public": "{name}'s archetype", "annual_report.summary.archetype.title_self": "Your archetype", "annual_report.summary.close": "Close", + "annual_report.summary.copy_link": "Copy link", "annual_report.summary.followers.new_followers": "{count, plural, one {new follower} other {new followers}}", "annual_report.summary.highlighted_post.boost_count": "This post was boosted {count, plural, one {once} other {# times}}.", "annual_report.summary.highlighted_post.favourite_count": "This post was favorited {count, plural, one {once} other {# times}}.", @@ -155,6 +156,7 @@ "annual_report.summary.new_posts.new_posts": "new posts", "annual_report.summary.percentile.text": "That puts you in the topof {domain} users.", "annual_report.summary.percentile.we_wont_tell_bernie": "We won't tell Bernie.", + "annual_report.summary.share_elsewhere": "Share elsewhere", "annual_report.summary.share_message": "I got the {archetype} archetype!", "annual_report.summary.share_on_mastodon": "Share on Mastodon", "attachments_list.unprocessed": "(unprocessed)", From 861202fd080d9a7db0e478d14df79ed317dcf501 Mon Sep 17 00:00:00 2001 From: diondiondion Date: Fri, 12 Dec 2025 15:31:21 +0100 Subject: [PATCH 763/853] =?UTF-8?q?Change=20Emoji=20in=20Wrapstodon=20foot?= =?UTF-8?q?er=20=F0=9F=90=98=20(#37226)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/javascript/mastodon/features/annual_report/shared_page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/mastodon/features/annual_report/shared_page.tsx b/app/javascript/mastodon/features/annual_report/shared_page.tsx index 7884890cc75cc8..c69a05e5af102f 100644 --- a/app/javascript/mastodon/features/annual_report/shared_page.tsx +++ b/app/javascript/mastodon/features/annual_report/shared_page.tsx @@ -17,7 +17,7 @@ export const WrapstodonSharedPage: FC = () => {
); }; diff --git a/app/javascript/flavours/glitch/features/annual_report/nav_item.tsx b/app/javascript/flavours/glitch/features/annual_report/nav_item.tsx new file mode 100644 index 00000000000000..f67b99f01ad6c6 --- /dev/null +++ b/app/javascript/flavours/glitch/features/annual_report/nav_item.tsx @@ -0,0 +1,55 @@ +import { useCallback } from 'react'; +import type { FC } from 'react'; + +import { FormattedMessage } from 'react-intl'; + +import classNames from 'classnames'; + +import { openModal } from '@/flavours/glitch/actions/modal'; +import { Icon } from '@/flavours/glitch/components/icon'; +import { selectWrapstodonYear } from '@/flavours/glitch/reducers/slices/annual_report'; +import { + createAppSelector, + useAppDispatch, + useAppSelector, +} from '@/flavours/glitch/store'; +import IconPlanet from '@/images/icons/icon_planet.svg?react'; + +import classes from './index.module.scss'; + +const selectReportModalOpen = createAppSelector( + [(state) => state.modal.getIn(['stack', 0, 'modalType'])], + (modalType) => modalType === 'ANNUAL_REPORT', +); + +export const AnnualReportNavItem: FC = () => { + const { state } = useAppSelector((state) => state.annualReport); + const year = useAppSelector(selectWrapstodonYear); + const active = useAppSelector(selectReportModalOpen); + + const dispatch = useAppDispatch(); + const handleClick = useCallback(() => { + dispatch(openModal({ modalType: 'ANNUAL_REPORT', modalProps: {} })); + }, [dispatch]); + + if (!year || !state || state === 'ineligible') { + return null; + } + + return ( + + ); +}; diff --git a/app/javascript/flavours/glitch/features/navigation_panel/index.tsx b/app/javascript/flavours/glitch/features/navigation_panel/index.tsx index a14316df6e125e..bc19e20b5a739f 100644 --- a/app/javascript/flavours/glitch/features/navigation_panel/index.tsx +++ b/app/javascript/flavours/glitch/features/navigation_panel/index.tsx @@ -51,6 +51,8 @@ import { canViewFeed } from 'flavours/glitch/permissions'; import { selectUnreadNotificationGroupsCount } from 'flavours/glitch/selectors/notifications'; import { useAppSelector, useAppDispatch } from 'flavours/glitch/store'; +import { AnnualReportNavItem } from '../annual_report/nav_item'; + import { DisabledAccountBanner } from './components/disabled_account_banner'; import { FollowedTagsPanel } from './components/followed_tags_panel'; import { ListPanel } from './components/list_panel'; @@ -318,6 +320,8 @@ export const NavigationPanel: React.FC<{ multiColumn?: boolean }> = ({ + +
From 8fad8681abb0c59d14ad484505e450df23ffa6b3 Mon Sep 17 00:00:00 2001 From: diondiondion Date: Fri, 12 Dec 2025 11:20:32 +0100 Subject: [PATCH 768/853] [Glitch] Convert Settings class to TS Port 8748f0812d17eb602eefca840d134d1da7a9b9ab to glitch-soc Signed-off-by: Claire --- .../flavours/glitch/actions/search.ts | 2 +- .../flavours/glitch/features/audio/index.tsx | 4 +- app/javascript/flavours/glitch/settings.js | 51 --------------- app/javascript/flavours/glitch/settings.ts | 65 +++++++++++++++++++ 4 files changed, 68 insertions(+), 54 deletions(-) delete mode 100644 app/javascript/flavours/glitch/settings.js create mode 100644 app/javascript/flavours/glitch/settings.ts diff --git a/app/javascript/flavours/glitch/actions/search.ts b/app/javascript/flavours/glitch/actions/search.ts index d0c3e01c7701b2..ba11d8e79e88cf 100644 --- a/app/javascript/flavours/glitch/actions/search.ts +++ b/app/javascript/flavours/glitch/actions/search.ts @@ -147,7 +147,7 @@ export const hydrateSearch = createAppAsyncThunk( 'search/hydrate', (_args, { dispatch, getState }) => { const me = getState().meta.get('me') as string; - const history = searchHistory.get(me) as RecentSearch[] | null; + const history = searchHistory.get(me); if (history !== null) { dispatch(updateSearchHistory(history)); diff --git a/app/javascript/flavours/glitch/features/audio/index.tsx b/app/javascript/flavours/glitch/features/audio/index.tsx index be26c9eeb269fe..0a1a054bdd88d1 100644 --- a/app/javascript/flavours/glitch/features/audio/index.tsx +++ b/app/javascript/flavours/glitch/features/audio/index.tsx @@ -41,8 +41,8 @@ const persistVolume = (volume: number, muted: boolean) => { }; const restoreVolume = (audio: HTMLAudioElement) => { - const volume = (playerSettings.get('volume') as number | undefined) ?? 0.5; - const muted = (playerSettings.get('muted') as boolean | undefined) ?? false; + const volume = playerSettings.get('volume') ?? 0.5; + const muted = playerSettings.get('muted') ?? false; audio.volume = volume; audio.muted = muted; diff --git a/app/javascript/flavours/glitch/settings.js b/app/javascript/flavours/glitch/settings.js deleted file mode 100644 index f4883dc406cdb5..00000000000000 --- a/app/javascript/flavours/glitch/settings.js +++ /dev/null @@ -1,51 +0,0 @@ -export default class Settings { - - constructor(keyBase = null) { - this.keyBase = keyBase; - } - - generateKey(id) { - return this.keyBase ? [this.keyBase, `id${id}`].join('.') : id; - } - - set(id, data) { - const key = this.generateKey(id); - try { - const encodedData = JSON.stringify(data); - localStorage.setItem(key, encodedData); - return data; - } catch { - return null; - } - } - - get(id) { - const key = this.generateKey(id); - try { - const rawData = localStorage.getItem(key); - return JSON.parse(rawData); - } catch { - return null; - } - } - - remove(id) { - const data = this.get(id); - if (data) { - const key = this.generateKey(id); - try { - localStorage.removeItem(key); - } catch { - // ignore if the key is not found - } - } - return data; - } - -} - -export const pushNotificationsSetting = new Settings('mastodon_push_notification_data'); -export const tagHistory = new Settings('mastodon_tag_history'); -export const bannerSettings = new Settings('mastodon_banner_settings'); -export const searchHistory = new Settings('mastodon_search_history'); -export const playerSettings = new Settings('mastodon_player'); diff --git a/app/javascript/flavours/glitch/settings.ts b/app/javascript/flavours/glitch/settings.ts new file mode 100644 index 00000000000000..24bf1a257379ec --- /dev/null +++ b/app/javascript/flavours/glitch/settings.ts @@ -0,0 +1,65 @@ +import type { RecentSearch } from './models/search'; + +export class Settings> { + keyBase: string | null; + + constructor(keyBase: string | null = null) { + this.keyBase = keyBase; + } + + private generateKey(id: string | number | symbol): string { + const idStr = typeof id === 'string' ? id : String(id); + return this.keyBase ? [this.keyBase, `id${idStr}`].join('.') : idStr; + } + + set(id: K, data: T[K]): T[K] | null { + const key = this.generateKey(id); + try { + const encodedData = JSON.stringify(data); + localStorage.setItem(key, encodedData); + return data; + } catch { + return null; + } + } + + get(id: K): T[K] | null { + const key = this.generateKey(id); + try { + const rawData = localStorage.getItem(key); + if (rawData === null) return null; + return JSON.parse(rawData) as T[K]; + } catch { + return null; + } + } + + remove(id: K): T[K] | null { + const data = this.get(id); + if (data !== null) { + const key = this.generateKey(id); + try { + localStorage.removeItem(key); + } catch { + // ignore if the key is not found + } + } + return data; + } +} + +export const pushNotificationsSetting = new Settings< + Record +>('mastodon_push_notification_data'); +export const tagHistory = new Settings>( + 'mastodon_tag_history', +); +export const bannerSettings = new Settings>( + 'mastodon_banner_settings', +); +export const searchHistory = new Settings>( + 'mastodon_search_history', +); +export const playerSettings = new Settings<{ volume: number; muted: boolean }>( + 'mastodon_player', +); From acf583d37425eabdd8c6bd5d77441243b1af369f Mon Sep 17 00:00:00 2001 From: diondiondion Date: Fri, 12 Dec 2025 12:03:00 +0100 Subject: [PATCH 769/853] [Glitch] Remember revealed archetype on future Wrapstodon visits Port b72b5075848e65cb7eebb5e64ece59ed0e77be57 to glitch-soc Signed-off-by: Claire --- .../glitch/features/annual_report/archetype.tsx | 11 ++++++++++- .../flavours/glitch/features/video/index.tsx | 4 ++-- app/javascript/flavours/glitch/settings.ts | 3 +++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/app/javascript/flavours/glitch/features/annual_report/archetype.tsx b/app/javascript/flavours/glitch/features/annual_report/archetype.tsx index eb2119009ec4f4..297e12cda80ae6 100644 --- a/app/javascript/flavours/glitch/features/annual_report/archetype.tsx +++ b/app/javascript/flavours/glitch/features/annual_report/archetype.tsx @@ -6,11 +6,13 @@ import classNames from 'classnames'; import { Avatar } from '@/flavours/glitch/components/avatar'; import { Button } from '@/flavours/glitch/components/button'; +import { me } from '@/flavours/glitch/initial_state'; import type { Account } from '@/flavours/glitch/models/account'; import type { AnnualReport, Archetype as ArchetypeData, } from '@/flavours/glitch/models/annual_report'; +import { wrapstodonSettings } from '@/flavours/glitch/settings'; import booster from '@/images/archetypes/booster.png'; import lurker from '@/images/archetypes/lurker.png'; import oracle from '@/images/archetypes/oracle.png'; @@ -117,9 +119,16 @@ export const Archetype: React.FC<{ const wrapperRef = useRef(null); const isSelfView = context === 'modal'; - const [isRevealed, setIsRevealed] = useState(!isSelfView); + const [isRevealed, setIsRevealed] = useState( + () => + !isSelfView || + (me ? (wrapstodonSettings.get(me)?.archetypeRevealed ?? false) : true), + ); const reveal = useCallback(() => { setIsRevealed(true); + if (me) { + wrapstodonSettings.set(me, { archetypeRevealed: true }); + } wrapperRef.current?.focus(); }, []); diff --git a/app/javascript/flavours/glitch/features/video/index.tsx b/app/javascript/flavours/glitch/features/video/index.tsx index 522995881869c0..b43bfae7032d30 100644 --- a/app/javascript/flavours/glitch/features/video/index.tsx +++ b/app/javascript/flavours/glitch/features/video/index.tsx @@ -139,8 +139,8 @@ const persistVolume = (volume: number, muted: boolean) => { }; const restoreVolume = (video: HTMLVideoElement) => { - const volume = (playerSettings.get('volume') as number | undefined) ?? 0.5; - const muted = (playerSettings.get('muted') as boolean | undefined) ?? false; + const volume = playerSettings.get('volume') ?? 0.5; + const muted = playerSettings.get('muted') ?? false; video.volume = volume; video.muted = muted; diff --git a/app/javascript/flavours/glitch/settings.ts b/app/javascript/flavours/glitch/settings.ts index 24bf1a257379ec..87c67a6e04a466 100644 --- a/app/javascript/flavours/glitch/settings.ts +++ b/app/javascript/flavours/glitch/settings.ts @@ -63,3 +63,6 @@ export const searchHistory = new Settings>( export const playerSettings = new Settings<{ volume: number; muted: boolean }>( 'mastodon_player', ); +export const wrapstodonSettings = new Settings< + Record +>('wrapstodon'); From cb1d1e289e93e1da761586f20330ee1d8ce08044 Mon Sep 17 00:00:00 2001 From: diondiondion Date: Fri, 12 Dec 2025 14:39:56 +0100 Subject: [PATCH 770/853] [Glitch] Add secondary Wrapstodon share button Port 6821b707960e2f0a639069665865b08df8bc672f to glitch-soc Signed-off-by: Claire --- .../features/annual_report/index.module.scss | 15 +++++- .../features/annual_report/share_button.tsx | 48 +++++++++++++++++-- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/app/javascript/flavours/glitch/features/annual_report/index.module.scss b/app/javascript/flavours/glitch/features/annual_report/index.module.scss index 375b2e211e70b4..024518d72f75fe 100644 --- a/app/javascript/flavours/glitch/features/annual_report/index.module.scss +++ b/app/javascript/flavours/glitch/features/annual_report/index.module.scss @@ -174,7 +174,7 @@ $mobile-breakpoint: 540px; .title { text-transform: uppercase; - color: #c2c8ff; + color: var(--color-text-brand-soft); font-weight: 500; &:last-child { @@ -333,6 +333,19 @@ $mobile-breakpoint: 540px; mix-blend-mode: screen; } +.shareButtonWrapper { + display: flex; + flex-direction: column; + gap: 10px; +} + +.secondaryShareButton { + // Extra selector is needed to override color + &:global(.button) { + color: var(--color-text-primary); + } +} + .navItemBadge { background: var(--color-bg-brand-soft); } diff --git a/app/javascript/flavours/glitch/features/annual_report/share_button.tsx b/app/javascript/flavours/glitch/features/annual_report/share_button.tsx index 652c8af913dcbf..58ea88933605b3 100644 --- a/app/javascript/flavours/glitch/features/annual_report/share_button.tsx +++ b/app/javascript/flavours/glitch/features/annual_report/share_button.tsx @@ -3,6 +3,7 @@ import type { FC } from 'react'; import { defineMessages, useIntl } from 'react-intl'; +import { showAlert } from '@/flavours/glitch/actions/alerts'; import { resetCompose, focusCompose } from '@/flavours/glitch/actions/compose'; import { closeModal } from '@/flavours/glitch/actions/modal'; import { Button } from '@/flavours/glitch/components/button'; @@ -10,6 +11,7 @@ import type { AnnualReport as AnnualReportData } from '@/flavours/glitch/models/ import { useAppDispatch } from '@/flavours/glitch/store'; import { archetypeNames } from './archetype'; +import styles from './index.module.scss'; const messages = defineMessages({ share_message: { @@ -20,11 +22,24 @@ const messages = defineMessages({ id: 'annual_report.summary.share_on_mastodon', defaultMessage: 'Share on Mastodon', }, + share_elsewhere: { + id: 'annual_report.summary.share_elsewhere', + defaultMessage: 'Share elsewhere', + }, + copy_link: { + id: 'annual_report.summary.copy_link', + defaultMessage: 'Copy link', + }, + copied: { + id: 'copy_icon_button.copied', + defaultMessage: 'Copied to clipboard', + }, }); export const ShareButton: FC<{ report: AnnualReportData }> = ({ report }) => { const intl = useIntl(); const dispatch = useAppDispatch(); + const handleShareClick = useCallback(() => { // Generate the share message. const archetypeName = intl.formatMessage( @@ -47,10 +62,35 @@ export const ShareButton: FC<{ report: AnnualReportData }> = ({ report }) => { dispatch(closeModal({ modalType: 'ANNUAL_REPORT', ignoreFocus: false })); }, [report, intl, dispatch]); + const supportsNativeShare = 'share' in navigator; + + const handleSecondaryShare = useCallback(() => { + if (report.schema_version === 2 && report.share_url) { + if (supportsNativeShare) { + void navigator.share({ + url: report.share_url, + }); + } else { + void navigator.clipboard.writeText(report.share_url); + dispatch(showAlert({ message: messages.copied })); + } + } + }, [report, supportsNativeShare, dispatch]); + return ( -
); }; From 6734fd206e5399f01a08cebc074a6cc81983301a Mon Sep 17 00:00:00 2001 From: diondiondion Date: Fri, 12 Dec 2025 15:31:21 +0100 Subject: [PATCH 771/853] =?UTF-8?q?[Glitch]=20Change=20Emoji=20in=20Wrapst?= =?UTF-8?q?odon=20footer=20=F0=9F=90=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Port 861202fd080d9a7db0e478d14df79ed317dcf501 to glitch-soc Signed-off-by: Claire --- .../flavours/glitch/features/annual_report/shared_page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/flavours/glitch/features/annual_report/shared_page.tsx b/app/javascript/flavours/glitch/features/annual_report/shared_page.tsx index fcf4745249d5e1..a2dc9ff8487d29 100644 --- a/app/javascript/flavours/glitch/features/annual_report/shared_page.tsx +++ b/app/javascript/flavours/glitch/features/annual_report/shared_page.tsx @@ -17,7 +17,7 @@ export const WrapstodonSharedPage: FC = () => {
+ ); }; diff --git a/app/javascript/flavours/glitch/styles/mastodon/components.scss b/app/javascript/flavours/glitch/styles/mastodon/components.scss index b00dcf718d14b2..0ac2884eb90cfd 100644 --- a/app/javascript/flavours/glitch/styles/mastodon/components.scss +++ b/app/javascript/flavours/glitch/styles/mastodon/components.scss @@ -628,11 +628,6 @@ body > [data-popper-placement] { gap: 8px; margin: 8px; flex-wrap: wrap; - - & > div { - overflow: hidden; - display: flex; - } } &__uploads { @@ -813,7 +808,6 @@ body > [data-popper-placement] { display: flex; flex: 1 0 100%; // glitch: always on its own line max-width: 100%; - overflow: hidden; gap: 5px; // glitch: handle secondary post privacy align-items: stretch; // glitch: handle secondary post privacy @@ -985,6 +979,11 @@ body > [data-popper-placement] { text-overflow: ellipsis; white-space: nowrap; + &:focus-visible { + outline: var(--outline-focus-default); + outline-offset: 2px; + } + &[disabled] { cursor: default; color: var(--color-text-disabled); From 56a9d62972c7b8762f062226886835e294aac1ef Mon Sep 17 00:00:00 2001 From: Echo Date: Mon, 15 Dec 2025 13:54:46 +0100 Subject: [PATCH 789/853] [Glitch] Fixes display names not rendering with emojis Port 5fa765468878a0efcee58f832075df8a499bd18b to glitch-soc Signed-off-by: Claire --- .../glitch/entrypoints/wrapstodon.tsx | 7 +++-- .../features/annual_report/archetype.tsx | 10 +++---- .../glitch/features/annual_report/index.tsx | 6 +---- .../annual_report/most_used_hashtag.tsx | 26 +++++++++++-------- .../features/annual_report/shared_page.tsx | 5 ++-- 5 files changed, 29 insertions(+), 25 deletions(-) diff --git a/app/javascript/flavours/glitch/entrypoints/wrapstodon.tsx b/app/javascript/flavours/glitch/entrypoints/wrapstodon.tsx index 5de491c47a83a1..972e5dac038e0d 100644 --- a/app/javascript/flavours/glitch/entrypoints/wrapstodon.tsx +++ b/app/javascript/flavours/glitch/entrypoints/wrapstodon.tsx @@ -25,7 +25,7 @@ function loaded() { const initialState = JSON.parse( propsNode.textContent, - ) as ApiAnnualReportResponse; + ) as ApiAnnualReportResponse & { me?: string }; const report = initialState.annual_reports[0]; if (!report) { @@ -35,7 +35,10 @@ function loaded() { // Set up store store.dispatch( hydrateStore({ - meta: { locale: document.documentElement.lang }, + meta: { + locale: document.documentElement.lang, + me: initialState.me, + }, accounts: initialState.accounts, }), ); diff --git a/app/javascript/flavours/glitch/features/annual_report/archetype.tsx b/app/javascript/flavours/glitch/features/annual_report/archetype.tsx index 352a99656b42e4..743aa0c05c64c9 100644 --- a/app/javascript/flavours/glitch/features/annual_report/archetype.tsx +++ b/app/javascript/flavours/glitch/features/annual_report/archetype.tsx @@ -6,6 +6,7 @@ import classNames from 'classnames'; import { Avatar } from '@/flavours/glitch/components/avatar'; import { Button } from '@/flavours/glitch/components/button'; +import { DisplayName } from '@/flavours/glitch/components/display_name'; import { me } from '@/flavours/glitch/initial_state'; import type { Account } from '@/flavours/glitch/models/account'; import type { @@ -137,9 +138,6 @@ export const Archetype: React.FC<{ ? archetypeSelfDescriptions : archetypePublicDescriptions; - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- we specifically want to fallback if `display_name` is empty - const name = account?.display_name || account?.username; - return (
, + }} /> )} @@ -199,7 +199,7 @@ export const Archetype: React.FC<{

{isRevealed ? ( intl.formatMessage(descriptions[archetype], { - name, + name: , }) ) : ( state.accounts, (state) => state.annualReport.report], (accounts, report) => { - if (me) { - return accounts.get(me); - } if (report?.schema_version === 2) { return accounts.get(report.account_id); } @@ -109,7 +105,7 @@ export const AnnualReport: FC<{ context?: 'modal' | 'standalone' }> = ({ {topHashtag && ( )} diff --git a/app/javascript/flavours/glitch/features/annual_report/most_used_hashtag.tsx b/app/javascript/flavours/glitch/features/annual_report/most_used_hashtag.tsx index 7f60db8038aced..46f17fff9b4ab9 100644 --- a/app/javascript/flavours/glitch/features/annual_report/most_used_hashtag.tsx +++ b/app/javascript/flavours/glitch/features/annual_report/most_used_hashtag.tsx @@ -2,15 +2,17 @@ import { FormattedMessage } from 'react-intl'; import classNames from 'classnames'; +import { DisplayName } from '@/flavours/glitch/components/display_name'; +import type { Account } from '@/flavours/glitch/models/account'; import type { NameAndCount } from 'flavours/glitch/models/annual_report'; import styles from './index.module.scss'; export const MostUsedHashtag: React.FC<{ hashtag: NameAndCount; - name: string | undefined; context: 'modal' | 'standalone'; -}> = ({ hashtag, name, context }) => { + account?: Account; +}> = ({ hashtag, context, account }) => { return (

#{hashtag.name}

- {context === 'modal' ? ( + {context === 'modal' && ( - ) : ( - name && ( - - ) + )} + {context !== 'modal' && account && ( + , + }} + /> )}

diff --git a/app/javascript/flavours/glitch/features/annual_report/shared_page.tsx b/app/javascript/flavours/glitch/features/annual_report/shared_page.tsx index a2dc9ff8487d29..8e0881792420d0 100644 --- a/app/javascript/flavours/glitch/features/annual_report/shared_page.tsx +++ b/app/javascript/flavours/glitch/features/annual_report/shared_page.tsx @@ -3,12 +3,13 @@ import type { FC } from 'react'; import { FormattedMessage } from 'react-intl'; import { IconLogo } from '@/flavours/glitch/components/logo'; -import { me } from '@/flavours/glitch/initial_state'; +import { useAppSelector } from '@/flavours/glitch/store'; import { AnnualReport } from './index'; import classes from './shared_page.module.scss'; export const WrapstodonSharedPage: FC = () => { + const isLoggedIn = useAppSelector((state) => !!state.meta.get('me')); return (
@@ -23,7 +24,7 @@ export const WrapstodonSharedPage: FC = () => { - {!me && ( + {!isLoggedIn && ( Date: Mon, 15 Dec 2025 16:24:03 +0100 Subject: [PATCH 790/853] [Glitch] Prevent "invalid access token" error when opening Mastodon while logged out Port 807e1254e6f1e4d73941a94623d606159382245e to glitch-soc Signed-off-by: Claire --- .../flavours/glitch/reducers/slices/annual_report.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/javascript/flavours/glitch/reducers/slices/annual_report.ts b/app/javascript/flavours/glitch/reducers/slices/annual_report.ts index d7dbccdb576283..0d159f947e283e 100644 --- a/app/javascript/flavours/glitch/reducers/slices/annual_report.ts +++ b/app/javascript/flavours/glitch/reducers/slices/annual_report.ts @@ -62,7 +62,8 @@ export const checkAnnualReport = createAppThunk( `${annualReportSlice.name}/checkAnnualReport`, (_arg: unknown, { dispatch, getState }) => { const year = selectWrapstodonYear(getState()); - if (!year) { + const me = getState().meta.get('me') as string; + if (!year || !me) { return; } void dispatch(fetchReportState()); From 460e6753270623c5f04d6699e92072b80eb848a3 Mon Sep 17 00:00:00 2001 From: Echo Date: Mon, 15 Dec 2025 16:38:13 +0100 Subject: [PATCH 791/853] [Glitch] Emoji: Import and use shortcode data Port cbe135210305c0ce4455130c4e75680e53ff1425 to glitch-soc Signed-off-by: Claire --- .../glitch/components/emoji/emoji.stories.tsx | 9 +- .../glitch/components/emoji/index.tsx | 22 +++- .../glitch/features/emoji/constants.ts | 4 + .../glitch/features/emoji/database.test.ts | 86 ++++++++++++- .../glitch/features/emoji/database.ts | 121 ++++++++++++++++-- .../flavours/glitch/features/emoji/index.ts | 35 +++-- .../flavours/glitch/features/emoji/loader.ts | 120 ++++++++++++++--- .../glitch/features/emoji/render.test.ts | 59 ++++++++- .../flavours/glitch/features/emoji/render.ts | 12 +- .../flavours/glitch/features/emoji/types.ts | 4 +- .../flavours/glitch/features/emoji/worker.ts | 11 +- app/javascript/flavours/glitch/utils/types.ts | 2 + 12 files changed, 418 insertions(+), 67 deletions(-) diff --git a/app/javascript/flavours/glitch/components/emoji/emoji.stories.tsx b/app/javascript/flavours/glitch/components/emoji/emoji.stories.tsx index d4f5663ae4dc6d..d390387a036aba 100644 --- a/app/javascript/flavours/glitch/components/emoji/emoji.stories.tsx +++ b/app/javascript/flavours/glitch/components/emoji/emoji.stories.tsx @@ -2,8 +2,6 @@ import type { ComponentProps } from 'react'; import type { Meta, StoryObj } from '@storybook/react-vite'; -import { importCustomEmojiData } from '@/flavours/glitch/features/emoji/loader'; - import { Emoji } from './index'; type EmojiProps = ComponentProps & { state: string }; @@ -38,7 +36,6 @@ const meta = { }, }, render(args) { - void importCustomEmojiData(); return ; }, } satisfies Meta; @@ -54,3 +51,9 @@ export const CustomEmoji: Story = { code: ':custom:', }, }; + +export const LegacyEmoji: Story = { + args: { + code: ':copyright:', + }, +}; diff --git a/app/javascript/flavours/glitch/components/emoji/index.tsx b/app/javascript/flavours/glitch/components/emoji/index.tsx index b950f4c04224d5..2b596be6daa610 100644 --- a/app/javascript/flavours/glitch/components/emoji/index.tsx +++ b/app/javascript/flavours/glitch/components/emoji/index.tsx @@ -3,7 +3,10 @@ import { useContext, useEffect, useState } from 'react'; import classNames from 'classnames'; -import { EMOJI_TYPE_CUSTOM } from '@/flavours/glitch/features/emoji/constants'; +import { + EMOJI_TYPE_CUSTOM, + EMOJI_TYPE_UNICODE, +} from '@/flavours/glitch/features/emoji/constants'; import { useEmojiAppState } from '@/flavours/glitch/features/emoji/mode'; import { emojiToInversionClassName, @@ -47,8 +50,6 @@ export const Emoji: FC = ({ const animate = useContext(AnimateEmojiContext); - const inversionClass = emojiToInversionClassName(code); - const fallback = showFallback ? code : null; // If the code is invalid or we otherwise know it's not valid, show the fallback. @@ -56,10 +57,6 @@ export const Emoji: FC = ({ return fallback; } - if (!shouldRenderImage(state, appState.mode)) { - return code; - } - if (!isStateLoaded(state)) { if (showLoading) { return ; @@ -67,6 +64,17 @@ export const Emoji: FC = ({ return fallback; } + const inversionClass = + state.type === EMOJI_TYPE_UNICODE && + emojiToInversionClassName(state.data.unicode); + + if (!shouldRenderImage(state, appState.mode)) { + if (state.type === EMOJI_TYPE_UNICODE) { + return state.data.unicode; + } + return code; + } + if (state.type === EMOJI_TYPE_CUSTOM) { const shortcode = `:${state.code}:`; return ( diff --git a/app/javascript/flavours/glitch/features/emoji/constants.ts b/app/javascript/flavours/glitch/features/emoji/constants.ts index f7705731214e8e..e02663c9d84082 100644 --- a/app/javascript/flavours/glitch/features/emoji/constants.ts +++ b/app/javascript/flavours/glitch/features/emoji/constants.ts @@ -23,6 +23,10 @@ export const EMOJI_MODE_TWEMOJI = 'twemoji'; export const EMOJI_TYPE_UNICODE = 'unicode'; export const EMOJI_TYPE_CUSTOM = 'custom'; +export const EMOJI_DB_NAME_SHORTCODES = 'shortcodes'; + +export const EMOJI_DB_SHORTCODE_TEST = '2122'; // 2122 is the trademark sign, which we know has shortcodes in all datasets. + export const EMOJIS_WITH_DARK_BORDER = [ '🎱', // 1F3B1 '🐜', // 1F41C diff --git a/app/javascript/flavours/glitch/features/emoji/database.test.ts b/app/javascript/flavours/glitch/features/emoji/database.test.ts index 0689fd7c542d7f..5931a238eabbd2 100644 --- a/app/javascript/flavours/glitch/features/emoji/database.test.ts +++ b/app/javascript/flavours/glitch/features/emoji/database.test.ts @@ -1,7 +1,8 @@ import { IDBFactory } from 'fake-indexeddb'; -import { unicodeEmojiFactory } from '@/testing/factories'; +import { customEmojiFactory, unicodeEmojiFactory } from '@/testing/factories'; +import { EMOJI_DB_SHORTCODE_TEST } from './constants'; import { putEmojiData, loadEmojiByHexcode, @@ -9,6 +10,11 @@ import { searchEmojisByTag, testClear, testGet, + putCustomEmojiData, + putLegacyShortcodes, + loadLegacyShortcodesByShortcode, + loadLatestEtag, + putLatestEtag, } from './database'; describe('emoji database', () => { @@ -16,6 +22,7 @@ describe('emoji database', () => { testClear(); indexedDB = new IDBFactory(); }); + describe('putEmojiData', () => { test('adds to loaded locales', async () => { const { loadedLocales } = await testGet(); @@ -33,6 +40,29 @@ describe('emoji database', () => { }); }); + describe('putCustomEmojiData', () => { + test('loads custom emoji into indexedDB', async () => { + const { db } = await testGet(); + await putCustomEmojiData([customEmojiFactory()]); + await expect(db.get('custom', 'custom')).resolves.toEqual( + customEmojiFactory(), + ); + }); + }); + + describe('putLegacyShortcodes', () => { + test('loads shortcodes into indexedDB', async () => { + const { db } = await testGet(); + await putLegacyShortcodes({ + test_hexcode: ['shortcode1', 'shortcode2'], + }); + await expect(db.get('shortcodes', 'test_hexcode')).resolves.toEqual({ + hexcode: 'test_hexcode', + shortcodes: ['shortcode1', 'shortcode2'], + }); + }); + }); + describe('loadEmojiByHexcode', () => { test('throws if the locale is not loaded', async () => { await expect(loadEmojiByHexcode('en', 'test')).rejects.toThrowError( @@ -136,4 +166,58 @@ describe('emoji database', () => { expect(actual).toHaveLength(0); }); }); + + describe('loadLegacyShortcodesByShortcode', () => { + const data = { + hexcode: 'test_hexcode', + shortcodes: ['shortcode1', 'shortcode2'], + }; + + beforeEach(async () => { + await putLegacyShortcodes({ + [data.hexcode]: data.shortcodes, + }); + }); + + test('retrieves the shortcodes', async () => { + await expect( + loadLegacyShortcodesByShortcode('shortcode1'), + ).resolves.toEqual(data); + await expect( + loadLegacyShortcodesByShortcode('shortcode2'), + ).resolves.toEqual(data); + }); + }); + + describe('loadLatestEtag', () => { + beforeEach(async () => { + await putLatestEtag('etag', 'en'); + await putEmojiData([unicodeEmojiFactory()], 'en'); + await putLatestEtag('fr-etag', 'fr'); + }); + + test('retrieves the etag for loaded locale', async () => { + await putEmojiData( + [unicodeEmojiFactory({ hexcode: EMOJI_DB_SHORTCODE_TEST })], + 'en', + ); + const etag = await loadLatestEtag('en'); + expect(etag).toBe('etag'); + }); + + test('returns null if locale has no shortcodes', async () => { + const etag = await loadLatestEtag('en'); + expect(etag).toBeNull(); + }); + + test('returns null if locale not loaded', async () => { + const etag = await loadLatestEtag('de'); + expect(etag).toBeNull(); + }); + + test('returns null if locale has no data', async () => { + const etag = await loadLatestEtag('fr'); + expect(etag).toBeNull(); + }); + }); }); diff --git a/app/javascript/flavours/glitch/features/emoji/database.ts b/app/javascript/flavours/glitch/features/emoji/database.ts index b7f8a32f76ca83..2e8de712217570 100644 --- a/app/javascript/flavours/glitch/features/emoji/database.ts +++ b/app/javascript/flavours/glitch/features/emoji/database.ts @@ -1,8 +1,9 @@ import { SUPPORTED_LOCALES } from 'emojibase'; -import type { Locale } from 'emojibase'; +import type { Locale, ShortcodesDataset } from 'emojibase'; import type { DBSchema, IDBPDatabase } from 'idb'; import { openDB } from 'idb'; +import { EMOJI_DB_SHORTCODE_TEST } from './constants'; import { toSupportedLocale, toSupportedLocaleOrCustom } from './locale'; import type { CustomEmojiData, @@ -19,6 +20,17 @@ interface EmojiDB extends LocaleTables, DBSchema { category: string; }; }; + shortcodes: { + key: string; + value: { + hexcode: string; + shortcodes: string[]; + }; + indexes: { + hexcode: string; + shortcodes: string[]; + }; + }; etags: { key: LocaleOrCustom; value: string; @@ -33,13 +45,14 @@ interface LocaleTable { label: string; order: number; tags: string[]; + shortcodes: string[]; }; } type LocaleTables = Record; type Database = IDBPDatabase; -const SCHEMA_VERSION = 1; +const SCHEMA_VERSION = 2; const loadedLocales = new Set(); @@ -52,28 +65,76 @@ const loadDB = (() => { // Actually load the DB. async function initDB() { const db = await openDB('mastodon-emoji', SCHEMA_VERSION, { - upgrade(database) { - const customTable = database.createObjectStore('custom', { - keyPath: 'shortcode', - autoIncrement: false, - }); - customTable.createIndex('category', 'category'); + upgrade(database, oldVersion, newVersion, trx) { + if (!database.objectStoreNames.contains('custom')) { + const customTable = database.createObjectStore('custom', { + keyPath: 'shortcode', + autoIncrement: false, + }); + customTable.createIndex('category', 'category'); + } - database.createObjectStore('etags'); + if (!database.objectStoreNames.contains('etags')) { + database.createObjectStore('etags'); + } for (const locale of SUPPORTED_LOCALES) { - const localeTable = database.createObjectStore(locale, { + if (!database.objectStoreNames.contains(locale)) { + const localeTable = database.createObjectStore(locale, { + keyPath: 'hexcode', + autoIncrement: false, + }); + localeTable.createIndex('group', 'group'); + localeTable.createIndex('label', 'label'); + localeTable.createIndex('order', 'order'); + localeTable.createIndex('tags', 'tags', { multiEntry: true }); + localeTable.createIndex('shortcodes', 'shortcodes', { + multiEntry: true, + }); + } + // Added in version 2. + const localeTable = trx.objectStore(locale); + if (!localeTable.indexNames.contains('shortcodes')) { + localeTable.createIndex('shortcodes', 'shortcodes', { + multiEntry: true, + }); + } + } + + if (!database.objectStoreNames.contains('shortcodes')) { + const shortcodeTable = database.createObjectStore('shortcodes', { keyPath: 'hexcode', autoIncrement: false, }); - localeTable.createIndex('group', 'group'); - localeTable.createIndex('label', 'label'); - localeTable.createIndex('order', 'order'); - localeTable.createIndex('tags', 'tags', { multiEntry: true }); + shortcodeTable.createIndex('hexcode', 'hexcode'); + shortcodeTable.createIndex('shortcodes', 'shortcodes', { + multiEntry: true, + }); } + + log( + 'Upgraded emoji database from version %d to %d', + oldVersion, + newVersion, + ); + }, + blocked(currentVersion, blockedVersion) { + log( + 'Emoji database upgrade from version %d to %d is blocked', + currentVersion, + blockedVersion, + ); + }, + blocking(currentVersion, blockedVersion) { + log( + 'Emoji database upgrade from version %d is blocking upgrade to %d', + currentVersion, + blockedVersion, + ); }, }); await syncLocales(db); + log('Loaded database version %d', db.version); return db; } @@ -107,6 +168,20 @@ export async function putCustomEmojiData(emojis: CustomEmojiData[]) { await trx.done; } +export async function putLegacyShortcodes(shortcodes: ShortcodesDataset) { + const db = await loadDB(); + const trx = db.transaction('shortcodes', 'readwrite'); + await Promise.all( + Object.entries(shortcodes).map(([hexcode, codes]) => + trx.store.put({ + hexcode, + shortcodes: Array.isArray(codes) ? codes : [codes], + }), + ), + ); + await trx.done; +} + export async function putLatestEtag(etag: string, localeString: string) { const locale = toSupportedLocaleOrCustom(localeString); const db = await loadDB(); @@ -161,6 +236,15 @@ export async function searchCustomEmojisByShortcodes(shortcodes: string[]) { return results.filter((emoji) => shortcodes.includes(emoji.shortcode)); } +export async function loadLegacyShortcodesByShortcode(shortcode: string) { + const db = await loadDB(); + return db.getFromIndex( + 'shortcodes', + 'shortcodes', + IDBKeyRange.only(shortcode), + ); +} + export async function loadLatestEtag(localeString: string) { const locale = toSupportedLocaleOrCustom(localeString); const db = await loadDB(); @@ -168,6 +252,15 @@ export async function loadLatestEtag(localeString: string) { if (!rowCount) { return null; // No data for this locale, return null even if there is an etag. } + + // Check if shortcodes exist for the given Unicode locale. + if (locale !== 'custom') { + const result = await db.get(locale, EMOJI_DB_SHORTCODE_TEST); + if (!result?.shortcodes) { + return null; + } + } + const etag = await db.get('etags', locale); return etag ?? null; } diff --git a/app/javascript/flavours/glitch/features/emoji/index.ts b/app/javascript/flavours/glitch/features/emoji/index.ts index 51baef753790df..4a04f99bed2a0b 100644 --- a/app/javascript/flavours/glitch/features/emoji/index.ts +++ b/app/javascript/flavours/glitch/features/emoji/index.ts @@ -1,5 +1,9 @@ +import type { Locale } from 'emojibase'; + import { initialState } from '@/flavours/glitch/initial_state'; +import type { EMOJI_DB_NAME_SHORTCODES, EMOJI_TYPE_CUSTOM } from './constants'; +import { importLegacyShortcodes, localeToShortcodesPath } from './loader'; import { toSupportedLocale } from './locale'; import type { LocaleOrCustom } from './types'; import { emojiLogger } from './utils'; @@ -36,12 +40,8 @@ export function initializeEmoji() { log('worker ready, loading data'); clearTimeout(timeoutId); messageWorker('custom'); + messageWorker('shortcodes'); void loadEmojiLocale(userLocale); - // Load English locale as well, because people are still used to - // using it from before we supported other locales. - if (userLocale !== 'en') { - void loadEmojiLocale('en'); - } } else { log('got worker message: %s', message); } @@ -58,20 +58,23 @@ async function fallbackLoad() { if (emojis) { log('loaded %d custom emojis', emojis.length); } - await loadEmojiLocale(userLocale); - if (userLocale !== 'en') { - await loadEmojiLocale('en'); + const shortcodes = await importLegacyShortcodes(); + if (shortcodes.length) { + log('loaded %d legacy shortcodes', shortcodes.length); } + await loadEmojiLocale(userLocale); } async function loadEmojiLocale(localeString: string) { const locale = toSupportedLocale(localeString); - const { importEmojiData, localeToPath } = await import('./loader'); + const { importEmojiData, localeToEmojiPath: localeToPath } = + await import('./loader'); if (worker) { const path = await localeToPath(locale); + const shortcodesPath = await localeToShortcodesPath(locale); log('asking worker to load locale %s from %s', locale, path); - messageWorker(locale, path); + messageWorker(locale, path, shortcodesPath); } else { const emojis = await importEmojiData(locale); if (emojis) { @@ -80,9 +83,17 @@ async function loadEmojiLocale(localeString: string) { } } -function messageWorker(locale: LocaleOrCustom, path?: string) { +function messageWorker( + locale: typeof EMOJI_TYPE_CUSTOM | typeof EMOJI_DB_NAME_SHORTCODES, +): void; +function messageWorker(locale: Locale, path: string, shortcodes?: string): void; +function messageWorker( + locale: LocaleOrCustom | typeof EMOJI_DB_NAME_SHORTCODES, + path?: string, + shortcodes?: string, +) { if (!worker) { return; } - worker.postMessage({ locale, path }); + worker.postMessage({ locale, path, shortcodes }); } diff --git a/app/javascript/flavours/glitch/features/emoji/loader.ts b/app/javascript/flavours/glitch/features/emoji/loader.ts index 86c879cddc9d79..18c04dc64d5501 100644 --- a/app/javascript/flavours/glitch/features/emoji/loader.ts +++ b/app/javascript/flavours/glitch/features/emoji/loader.ts @@ -1,16 +1,26 @@ import { flattenEmojiData } from 'emojibase'; -import type { CompactEmoji, FlatCompactEmoji, Locale } from 'emojibase'; +import type { + CompactEmoji, + FlatCompactEmoji, + Locale, + ShortcodesDataset, +} from 'emojibase'; import { putEmojiData, putCustomEmojiData, loadLatestEtag, putLatestEtag, + putLegacyShortcodes, } from './database'; import { toSupportedLocale, toSupportedLocaleOrCustom } from './locale'; import type { CustomEmojiData } from './types'; -export async function importEmojiData(localeString: string, path?: string) { +export async function importEmojiData( + localeString: string, + path?: string, + shortcodes: boolean | string = true, +) { const locale = toSupportedLocale(localeString); // Validate the provided path. @@ -18,14 +28,42 @@ export async function importEmojiData(localeString: string, path?: string) { throw new Error('Invalid path for emoji data'); } else { // Otherwise get the path if not provided. - path ??= await localeToPath(locale); + path ??= await localeToEmojiPath(locale); } const emojis = await fetchAndCheckEtag(locale, path); if (!emojis) { return; } - const flattenedEmojis: FlatCompactEmoji[] = flattenEmojiData(emojis); + + const shortcodesData: ShortcodesDataset[] = []; + if (shortcodes) { + if ( + typeof shortcodes === 'string' && + !/^[/a-z]*\/packs\/assets\/shortcodes\/cldr\.json$/.test(shortcodes) + ) { + throw new Error('Invalid path for shortcodes data'); + } + const shortcodesPath = + typeof shortcodes === 'string' + ? shortcodes + : await localeToShortcodesPath(locale); + const shortcodesResponse = await fetchAndCheckEtag( + locale, + shortcodesPath, + false, + ); + if (shortcodesResponse) { + shortcodesData.push(shortcodesResponse); + } else { + throw new Error(`No shortcodes data found for locale ${locale}`); + } + } + + const flattenedEmojis: FlatCompactEmoji[] = flattenEmojiData( + emojis, + shortcodesData, + ); await putEmojiData(flattenedEmojis, locale); return flattenedEmojis; } @@ -42,32 +80,77 @@ export async function importCustomEmojiData() { return emojis; } -const modules = import.meta.glob( - '../../../../../../node_modules/emojibase-data/**/compact.json', - { - query: '?url', - import: 'default', - }, +export async function importLegacyShortcodes() { + const { default: shortcodesPath } = + await import('emojibase-data/en/shortcodes/iamcal.json?url'); + const response = await fetch(shortcodesPath); + if (!response.ok) { + throw new Error( + `Failed to fetch legacy shortcodes data: ${response.statusText}`, + ); + } + const shortcodesData = (await response.json()) as ShortcodesDataset; + await putLegacyShortcodes(shortcodesData); + return Object.keys(shortcodesData); +} + +const emojiModules = new Map( + Object.entries( + import.meta.glob( + '../../../../../../node_modules/emojibase-data/**/compact.json', + { + query: '?url', + import: 'default', + }, + ), + ).map(([key, loader]) => { + const match = /emojibase-data\/([^/]+)\/compact\.json$/.exec(key); + return [match?.at(1) ?? key, loader]; + }), ); -export function localeToPath(locale: Locale) { - const key = `../../../../../../node_modules/emojibase-data/${locale}/compact.json`; - if (!modules[key] || typeof modules[key] !== 'function') { +export function localeToEmojiPath(locale: Locale) { + const path = emojiModules.get(locale); + if (!path) { throw new Error(`Unsupported locale: ${locale}`); } - return modules[key](); + return path(); } -export async function fetchAndCheckEtag( +const shortcodesModules = new Map( + Object.entries( + import.meta.glob( + '../../../../../../node_modules/emojibase-data/**/shortcodes/cldr.json', + { + query: '?url', + import: 'default', + }, + ), + ).map(([key, loader]) => { + const match = /emojibase-data\/([^/]+)\/shortcodes\/cldr\.json$/.exec(key); + return [match?.at(1) ?? key, loader]; + }), +); + +export function localeToShortcodesPath(locale: Locale) { + const path = shortcodesModules.get(locale); + if (!path) { + throw new Error(`Unsupported locale for shortcodes: ${locale}`); + } + return path(); +} + +export async function fetchAndCheckEtag( localeString: string, path: string, + checkEtag = true, ): Promise { const locale = toSupportedLocaleOrCustom(localeString); // Use location.origin as this script may be loaded from a CDN domain. const url = new URL(path, location.origin); - const oldEtag = await loadLatestEtag(locale); + const oldEtag = checkEtag ? await loadLatestEtag(locale) : null; const response = await fetch(url, { headers: { 'Content-Type': 'application/json', @@ -85,13 +168,10 @@ export async function fetchAndCheckEtag( } const data = (await response.json()) as ResultType; - if (!Array.isArray(data)) { - throw new Error(`Unexpected data format for ${locale}: expected an array`); - } // Store the ETag for future requests const etag = response.headers.get('ETag'); - if (etag) { + if (etag && checkEtag) { await putLatestEtag(etag, localeString); } diff --git a/app/javascript/flavours/glitch/features/emoji/render.test.ts b/app/javascript/flavours/glitch/features/emoji/render.test.ts index 3c96cbfb553da8..782148b36e377c 100644 --- a/app/javascript/flavours/glitch/features/emoji/render.test.ts +++ b/app/javascript/flavours/glitch/features/emoji/render.test.ts @@ -7,6 +7,7 @@ import { stringToEmojiState, tokenizeText, } from './render'; +import type { EmojiStateCustom, EmojiStateUnicode } from './types'; describe('tokenizeText', () => { test('returns an array of text to be a single token', () => { @@ -120,13 +121,24 @@ describe('loadEmojiDataToState', () => { const dbCall = vi .spyOn(db, 'loadEmojiByHexcode') .mockResolvedValue(unicodeEmojiFactory()); - const unicodeState = { type: 'unicode', code: '1F60A' } as const; + const dbLegacyCall = vi + .spyOn(db, 'loadLegacyShortcodesByShortcode') + .mockResolvedValueOnce({ + shortcodes: ['legacy_code'], + hexcode: '1F60A', + }); + const unicodeState = { + type: 'unicode', + code: '1F60A', + } as const satisfies EmojiStateUnicode; const result = await loadEmojiDataToState(unicodeState, 'en'); expect(dbCall).toHaveBeenCalledWith('1F60A', 'en'); + expect(dbLegacyCall).toHaveBeenCalledWith('1F60A'); expect(result).toEqual({ type: 'unicode', code: '1F60A', data: unicodeEmojiFactory(), + shortcode: 'legacy_code', }); }); @@ -134,7 +146,10 @@ describe('loadEmojiDataToState', () => { const dbCall = vi .spyOn(db, 'loadCustomEmojiByShortcode') .mockResolvedValueOnce(customEmojiFactory()); - const customState = { type: 'custom', code: 'smile' } as const; + const customState = { + type: 'custom', + code: 'smile', + } as const satisfies EmojiStateCustom; const result = await loadEmojiDataToState(customState, 'en'); expect(dbCall).toHaveBeenCalledWith('smile'); expect(result).toEqual({ @@ -144,16 +159,47 @@ describe('loadEmojiDataToState', () => { }); }); + test('loads unicode data using legacy shortcode', async () => { + const dbLegacyCall = vi + .spyOn(db, 'loadLegacyShortcodesByShortcode') + .mockResolvedValueOnce({ + shortcodes: ['test'], + hexcode: 'test', + }); + const dbUnicodeCall = vi + .spyOn(db, 'loadEmojiByHexcode') + .mockResolvedValue(unicodeEmojiFactory()); + const unicodeState = { + type: 'unicode', + code: 'test', + } as const satisfies EmojiStateUnicode; + const result = await loadEmojiDataToState(unicodeState, 'en'); + expect(dbLegacyCall).toHaveBeenCalledWith('test'); + expect(dbUnicodeCall).toHaveBeenCalledWith('test', 'en'); + expect(result).toEqual({ + type: 'unicode', + code: 'test', + data: unicodeEmojiFactory(), + shortcode: 'test', + }); + }); + test('returns null if unicode emoji not found in database', async () => { vi.spyOn(db, 'loadEmojiByHexcode').mockResolvedValueOnce(undefined); - const unicodeState = { type: 'unicode', code: '1F60A' } as const; + const unicodeState = { + type: 'unicode', + code: '1F60A', + } as const satisfies EmojiStateUnicode; const result = await loadEmojiDataToState(unicodeState, 'en'); expect(result).toBeNull(); }); test('returns null if custom emoji not found in database', async () => { vi.spyOn(db, 'loadCustomEmojiByShortcode').mockResolvedValueOnce(undefined); - const customState = { type: 'custom', code: 'smile' } as const; + const customState = { + type: 'custom', + code: 'smile', + } as const satisfies EmojiStateCustom; const result = await loadEmojiDataToState(customState, 'en'); expect(result).toBeNull(); }); @@ -167,7 +213,10 @@ describe('loadEmojiDataToState', () => { .spyOn(console, 'warn') .mockImplementationOnce(() => null); - const unicodeState = { type: 'unicode', code: '1F60A' } as const; + const unicodeState = { + type: 'unicode', + code: '1F60A', + } as const satisfies EmojiStateUnicode; const result = await loadEmojiDataToState(unicodeState, 'en'); expect(dbCall).toHaveBeenCalledTimes(2); diff --git a/app/javascript/flavours/glitch/features/emoji/render.ts b/app/javascript/flavours/glitch/features/emoji/render.ts index 574d5ef59b2484..e00525fe0a110e 100644 --- a/app/javascript/flavours/glitch/features/emoji/render.ts +++ b/app/javascript/flavours/glitch/features/emoji/render.ts @@ -7,6 +7,7 @@ import { import { loadCustomEmojiByShortcode, loadEmojiByHexcode, + loadLegacyShortcodesByShortcode, LocaleNotLoadedError, } from './database'; import { importEmojiData } from './loader'; @@ -116,13 +117,20 @@ export async function loadEmojiDataToState( // First, try to load the data from IndexedDB. try { + const legacyCode = await loadLegacyShortcodesByShortcode(state.code); // This is duplicative, but that's because TS can't distinguish the state type easily. - if (state.type === EMOJI_TYPE_UNICODE) { - const data = await loadEmojiByHexcode(state.code, locale); + if (state.type === EMOJI_TYPE_UNICODE || legacyCode) { + const data = await loadEmojiByHexcode( + legacyCode?.hexcode ?? state.code, + locale, + ); if (data) { return { ...state, + type: EMOJI_TYPE_UNICODE, data, + // TODO: Use CLDR shortcodes when the picker supports them. + shortcode: legacyCode?.shortcodes.at(0), }; } } else { diff --git a/app/javascript/flavours/glitch/features/emoji/types.ts b/app/javascript/flavours/glitch/features/emoji/types.ts index a940aa4d929386..da4b87c23ebe28 100644 --- a/app/javascript/flavours/glitch/features/emoji/types.ts +++ b/app/javascript/flavours/glitch/features/emoji/types.ts @@ -4,6 +4,7 @@ import type { FlatCompactEmoji, Locale } from 'emojibase'; import type { ApiCustomEmojiJSON } from '@/flavours/glitch/api_types/custom_emoji'; import type { CustomEmoji } from '@/flavours/glitch/models/custom_emoji'; +import type { RequiredExcept } from '@/flavours/glitch/utils/types'; import type { EMOJI_MODE_NATIVE, @@ -40,6 +41,7 @@ export interface EmojiStateUnicode { type: typeof EMOJI_TYPE_UNICODE; code: string; data?: UnicodeEmojiData; + shortcode?: string; } export interface EmojiStateCustom { type: typeof EMOJI_TYPE_CUSTOM; @@ -49,7 +51,7 @@ export interface EmojiStateCustom { export type EmojiState = EmojiStateUnicode | EmojiStateCustom; export type EmojiLoadedState = - | Required + | RequiredExcept | Required; export type CustomEmojiMapArg = diff --git a/app/javascript/flavours/glitch/features/emoji/worker.ts b/app/javascript/flavours/glitch/features/emoji/worker.ts index 5360484d7788a5..2243678276a58d 100644 --- a/app/javascript/flavours/glitch/features/emoji/worker.ts +++ b/app/javascript/flavours/glitch/features/emoji/worker.ts @@ -1,4 +1,9 @@ -import { importCustomEmojiData, importEmojiData } from './loader'; +import { EMOJI_DB_NAME_SHORTCODES, EMOJI_TYPE_CUSTOM } from './constants'; +import { + importCustomEmojiData, + importEmojiData, + importLegacyShortcodes, +} from './loader'; addEventListener('message', handleMessage); self.postMessage('ready'); // After the worker is ready, notify the main thread @@ -12,8 +17,10 @@ function handleMessage(event: MessageEvent<{ locale: string; path?: string }>) { async function loadData(locale: string, path?: string) { let importCount: number | undefined; - if (locale === 'custom') { + if (locale === EMOJI_TYPE_CUSTOM) { importCount = (await importCustomEmojiData())?.length; + } else if (locale === EMOJI_DB_NAME_SHORTCODES) { + importCount = (await importLegacyShortcodes()).length; } else if (path) { importCount = (await importEmojiData(locale, path))?.length; } else { diff --git a/app/javascript/flavours/glitch/utils/types.ts b/app/javascript/flavours/glitch/utils/types.ts index eb45881ee47ca8..019b074813857b 100644 --- a/app/javascript/flavours/glitch/utils/types.ts +++ b/app/javascript/flavours/glitch/utils/types.ts @@ -15,6 +15,8 @@ export type SomeRequired = T & Required>; export type SomeOptional = Pick> & Partial>; +export type RequiredExcept = SomeOptional, K>; + export type OmitValueType = { [K in keyof T as T[K] extends V ? never : K]: T[K]; }; From 0551455a3cba7e819dd22a418b0b170ce90eabd6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 15 Dec 2025 13:53:21 +0100 Subject: [PATCH 792/853] [Glitch] Update devDependencies (non-major) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: ChaosExAnima Signed-off-by: Claire --- .../glitch/api_types/notifications.ts | 9 ++--- .../glitch/components/button/index.tsx | 6 ++-- .../glitch/components/dropdown_menu.tsx | 2 +- .../flavours/glitch/entrypoints/admin.tsx | 5 ++- app/javascript/flavours/glitch/main.tsx | 5 ++- .../flavours/glitch/models/account.ts | 7 ++-- .../glitch/models/notification_group.ts | 34 ++++++++++--------- .../glitch/models/notification_request.ts | 6 ++-- app/javascript/flavours/glitch/models/poll.ts | 6 ++-- 9 files changed, 41 insertions(+), 39 deletions(-) diff --git a/app/javascript/flavours/glitch/api_types/notifications.ts b/app/javascript/flavours/glitch/api_types/notifications.ts index c4556fa8e5577a..50b03cc109e3c7 100644 --- a/app/javascript/flavours/glitch/api_types/notifications.ts +++ b/app/javascript/flavours/glitch/api_types/notifications.ts @@ -102,8 +102,7 @@ export interface ApiAccountWarningJSON { appeal: unknown; } -interface ModerationWarningNotificationGroupJSON - extends BaseNotificationGroupJSON { +interface ModerationWarningNotificationGroupJSON extends BaseNotificationGroupJSON { type: 'moderation_warning'; moderation_warning: ApiAccountWarningJSON; } @@ -123,14 +122,12 @@ export interface ApiAccountRelationshipSeveranceEventJSON { created_at: string; } -interface AccountRelationshipSeveranceNotificationGroupJSON - extends BaseNotificationGroupJSON { +interface AccountRelationshipSeveranceNotificationGroupJSON extends BaseNotificationGroupJSON { type: 'severed_relationships'; event: ApiAccountRelationshipSeveranceEventJSON; } -interface AccountRelationshipSeveranceNotificationJSON - extends BaseNotificationJSON { +interface AccountRelationshipSeveranceNotificationJSON extends BaseNotificationJSON { type: 'severed_relationships'; event: ApiAccountRelationshipSeveranceEventJSON; } diff --git a/app/javascript/flavours/glitch/components/button/index.tsx b/app/javascript/flavours/glitch/components/button/index.tsx index c6300bd6846242..fb107c78e0047d 100644 --- a/app/javascript/flavours/glitch/components/button/index.tsx +++ b/app/javascript/flavours/glitch/components/button/index.tsx @@ -5,8 +5,10 @@ import classNames from 'classnames'; import { LoadingIndicator } from 'flavours/glitch/components/loading_indicator'; -interface BaseProps - extends Omit, 'children'> { +interface BaseProps extends Omit< + React.ButtonHTMLAttributes, + 'children' +> { block?: boolean; secondary?: boolean; plain?: boolean; diff --git a/app/javascript/flavours/glitch/components/dropdown_menu.tsx b/app/javascript/flavours/glitch/components/dropdown_menu.tsx index 52a6072ee7e655..fa196a8bdb61d7 100644 --- a/app/javascript/flavours/glitch/components/dropdown_menu.tsx +++ b/app/javascript/flavours/glitch/components/dropdown_menu.tsx @@ -309,7 +309,7 @@ interface DropdownProps { renderItem?: RenderItemFn; renderHeader?: RenderHeaderFn; onOpen?: // Must use a union type for the full function as a union with void is not allowed. - | ((event: React.MouseEvent | React.KeyboardEvent) => void) + | ((event: React.MouseEvent | React.KeyboardEvent) => void) | ((event: React.MouseEvent | React.KeyboardEvent) => boolean); onItemClick?: ItemClickFn; } diff --git a/app/javascript/flavours/glitch/entrypoints/admin.tsx b/app/javascript/flavours/glitch/entrypoints/admin.tsx index 25680391d40baa..1ec50cf59ef905 100644 --- a/app/javascript/flavours/glitch/entrypoints/admin.tsx +++ b/app/javascript/flavours/glitch/entrypoints/admin.tsx @@ -256,9 +256,8 @@ async function mountReactComponent(element: Element) { const componentProps = JSON.parse(stringProps) as object; - const { default: AdminComponent } = await import( - '@/flavours/glitch/containers/admin_component' - ); + const { default: AdminComponent } = + await import('@/flavours/glitch/containers/admin_component'); const { default: Component } = (await import( `@/flavours/glitch/components/admin/${componentName}.jsx` diff --git a/app/javascript/flavours/glitch/main.tsx b/app/javascript/flavours/glitch/main.tsx index 167f8df476db81..d91cd2bcff633e 100644 --- a/app/javascript/flavours/glitch/main.tsx +++ b/app/javascript/flavours/glitch/main.tsx @@ -55,9 +55,8 @@ function main() { 'Notification' in window && Notification.permission === 'granted' ) { - const registerPushNotifications = await import( - 'flavours/glitch/actions/push_notifications' - ); + const registerPushNotifications = + await import('flavours/glitch/actions/push_notifications'); store.dispatch(registerPushNotifications.register()); } diff --git a/app/javascript/flavours/glitch/models/account.ts b/app/javascript/flavours/glitch/models/account.ts index 316455534557fb..a8410662d98933 100644 --- a/app/javascript/flavours/glitch/models/account.ts +++ b/app/javascript/flavours/glitch/models/account.ts @@ -42,10 +42,9 @@ const AccountRoleFactory = ImmutableRecord({ }); // Account -export interface AccountShape - extends Required< - Omit - > { +export interface AccountShape extends Required< + Omit +> { emojis: ImmutableList; fields: ImmutableList; roles: ImmutableList; diff --git a/app/javascript/flavours/glitch/models/notification_group.ts b/app/javascript/flavours/glitch/models/notification_group.ts index 886ab5a639feb1..29db886b5efcbd 100644 --- a/app/javascript/flavours/glitch/models/notification_group.ts +++ b/app/javascript/flavours/glitch/models/notification_group.ts @@ -14,20 +14,24 @@ import type { ApiReportJSON } from 'flavours/glitch/api_types/reports'; // This corresponds to the max length of `group.sampleAccountIds` export const NOTIFICATIONS_GROUP_MAX_AVATARS = 8; -interface BaseNotificationGroup - extends Omit { +interface BaseNotificationGroup extends Omit< + BaseNotificationGroupJSON, + 'sample_account_ids' +> { sampleAccountIds: string[]; partial: boolean; } -interface BaseNotificationWithStatus - extends BaseNotificationGroup { +interface BaseNotificationWithStatus< + Type extends NotificationWithStatusType, +> extends BaseNotificationGroup { type: Type; statusId: string | undefined; } -interface BaseNotification - extends BaseNotificationGroup { +interface BaseNotification< + Type extends NotificationType, +> extends BaseNotificationGroup { type: Type; } @@ -53,26 +57,25 @@ export type AccountWarningAction = | 'sensitive' | 'silence' | 'suspend'; -export interface AccountWarning - extends Omit { +export interface AccountWarning extends Omit< + ApiAccountWarningJSON, + 'target_account' +> { targetAccountId: string; } -export interface NotificationGroupModerationWarning - extends BaseNotification<'moderation_warning'> { +export interface NotificationGroupModerationWarning extends BaseNotification<'moderation_warning'> { moderationWarning: AccountWarning; } type AccountRelationshipSeveranceEvent = ApiAccountRelationshipSeveranceEventJSON; -export interface NotificationGroupSeveredRelationships - extends BaseNotification<'severed_relationships'> { +export interface NotificationGroupSeveredRelationships extends BaseNotification<'severed_relationships'> { event: AccountRelationshipSeveranceEvent; } type AnnualReportEvent = ApiAnnualReportEventJSON; -export interface NotificationGroupAnnualReport - extends BaseNotification<'annual_report'> { +export interface NotificationGroupAnnualReport extends BaseNotification<'annual_report'> { annualReport: AnnualReportEvent; } @@ -80,8 +83,7 @@ interface Report extends Omit { targetAccountId: string; } -export interface NotificationGroupAdminReport - extends BaseNotification<'admin.report'> { +export interface NotificationGroupAdminReport extends BaseNotification<'admin.report'> { report: Report; } diff --git a/app/javascript/flavours/glitch/models/notification_request.ts b/app/javascript/flavours/glitch/models/notification_request.ts index 4b4b97758fc4ba..be4a2bcf30ebd8 100644 --- a/app/javascript/flavours/glitch/models/notification_request.ts +++ b/app/javascript/flavours/glitch/models/notification_request.ts @@ -1,7 +1,9 @@ import type { ApiNotificationRequestJSON } from 'flavours/glitch/api_types/notifications'; -export interface NotificationRequest - extends Omit { +export interface NotificationRequest extends Omit< + ApiNotificationRequestJSON, + 'account' | 'notifications_count' +> { account_id: string; notifications_count: number; } diff --git a/app/javascript/flavours/glitch/models/poll.ts b/app/javascript/flavours/glitch/models/poll.ts index 03f61fd6be6474..7559e6f12c09b0 100644 --- a/app/javascript/flavours/glitch/models/poll.ts +++ b/app/javascript/flavours/glitch/models/poll.ts @@ -28,8 +28,10 @@ export function createPollOptionTranslationFromServerJSON(translation: { } as PollOptionTranslation; } -export interface Poll - extends Omit { +export interface Poll extends Omit< + ApiPollJSON, + 'emojis' | 'options' | 'own_votes' +> { emojis: CustomEmoji[]; options: PollOption[]; own_votes?: number[]; From 080110472947508f0236278a74550a7dd2346466 Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 16 Dec 2025 09:49:48 +0100 Subject: [PATCH 793/853] Fix mentions of domain-blocked users being processed (#37257) --- app/services/process_mentions_service.rb | 2 +- spec/services/process_mentions_service_spec.rb | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/services/process_mentions_service.rb b/app/services/process_mentions_service.rb index 6906f77e1eeaf0..c2c33689ea0a86 100644 --- a/app/services/process_mentions_service.rb +++ b/app/services/process_mentions_service.rb @@ -71,7 +71,7 @@ def assign_mentions! # Make sure we never mention blocked accounts unless @current_mentions.empty? mentioned_domains = @current_mentions.filter_map { |m| m.account.domain }.uniq - blocked_domains = Set.new(mentioned_domains.empty? ? [] : AccountDomainBlock.where(account_id: @status.account_id, domain: mentioned_domains)) + blocked_domains = Set.new(mentioned_domains.empty? ? [] : AccountDomainBlock.where(account_id: @status.account_id, domain: mentioned_domains).pluck(:domain)) mentioned_account_ids = @current_mentions.map(&:account_id) blocked_account_ids = Set.new(@status.account.block_relationships.where(target_account_id: mentioned_account_ids).pluck(:target_account_id)) diff --git a/spec/services/process_mentions_service_spec.rb b/spec/services/process_mentions_service_spec.rb index 3cc83d82f3cb08..61faf3d04a0582 100644 --- a/spec/services/process_mentions_service_spec.rb +++ b/spec/services/process_mentions_service_spec.rb @@ -8,9 +8,9 @@ let(:account) { Fabricate(:account, username: 'alice') } context 'when mentions contain blocked accounts' do - let(:non_blocked_account) { Fabricate(:account) } - let(:individually_blocked_account) { Fabricate(:account) } - let(:domain_blocked_account) { Fabricate(:account, domain: 'evil.com') } + let!(:non_blocked_account) { Fabricate(:account) } + let!(:individually_blocked_account) { Fabricate(:account) } + let!(:domain_blocked_account) { Fabricate(:account, domain: 'evil.com', protocol: :activitypub) } let(:status) { Fabricate(:status, account: account, text: "Hello @#{non_blocked_account.acct} @#{individually_blocked_account.acct} @#{domain_blocked_account.acct}", visibility: :public) } before do From 71821eb9c1f36fef7a515c2a0c5cf104054b5206 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 16 Dec 2025 10:45:59 +0100 Subject: [PATCH 794/853] Update dependency tzinfo-data to v1.2025.3 (#37242) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index c40b45088dd857..7664743aa27882 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -166,7 +166,7 @@ GEM climate_control (1.2.0) cocoon (1.2.15) color_diff (0.1) - concurrent-ruby (1.3.5) + concurrent-ruby (1.3.6) connection_pool (2.5.5) cose (1.3.1) cbor (~> 0.5.9) @@ -880,7 +880,7 @@ GEM unf (~> 0.1.0) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - tzinfo-data (1.2025.2) + tzinfo-data (1.2025.3) tzinfo (>= 1.0.0) unf (0.1.4) unf_ext From 4c679c698f77daf14949ca29d0000e3df6c13f73 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 16 Dec 2025 09:46:39 +0000 Subject: [PATCH 795/853] Update dependency vite-tsconfig-paths to v6 (#37247) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 38da4d371e38dd..794b123385d4b3 100644 --- a/package.json +++ b/package.json @@ -121,7 +121,7 @@ "vite-plugin-manifest-sri": "^0.2.0", "vite-plugin-pwa": "^1.0.2", "vite-plugin-svgr": "^4.3.0", - "vite-tsconfig-paths": "^5.1.4", + "vite-tsconfig-paths": "^6.0.0", "wicg-inert": "^3.1.2", "workbox-expiration": "^7.3.0", "workbox-routing": "^7.3.0", diff --git a/yarn.lock b/yarn.lock index c5c229eb09f251..96ace4299b0027 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2884,7 +2884,7 @@ __metadata: vite-plugin-manifest-sri: "npm:^0.2.0" vite-plugin-pwa: "npm:^1.0.2" vite-plugin-svgr: "npm:^4.3.0" - vite-tsconfig-paths: "npm:^5.1.4" + vite-tsconfig-paths: "npm:^6.0.0" vitest: "npm:^4.0.5" wicg-inert: "npm:^3.1.2" workbox-expiration: "npm:^7.3.0" @@ -14068,9 +14068,9 @@ __metadata: languageName: node linkType: hard -"vite-tsconfig-paths@npm:^5.1.4": - version: 5.1.4 - resolution: "vite-tsconfig-paths@npm:5.1.4" +"vite-tsconfig-paths@npm:^6.0.0": + version: 6.0.1 + resolution: "vite-tsconfig-paths@npm:6.0.1" dependencies: debug: "npm:^4.1.1" globrex: "npm:^0.1.2" @@ -14080,7 +14080,7 @@ __metadata: peerDependenciesMeta: vite: optional: true - checksum: 10c0/6228f23155ea25d92b1e1702284cf8dc52ad3c683c5ca691edd5a4c82d2913e7326d00708cef1cbfde9bb226261df0e0a12e03ef1d43b6a92d8f02b483ef37e3 + checksum: 10c0/c0702f1d2b9d2e3e6ebb44d8e9c27b17b1102e86946ab54b6bbd290419b134e84df4e451b55db973bc97d9de5689df6f67e479633df20244aa0c62ffd0b16e43 languageName: node linkType: hard From 550a6d4765e5af144052b9fb6cdc5d3a4e958a87 Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 16 Dec 2025 10:47:18 +0100 Subject: [PATCH 796/853] Add wrapstodon to initial state and show wrapstodon sidebar item on load (#37261) --- .../api/v1/annual_reports_controller.rb | 19 +++++-------------- app/javascript/mastodon/initial_state.ts | 7 +++++++ .../mastodon/reducers/slices/annual_report.ts | 11 ++++++++--- app/lib/annual_report.rb | 19 +++++++++++++++++++ app/serializers/initial_state_serializer.rb | 11 +++++++++++ 5 files changed, 50 insertions(+), 17 deletions(-) diff --git a/app/controllers/api/v1/annual_reports_controller.rb b/app/controllers/api/v1/annual_reports_controller.rb index 724c7658d7247b..71a97e1d9a68b2 100644 --- a/app/controllers/api/v1/annual_reports_controller.rb +++ b/app/controllers/api/v1/annual_reports_controller.rb @@ -57,27 +57,18 @@ def read render_empty end - def refresh_key - "wrapstodon:#{current_account.id}:#{year}" - end - private def report_state - return 'available' if GeneratedAnnualReport.exists?(account_id: current_account.id, year: year) - - async_refresh = AsyncRefresh.new(refresh_key) - - if async_refresh.running? + AnnualReport.new(current_account, year).state do |async_refresh| add_async_refresh_header(async_refresh, retry_seconds: 2) - 'generating' - elsif AnnualReport.current_campaign == year && AnnualReport.new(current_account, year).eligible? - 'eligible' - else - 'ineligible' end end + def refresh_key + "wrapstodon:#{current_account.id}:#{year}" + end + def year params[:id]&.to_i end diff --git a/app/javascript/mastodon/initial_state.ts b/app/javascript/mastodon/initial_state.ts index 3bfd48a76b9f0d..358c307c30f015 100644 --- a/app/javascript/mastodon/initial_state.ts +++ b/app/javascript/mastodon/initial_state.ts @@ -2,6 +2,11 @@ import type { ApiAccountJSON } from './api_types/accounts'; type InitialStateLanguage = [code: string, name: string, localName: string]; +interface InitialWrapstodonState { + year: number; + state: 'available' | 'generating' | 'eligible' | 'ineligible'; +} + interface InitialStateMeta { access_token: string; advanced_layout?: boolean; @@ -47,6 +52,7 @@ interface InitialStateMeta { status_page_url: string; terms_of_service_enabled: boolean; emoji_style?: string; + wrapstodon?: InitialWrapstodonState | null; } interface Role { @@ -128,6 +134,7 @@ export const criticalUpdatesPending = initialState?.critical_updates_pending; export const statusPageUrl = getMeta('status_page_url'); export const sso_redirect = getMeta('sso_redirect'); export const termsOfServiceEnabled = getMeta('terms_of_service_enabled'); +export const wrapstodon = getMeta('wrapstodon'); const displayNames = // Intl.DisplayNames can be undefined in old browsers diff --git a/app/javascript/mastodon/reducers/slices/annual_report.ts b/app/javascript/mastodon/reducers/slices/annual_report.ts index a687f558e1786f..5e7f44798a4df9 100644 --- a/app/javascript/mastodon/reducers/slices/annual_report.ts +++ b/app/javascript/mastodon/reducers/slices/annual_report.ts @@ -11,6 +11,7 @@ import { apiGetAnnualReportState, apiRequestGenerateAnnualReport, } from '@/mastodon/api/annual_report'; +import { wrapstodon } from '@/mastodon/initial_state'; import type { AnnualReport } from '@/mastodon/models/annual_report'; import { @@ -20,13 +21,17 @@ import { } from '../../store/typed_functions'; interface AnnualReportState { + year?: number; state?: ApiAnnualReportState; report?: AnnualReport; } const annualReportSlice = createSlice({ name: 'annualReport', - initialState: {} as AnnualReportState, + initialState: { + year: wrapstodon?.year, + state: wrapstodon?.state, + } as AnnualReportState, reducers: { setReport(state, action: PayloadAction) { state.report = action.payload; @@ -53,8 +58,8 @@ export const annualReport = annualReportSlice.reducer; export const { setReport } = annualReportSlice.actions; export const selectWrapstodonYear = createAppSelector( - [(state) => state.server.getIn(['server', 'wrapstodon'])], - (year: unknown) => (typeof year === 'number' && year > 2000 ? year : null), + [(state) => state.annualReport.year], + (year: number | null | undefined) => year ?? null, ); // This kicks everything off, and is called after fetching the server info. diff --git a/app/lib/annual_report.rb b/app/lib/annual_report.rb index a9c9135ed46377..f487cb883f87e0 100644 --- a/app/lib/annual_report.rb +++ b/app/lib/annual_report.rb @@ -34,6 +34,25 @@ def eligible? end end + def state + return 'available' if GeneratedAnnualReport.exists?(account_id: @account.id, year: @year) + + async_refresh = AsyncRefresh.new(refresh_key) + + if async_refresh.running? + yield async_refresh if block_given? + 'generating' + elsif AnnualReport.current_campaign == @year && eligible? + 'eligible' + else + 'ineligible' + end + end + + def refresh_key + "wrapstodon:#{@account.id}:#{@year}" + end + def generate return if GeneratedAnnualReport.exists?(account: @account, year: @year) diff --git a/app/serializers/initial_state_serializer.rb b/app/serializers/initial_state_serializer.rb index 5f8921e246adac..fe2a857d50970d 100644 --- a/app/serializers/initial_state_serializer.rb +++ b/app/serializers/initial_state_serializer.rb @@ -32,6 +32,7 @@ def meta store[:use_pending_items] = object_account_user.setting_use_pending_items store[:show_trends] = Setting.trends && object_account_user.setting_trends store[:emoji_style] = object_account_user.settings['web.emoji_style'] + store[:wrapstodon] = wrapstodon else store[:auto_play_gif] = Setting.auto_play_gif store[:display_media] = Setting.display_media @@ -94,6 +95,16 @@ def features private + def wrapstodon + current_campaign = AnnualReport.current_campaign + return if current_campaign.blank? + + { + year: current_campaign, + state: AnnualReport.new(object.current_account, current_campaign).state, + } + end + def default_meta_store { access_token: object.token, From c8f608839b958aec51f94354c8a8a0223250ebd3 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 16 Dec 2025 05:13:43 -0500 Subject: [PATCH 797/853] Use bundler version 4.0.1 (#37191) --- Gemfile | 2 +- Gemfile.lock | 68 ++++++++++++++++++++++++++-------------------------- package.json | 2 +- yarn.lock | 20 ++++++++-------- 4 files changed, 46 insertions(+), 46 deletions(-) diff --git a/Gemfile b/Gemfile index 60dc80a9bc0494..0a7c00b11e343b 100644 --- a/Gemfile +++ b/Gemfile @@ -138,7 +138,7 @@ group :test do # Browser integration testing gem 'capybara', '~> 3.39' gem 'capybara-playwright-driver' - gem 'playwright-ruby-client', '1.56.0', require: false # Pinning the exact version as it needs to be kept in sync with the installed npm package + gem 'playwright-ruby-client', '1.57.0', require: false # Pinning the exact version as it needs to be kept in sync with the installed npm package # Used to reset the database between system tests gem 'database_cleaner-active_record' diff --git a/Gemfile.lock b/Gemfile.lock index 7664743aa27882..0692e07135ac2a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -96,7 +96,7 @@ GEM ast (2.4.3) attr_required (1.0.2) aws-eventstream (1.4.0) - aws-partitions (1.1190.0) + aws-partitions (1.1194.0) aws-sdk-core (3.239.2) aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.992.0) @@ -108,7 +108,7 @@ GEM aws-sdk-kms (1.118.0) aws-sdk-core (~> 3, >= 3.239.1) aws-sigv4 (~> 1.5) - aws-sdk-s3 (1.206.0) + aws-sdk-s3 (1.207.0) aws-sdk-core (~> 3, >= 3.234.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.5) @@ -182,7 +182,7 @@ GEM activerecord (>= 5.a) database_cleaner-core (~> 2.0) database_cleaner-core (2.0.1) - date (3.5.0) + date (3.5.1) debug (1.11.0) irb (~> 1.10) reline (>= 0.3.8) @@ -208,7 +208,7 @@ GEM domain_name (0.6.20240107) doorkeeper (5.8.2) railties (>= 5) - dotenv (3.1.8) + dotenv (3.2.0) drb (2.2.3) dry-cli (1.3.0) elasticsearch (7.17.11) @@ -227,11 +227,11 @@ GEM mail (~> 2.7) email_validator (2.2.4) activemodel - erb (5.1.3) + erb (6.0.1) erubi (1.13.1) et-orbi (1.4.0) tzinfo - excon (1.3.0) + excon (1.3.2) logger fabrication (3.0.0) faker (3.5.3) @@ -244,8 +244,8 @@ GEM faraday (>= 1, < 3) faraday-httpclient (2.0.2) httpclient (>= 2.2) - faraday-net_http (3.4.1) - net-http (>= 0.5.0) + faraday-net_http (3.4.2) + net-http (~> 0.5) fast_blank (1.0.1) fastimage (2.4.0) ffi (1.17.2) @@ -269,20 +269,20 @@ GEM fog-openstack (1.1.5) fog-core (~> 2.1) fog-json (>= 1.0) - formatador (1.2.1) + formatador (1.2.3) reline forwardable (1.3.3) - fugit (1.12.0) + fugit (1.12.1) et-orbi (~> 1.4) raabro (~> 1.4) globalid (1.3.0) activesupport (>= 6.1) - google-protobuf (4.32.1) + google-protobuf (4.33.2) bigdecimal rake (>= 13) googleapis-common-protos-types (1.22.0) google-protobuf (~> 4.26) - haml (6.4.0) + haml (7.1.0) temple (>= 0.8.2) thor tilt @@ -291,7 +291,7 @@ GEM activesupport (>= 5.1) haml (>= 4.0.6) railties (>= 5.1) - haml_lint (0.67.0) + haml_lint (0.68.0) haml (>= 5.0) parallel (~> 1.10) rainbow @@ -340,7 +340,7 @@ GEM inline_svg (1.10.0) activesupport (>= 3.0) nokogiri (>= 1.6) - io-console (0.8.1) + io-console (0.8.2) irb (1.15.3) pp (>= 0.6.0) rdoc (>= 4.0.0) @@ -350,7 +350,7 @@ GEM azure-blob (~> 0.5.2) hashie (~> 5.0) jmespath (1.6.2) - json (2.16.0) + json (2.18.0) json-canonicalization (1.0.0) json-jwt (1.17.0) activesupport (>= 4.2) @@ -447,13 +447,13 @@ GEM mime-types-data (3.2025.0924) mini_mime (1.1.5) mini_portile2 (2.8.9) - minitest (5.26.2) + minitest (5.27.0) msgpack (1.8.0) - multi_json (1.17.0) + multi_json (1.18.0) mutex_m (0.3.0) net-http (0.6.0) uri - net-imap (0.5.12) + net-imap (0.6.0) date net-protocol net-ldap (0.20.0) @@ -465,7 +465,7 @@ GEM timeout net-smtp (0.5.1) net-protocol - nio4r (2.7.4) + nio4r (2.7.5) nokogiri (1.18.10) mini_portile2 (~> 2.8.2) racc (~> 1.4) @@ -594,7 +594,7 @@ GEM pg (1.6.2) pghero (3.7.0) activerecord (>= 7.1) - playwright-ruby-client (1.56.0) + playwright-ruby-client (1.57.0) concurrent-ruby (>= 1.1.6) mime-types (>= 3.0) pp (0.6.3) @@ -615,7 +615,7 @@ GEM actionpack (>= 7.0.0) activesupport (>= 7.0.0) rack - psych (5.2.6) + psych (5.3.0) date stringio public_suffix (7.0.0) @@ -631,7 +631,7 @@ GEM rack-cors (3.0.0) logger rack (>= 3.0.14) - rack-oauth2 (2.2.1) + rack-oauth2 (2.3.0) activesupport attr_required faraday (~> 2.0) @@ -649,7 +649,7 @@ GEM rack (>= 3.0.0) rack-test (2.2.0) rack (>= 1.3) - rackup (2.2.1) + rackup (2.3.1) rack (>= 3) rails (8.0.3) actioncable (= 8.0.3) @@ -695,7 +695,7 @@ GEM readline (~> 0.0) rdf-normalize (0.7.0) rdf (~> 3.3) - rdoc (6.15.1) + rdoc (6.17.0) erb psych (>= 4.0.0) tsort @@ -721,18 +721,18 @@ GEM chunky_png (~> 1.0) rqrcode_core (~> 2.0) rqrcode_core (2.0.1) - rspec (3.13.1) + rspec (3.13.2) rspec-core (~> 3.13.0) rspec-expectations (~> 3.13.0) rspec-mocks (~> 3.13.0) - rspec-core (3.13.5) + rspec-core (3.13.6) rspec-support (~> 3.13.0) rspec-expectations (3.13.5) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) rspec-github (3.0.0) rspec-core (~> 3.0) - rspec-mocks (3.13.5) + rspec-mocks (3.13.7) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) rspec-rails (8.0.2) @@ -820,7 +820,7 @@ GEM sidekiq-scheduler (6.0.1) rufus-scheduler (~> 3.2) sidekiq (>= 7.3, < 9) - sidekiq-unique-jobs (8.0.11) + sidekiq-unique-jobs (8.0.12) concurrent-ruby (~> 1.0, >= 1.0.5) sidekiq (>= 7.0.0, < 9.0.0) thor (>= 1.0, < 3.0) @@ -842,7 +842,7 @@ GEM stoplight (5.7.0) concurrent-ruby zeitwerk - stringio (3.1.8) + stringio (3.1.9) strong_migrations (2.5.1) activerecord (>= 7.1) swd (2.0.3) @@ -859,7 +859,7 @@ GEM test-prof (1.5.0) thor (1.4.0) tilt (2.6.1) - timeout (0.4.3) + timeout (0.5.0) tpm-key_attestation (0.14.1) bindata (~> 2.4) openssl (> 2.0) @@ -920,7 +920,7 @@ GEM addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) - webrick (1.9.1) + webrick (1.9.2) websocket-driver (0.8.0) base64 websocket-extensions (>= 0.1.0) @@ -1033,7 +1033,7 @@ DEPENDENCIES parslet pg (~> 1.5) pghero - playwright-ruby-client (= 1.56.0) + playwright-ruby-client (= 1.57.0) premailer-rails prometheus_exporter (~> 2.2) propshaft @@ -1090,7 +1090,7 @@ DEPENDENCIES xorcist (~> 1.1) RUBY VERSION - ruby 3.4.1p0 + ruby 3.4.1p0 BUNDLED WITH - 2.7.2 + 4.0.1 diff --git a/package.json b/package.json index 794b123385d4b3..8a1ecc77374d54 100644 --- a/package.json +++ b/package.json @@ -180,7 +180,7 @@ "lint-staged": "^16.2.6", "msw": "^2.12.1", "msw-storybook-addon": "^2.0.6", - "playwright": "^1.56.1", + "playwright": "^1.57.0", "prettier": "^3.3.3", "react-test-renderer": "^18.2.0", "storybook": "^10.0.5", diff --git a/yarn.lock b/yarn.lock index 96ace4299b0027..cac2a0c716b82b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2838,7 +2838,7 @@ __metadata: msw: "npm:^2.12.1" msw-storybook-addon: "npm:^2.0.6" path-complete-extname: "npm:^1.0.0" - playwright: "npm:^1.56.1" + playwright: "npm:^1.57.0" postcss-preset-env: "npm:^10.1.5" prettier: "npm:^3.3.3" prop-types: "npm:^15.8.1" @@ -10542,27 +10542,27 @@ __metadata: languageName: node linkType: hard -"playwright-core@npm:1.56.1": - version: 1.56.1 - resolution: "playwright-core@npm:1.56.1" +"playwright-core@npm:1.57.0": + version: 1.57.0 + resolution: "playwright-core@npm:1.57.0" bin: playwright-core: cli.js - checksum: 10c0/ffd40142b99c68678b387445d5b42f1fee4ab0b65d983058c37f342e5629f9cdbdac0506ea80a0dfd41a8f9f13345bad54e9a8c35826ef66dc765f4eb3db8da7 + checksum: 10c0/798e35d83bf48419a8c73de20bb94d68be5dde68de23f95d80a0ebe401e3b83e29e3e84aea7894d67fa6c79d2d3d40cc5bcde3e166f657ce50987aaa2421b6a9 languageName: node linkType: hard -"playwright@npm:^1.56.1": - version: 1.56.1 - resolution: "playwright@npm:1.56.1" +"playwright@npm:^1.57.0": + version: 1.57.0 + resolution: "playwright@npm:1.57.0" dependencies: fsevents: "npm:2.3.2" - playwright-core: "npm:1.56.1" + playwright-core: "npm:1.57.0" dependenciesMeta: fsevents: optional: true bin: playwright: cli.js - checksum: 10c0/8e9965aede86df0f4722063385748498977b219630a40a10d1b82b8bd8d4d4e9b6b65ecbfa024331a30800163161aca292fb6dd7446c531a1ad25f4155625ab4 + checksum: 10c0/ab03c99a67b835bdea9059f516ad3b6e42c21025f9adaa161a4ef6bc7ca716dcba476d287140bb240d06126eb23f889a8933b8f5f1f1a56b80659d92d1358899 languageName: node linkType: hard From 7230c2059f1599809f812feeaad94c77aebf113e Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 16 Dec 2025 05:24:27 -0500 Subject: [PATCH 798/853] Add coverage for "domain variants" consumers (#35995) --- app/models/domain_allow.rb | 2 +- spec/models/domain_allow_spec.rb | 23 +++++++++++++ spec/models/domain_block_spec.rb | 11 ++++++ spec/models/email_domain_block_spec.rb | 42 ++++++++++++++++++++--- spec/models/preview_card_provider_spec.rb | 32 +++++++++++++++++ 5 files changed, 105 insertions(+), 5 deletions(-) diff --git a/app/models/domain_allow.rb b/app/models/domain_allow.rb index 8eab3164e5b2b3..783269bf258831 100644 --- a/app/models/domain_allow.rb +++ b/app/models/domain_allow.rb @@ -33,7 +33,7 @@ def allowed_domains def rule_for(domain) return if domain.blank? - uri = Addressable::URI.new.tap { |u| u.host = domain.delete('/') } + uri = Addressable::URI.new.tap { |u| u.host = domain.strip.delete('/') } find_by(domain: uri.normalized_host) end diff --git a/spec/models/domain_allow_spec.rb b/spec/models/domain_allow_spec.rb index 0c69aaff8dc84d..ac0c113d3a9ca3 100644 --- a/spec/models/domain_allow_spec.rb +++ b/spec/models/domain_allow_spec.rb @@ -27,4 +27,27 @@ it { is_expected.to contain_exactly(allowed_domain.domain, other_allowed_domain.domain) } end end + + describe '.rule_for' do + subject { described_class.rule_for(domain) } + + let(:domain) { 'host.example' } + + context 'with no records' do + it { is_expected.to be_nil } + end + + context 'with matching record' do + let!(:domain_allow) { Fabricate :domain_allow, domain: } + + it { is_expected.to eq(domain_allow) } + end + + context 'when called with non normalized string' do + let!(:domain_allow) { Fabricate :domain_allow, domain: } + let(:domain) { ' HOST.example/' } + + it { is_expected.to eq(domain_allow) } + end + end end diff --git a/spec/models/domain_block_spec.rb b/spec/models/domain_block_spec.rb index 14f904ea7fa6a5..e7f463c8f569a4 100644 --- a/spec/models/domain_block_spec.rb +++ b/spec/models/domain_block_spec.rb @@ -35,6 +35,17 @@ expect(described_class.rule_for('example.com')).to eq block end + it 'returns most specific rule matching a blocked domain' do + _block = Fabricate(:domain_block, domain: 'example.com') + blog_block = Fabricate(:domain_block, domain: 'blog.example.com') + expect(described_class.rule_for('host.blog.example.com')).to eq blog_block + end + + it 'returns rule matching a blocked domain when string needs normalization' do + block = Fabricate(:domain_block, domain: 'example.com') + expect(described_class.rule_for(' example.com/')).to eq block + end + it 'returns a rule matching a subdomain of a blocked domain' do block = Fabricate(:domain_block, domain: 'example.com') expect(described_class.rule_for('sub.example.com')).to eq block diff --git a/spec/models/email_domain_block_spec.rb b/spec/models/email_domain_block_spec.rb index 5874c5e53c4595..c3662b2d6cd83f 100644 --- a/spec/models/email_domain_block_spec.rb +++ b/spec/models/email_domain_block_spec.rb @@ -4,6 +4,8 @@ RSpec.describe EmailDomainBlock do describe 'block?' do + subject { described_class.block?(input) } + let(:input) { nil } context 'when given an e-mail address' do @@ -14,12 +16,12 @@ it 'returns true if the domain is blocked' do Fabricate(:email_domain_block, domain: 'example.com') - expect(described_class.block?(input)).to be true + expect(subject).to be true end it 'returns false if the domain is not blocked' do Fabricate(:email_domain_block, domain: 'other-example.com') - expect(described_class.block?(input)).to be false + expect(subject).to be false end end @@ -28,7 +30,7 @@ it 'returns true if it is a subdomain of a blocked domain' do Fabricate(:email_domain_block, domain: 'example.com') - expect(described_class.block?(input)).to be true + expect(subject).to be true end end end @@ -38,8 +40,40 @@ it 'returns true if the domain is blocked' do Fabricate(:email_domain_block, domain: 'mail.foo.com') - expect(described_class.block?(input)).to be true + expect(subject).to be true end end + + context 'when given nil' do + it { is_expected.to be false } + end + + context 'when given empty string' do + let(:input) { '' } + + it { is_expected.to be true } + end + end + + describe '.requires_approval?' do + subject { described_class.requires_approval?(input) } + + let(:input) { nil } + + context 'with a matching block requiring approval' do + before { Fabricate :email_domain_block, domain: input, allow_with_approval: true } + + let(:input) { 'host.example' } + + it { is_expected.to be true } + end + + context 'with a matching block not requiring approval' do + before { Fabricate :email_domain_block, domain: input, allow_with_approval: false } + + let(:input) { 'host.example' } + + it { is_expected.to be false } + end end end diff --git a/spec/models/preview_card_provider_spec.rb b/spec/models/preview_card_provider_spec.rb index 561c93d0b2571d..cd3283faa3f0aa 100644 --- a/spec/models/preview_card_provider_spec.rb +++ b/spec/models/preview_card_provider_spec.rb @@ -25,4 +25,36 @@ end end end + + describe '.matching_domain' do + subject { described_class.matching_domain(domain) } + + let(:domain) { 'host.example' } + + context 'without matching domains' do + it { is_expected.to be_nil } + end + + context 'with exact matching domain' do + let!(:preview_card_provider) { Fabricate :preview_card_provider, domain: 'host.example' } + + it { is_expected.to eq(preview_card_provider) } + end + + context 'with matching domain segment' do + let!(:preview_card_provider) { Fabricate :preview_card_provider, domain: 'host.example' } + let(:domain) { 'www.blog.host.example' } + + it { is_expected.to eq(preview_card_provider) } + end + + context 'with multiple matching records' do + let!(:preview_card_provider_more) { Fabricate :preview_card_provider, domain: 'blog.host.example' } + let(:domain) { 'www.blog.host.example' } + + before { Fabricate :preview_card_provider, domain: 'host.example' } + + it { is_expected.to eq(preview_card_provider_more) } + end + end end From 8c2845906c1f8f60708dad452b056bc7696c1224 Mon Sep 17 00:00:00 2001 From: Echo Date: Tue, 16 Dec 2025 12:27:18 +0100 Subject: [PATCH 799/853] Improve Redux Storybook (#37227) --- .storybook/preview.tsx | 25 +++++++++++++-- ...ybook-addon-vitest.d.ts => storybook.d.ts} | 13 ++++++++ .../components/account/account.stories.tsx | 32 +++++++++++++------ .../components/emoji/emoji.stories.tsx | 14 ++++---- 4 files changed, 63 insertions(+), 21 deletions(-) rename .storybook/{storybook-addon-vitest.d.ts => storybook.d.ts} (54%) diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index 32d4bc1867f9eb..abbd193c68190e 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -55,12 +55,31 @@ const preview: Preview = { locale: 'en', }, decorators: [ - (Story, { parameters, globals, args }) => { + (Story, { parameters, globals, args, argTypes }) => { // Get the locale from the global toolbar // and merge it with any parameters or args state. const { locale } = globals as { locale: string }; const { state = {} } = parameters; - const { state: argsState = {} } = args; + + const argsState: Record = {}; + for (const [key, value] of Object.entries(args)) { + const argType = argTypes[key]; + if (argType?.reduxPath) { + const reduxPath = Array.isArray(argType.reduxPath) + ? argType.reduxPath.map((p) => p.toString()) + : argType.reduxPath.split('.'); + + reduxPath.reduce((acc, key, i) => { + if (acc[key] === undefined) { + acc[key] = {}; + } + if (i === reduxPath.length - 1) { + acc[key] = value; + } + return acc[key] as Record; + }, argsState); + } + } const reducer = reducerWithInitialState( { @@ -69,7 +88,7 @@ const preview: Preview = { }, }, state as Record, - argsState as Record, + argsState, ); const store = configureStore({ diff --git a/.storybook/storybook-addon-vitest.d.ts b/.storybook/storybook.d.ts similarity index 54% rename from .storybook/storybook-addon-vitest.d.ts rename to .storybook/storybook.d.ts index 86852faca9f8f4..47624d1e9c6783 100644 --- a/.storybook/storybook-addon-vitest.d.ts +++ b/.storybook/storybook.d.ts @@ -1,7 +1,20 @@ // The addon package.json incorrectly exports types, so we need to override them here. + +import type { RootState } from '@/mastodon/store'; + // See: https://github.com/storybookjs/storybook/blob/v9.0.4/code/addons/vitest/package.json#L70-L76 declare module '@storybook/addon-vitest/vitest-plugin' { export * from '@storybook/addon-vitest/dist/vitest-plugin/index'; } +type RootPathKeys = keyof RootState; + +declare module 'storybook/internal/csf' { + export interface InputType { + reduxPath?: + | `${RootPathKeys}.${string}` + | [RootPathKeys, ...(string | number)[]]; + } +} + export {}; diff --git a/app/javascript/mastodon/components/account/account.stories.tsx b/app/javascript/mastodon/components/account/account.stories.tsx index 3a3a255b7fc582..050ed6e9005967 100644 --- a/app/javascript/mastodon/components/account/account.stories.tsx +++ b/app/javascript/mastodon/components/account/account.stories.tsx @@ -1,16 +1,28 @@ +import type { ComponentProps } from 'react'; + import type { Meta, StoryObj } from '@storybook/react-vite'; import { accountFactoryState, relationshipsFactory } from '@/testing/factories'; import { Account } from './index'; +type Props = Omit, 'id'> & { + name: string; + username: string; +}; + const meta = { title: 'Components/Account', - component: Account, argTypes: { - id: { + name: { + type: 'string', + description: 'The display name of the account', + reduxPath: 'accounts.1.display_name_html', + }, + username: { type: 'string', - description: 'ID of the account to display', + description: 'The username of the account', + reduxPath: 'accounts.1.acct', }, size: { type: 'number', @@ -40,7 +52,8 @@ const meta = { }, }, args: { - id: '1', + name: 'Test User', + username: 'testuser', size: 46, hidden: false, minimal: false, @@ -55,17 +68,16 @@ const meta = { }, }, }, -} satisfies Meta; + render(args) { + return ; + }, +} satisfies Meta; export default meta; type Story = StoryObj; -export const Primary: Story = { - args: { - id: '1', - }, -}; +export const Primary: Story = {}; export const Hidden: Story = { args: { diff --git a/app/javascript/mastodon/components/emoji/emoji.stories.tsx b/app/javascript/mastodon/components/emoji/emoji.stories.tsx index d390387a036aba..fcc81db6c3a98e 100644 --- a/app/javascript/mastodon/components/emoji/emoji.stories.tsx +++ b/app/javascript/mastodon/components/emoji/emoji.stories.tsx @@ -4,20 +4,22 @@ import type { Meta, StoryObj } from '@storybook/react-vite'; import { Emoji } from './index'; -type EmojiProps = ComponentProps & { state: string }; +type EmojiProps = ComponentProps & { + style: 'auto' | 'native' | 'twemoji'; +}; const meta = { title: 'Components/Emoji', component: Emoji, args: { code: '🖤', - state: 'auto', + style: 'auto', }, argTypes: { code: { name: 'Emoji', }, - state: { + style: { control: { type: 'select', labels: { @@ -28,11 +30,7 @@ const meta = { }, options: ['auto', 'native', 'twemoji'], name: 'Emoji Style', - mapping: { - auto: { meta: { emoji_style: 'auto' } }, - native: { meta: { emoji_style: 'native' } }, - twemoji: { meta: { emoji_style: 'twemoji' } }, - }, + reduxPath: 'meta.emoji_style', }, }, render(args) { From 9e97ad04d8e771dd8a618d3b0e1fda6f3efcfec9 Mon Sep 17 00:00:00 2001 From: diondiondion Date: Tue, 16 Dec 2025 12:38:47 +0100 Subject: [PATCH 800/853] Fix bad contrast on disabled dropdown menu items (#37268) --- app/javascript/styles/mastodon/components.scss | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 236efc40c8197e..47f17f6e79b74e 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -2848,7 +2848,7 @@ a.account__display-name { cursor: default; &:focus { - color: rgb(from var(--color-text-disabled) r g b / 70%); + color: var(--color-text-on-disabled); background: var(--color-bg-disabled); outline: 0; } @@ -3994,8 +3994,8 @@ a.account__display-name { box-sizing: border-box; &:hover, - &:focus, - &:active { + &:active, + &:focus-visible { color: var(--color-text-primary); } @@ -4013,14 +4013,7 @@ a.account__display-name { } &--logo { - background: transparent; padding: 10px; - - &:hover, - &:focus, - &:active { - background: transparent; - } } } From a9c84529b2c1c2ef3cf5c88521917834f2fe9e1c Mon Sep 17 00:00:00 2001 From: Echo Date: Tue, 16 Dec 2025 14:00:40 +0100 Subject: [PATCH 801/853] Wrapstodon: Load report data only on display (#37269) --- app/javascript/mastodon/actions/server.js | 5 ---- .../mastodon/features/annual_report/index.tsx | 10 ++++++- .../mastodon/features/annual_report/modal.tsx | 8 ++---- .../features/annual_report/nav_item.tsx | 4 +-- .../features/annual_report/timeline.tsx | 8 ++---- app/javascript/mastodon/features/ui/index.jsx | 2 ++ app/javascript/mastodon/initial_state.ts | 11 ++++---- .../mastodon/reducers/slices/annual_report.ts | 27 ++++++++----------- 8 files changed, 33 insertions(+), 42 deletions(-) diff --git a/app/javascript/mastodon/actions/server.js b/app/javascript/mastodon/actions/server.js index 47b6e7a1764dc9..32ee093afa8423 100644 --- a/app/javascript/mastodon/actions/server.js +++ b/app/javascript/mastodon/actions/server.js @@ -1,5 +1,3 @@ -import { checkAnnualReport } from '@/mastodon/reducers/slices/annual_report'; - import api from '../api'; import { importFetchedAccount } from './importer'; @@ -31,9 +29,6 @@ export const fetchServer = () => (dispatch, getState) => { .get('/api/v2/instance').then(({ data }) => { if (data.contact.account) dispatch(importFetchedAccount(data.contact.account)); dispatch(fetchServerSuccess(data)); - if (data.wrapstodon) { - void dispatch(checkAnnualReport()); - } }).catch(err => dispatch(fetchServerFail(err))); }; diff --git a/app/javascript/mastodon/features/annual_report/index.tsx b/app/javascript/mastodon/features/annual_report/index.tsx index fe55d250c6e1c8..218d60d26db75b 100644 --- a/app/javascript/mastodon/features/annual_report/index.tsx +++ b/app/javascript/mastodon/features/annual_report/index.tsx @@ -10,6 +10,7 @@ import classNames from 'classnames/bind'; import { closeModal } from '@/mastodon/actions/modal'; import { IconButton } from '@/mastodon/components/icon_button'; import { LoadingIndicator } from '@/mastodon/components/loading_indicator'; +import { getReport } from '@/mastodon/reducers/slices/annual_report'; import { createAppSelector, useAppDispatch, @@ -43,6 +44,13 @@ export const AnnualReport: FC<{ context?: 'modal' | 'standalone' }> = ({ const dispatch = useAppDispatch(); const report = useAppSelector((state) => state.annualReport.report); const account = useAppSelector(accountSelector); + const needsReport = !report; // Make into boolean to avoid object comparison in deps. + + useEffect(() => { + if (needsReport) { + void dispatch(getReport()); + } + }, [dispatch, needsReport]); const close = useCallback(() => { dispatch(closeModal({ modalType: 'ANNUAL_REPORT', ignoreFocus: false })); @@ -57,7 +65,7 @@ export const AnnualReport: FC<{ context?: 'modal' | 'standalone' }> = ({ } }, [pathname, initialPathname, close]); - if (!report) { + if (needsReport) { return ; } diff --git a/app/javascript/mastodon/features/annual_report/modal.tsx b/app/javascript/mastodon/features/annual_report/modal.tsx index 953732cba5d15e..01d7c4bbdbfc79 100644 --- a/app/javascript/mastodon/features/annual_report/modal.tsx +++ b/app/javascript/mastodon/features/annual_report/modal.tsx @@ -4,10 +4,7 @@ import { useCallback, useEffect } from 'react'; import classNames from 'classnames'; import { closeModal } from '@/mastodon/actions/modal'; -import { - generateReport, - selectWrapstodonYear, -} from '@/mastodon/reducers/slices/annual_report'; +import { generateReport } from '@/mastodon/reducers/slices/annual_report'; import { useAppDispatch, useAppSelector } from '@/mastodon/store'; import { AnnualReport } from '.'; @@ -21,8 +18,7 @@ const AnnualReportModal: React.FC<{ onChangeBackgroundColor('var(--color-bg-media-base)'); }, [onChangeBackgroundColor]); - const { state } = useAppSelector((state) => state.annualReport); - const year = useAppSelector(selectWrapstodonYear); + const { state, year } = useAppSelector((state) => state.annualReport); const showAnnouncement = year && state && state !== 'available'; diff --git a/app/javascript/mastodon/features/annual_report/nav_item.tsx b/app/javascript/mastodon/features/annual_report/nav_item.tsx index bc293a794777e5..435e2b1f70c848 100644 --- a/app/javascript/mastodon/features/annual_report/nav_item.tsx +++ b/app/javascript/mastodon/features/annual_report/nav_item.tsx @@ -8,7 +8,6 @@ import classNames from 'classnames'; import IconPlanet from '@/images/icons/icon_planet.svg?react'; import { openModal } from '@/mastodon/actions/modal'; import { Icon } from '@/mastodon/components/icon'; -import { selectWrapstodonYear } from '@/mastodon/reducers/slices/annual_report'; import { createAppSelector, useAppDispatch, @@ -23,8 +22,7 @@ const selectReportModalOpen = createAppSelector( ); export const AnnualReportNavItem: FC = () => { - const { state } = useAppSelector((state) => state.annualReport); - const year = useAppSelector(selectWrapstodonYear); + const { state, year } = useAppSelector((state) => state.annualReport); const active = useAppSelector(selectReportModalOpen); const dispatch = useAppDispatch(); diff --git a/app/javascript/mastodon/features/annual_report/timeline.tsx b/app/javascript/mastodon/features/annual_report/timeline.tsx index 4280c2a98aa8b4..28a4b1d27324ae 100644 --- a/app/javascript/mastodon/features/annual_report/timeline.tsx +++ b/app/javascript/mastodon/features/annual_report/timeline.tsx @@ -3,17 +3,13 @@ import type { FC } from 'react'; import { openModal } from '@/mastodon/actions/modal'; import { useDismissible } from '@/mastodon/hooks/useDismissible'; -import { - generateReport, - selectWrapstodonYear, -} from '@/mastodon/reducers/slices/annual_report'; +import { generateReport } from '@/mastodon/reducers/slices/annual_report'; import { useAppDispatch, useAppSelector } from '@/mastodon/store'; import { AnnualReportAnnouncement } from './announcement'; export const AnnualReportTimeline: FC = () => { - const { state } = useAppSelector((state) => state.annualReport); - const year = useAppSelector(selectWrapstodonYear); + const { state, year } = useAppSelector((state) => state.annualReport); const dispatch = useAppDispatch(); const handleBuildRequest = useCallback(() => { diff --git a/app/javascript/mastodon/features/ui/index.jsx b/app/javascript/mastodon/features/ui/index.jsx index 0d731068081718..61317fff5b291f 100644 --- a/app/javascript/mastodon/features/ui/index.jsx +++ b/app/javascript/mastodon/features/ui/index.jsx @@ -21,6 +21,7 @@ import { PictureInPicture } from 'mastodon/features/picture_in_picture'; import { identityContextPropShape, withIdentity } from 'mastodon/identity_context'; import { layoutFromWindow } from 'mastodon/is_mobile'; import { WithRouterPropTypes } from 'mastodon/utils/react_router'; +import { checkAnnualReport } from '@/mastodon/reducers/slices/annual_report'; import { uploadCompose, resetCompose, changeComposeSpoilerness } from '../../actions/compose'; import { clearHeight } from '../../actions/height_cache'; @@ -396,6 +397,7 @@ class UI extends PureComponent { this.props.dispatch(expandHomeTimeline()); this.props.dispatch(fetchNotifications()); this.props.dispatch(fetchServerTranslationLanguages()); + this.props.dispatch(checkAnnualReport()); setTimeout(() => this.props.dispatch(fetchServer()), 3000); } diff --git a/app/javascript/mastodon/initial_state.ts b/app/javascript/mastodon/initial_state.ts index 358c307c30f015..9af0c26f934b65 100644 --- a/app/javascript/mastodon/initial_state.ts +++ b/app/javascript/mastodon/initial_state.ts @@ -1,12 +1,8 @@ +import type { ApiAnnualReportState } from './api/annual_report'; import type { ApiAccountJSON } from './api_types/accounts'; type InitialStateLanguage = [code: string, name: string, localName: string]; -interface InitialWrapstodonState { - year: number; - state: 'available' | 'generating' | 'eligible' | 'ineligible'; -} - interface InitialStateMeta { access_token: string; advanced_layout?: boolean; @@ -63,6 +59,11 @@ interface Role { highlighted: boolean; } +interface InitialWrapstodonState { + year: number; + state: ApiAnnualReportState; +} + export interface InitialState { accounts: Record; languages: InitialStateLanguage[]; diff --git a/app/javascript/mastodon/reducers/slices/annual_report.ts b/app/javascript/mastodon/reducers/slices/annual_report.ts index 5e7f44798a4df9..798fe7cc9b0eb7 100644 --- a/app/javascript/mastodon/reducers/slices/annual_report.ts +++ b/app/javascript/mastodon/reducers/slices/annual_report.ts @@ -13,12 +13,10 @@ import { } from '@/mastodon/api/annual_report'; import { wrapstodon } from '@/mastodon/initial_state'; import type { AnnualReport } from '@/mastodon/models/annual_report'; - import { - createAppSelector, createAppThunk, createDataLoadingThunk, -} from '../../store/typed_functions'; +} from '@/mastodon/store/typed_functions'; interface AnnualReportState { year?: number; @@ -57,18 +55,17 @@ const annualReportSlice = createSlice({ export const annualReport = annualReportSlice.reducer; export const { setReport } = annualReportSlice.actions; -export const selectWrapstodonYear = createAppSelector( - [(state) => state.annualReport.year], - (year: number | null | undefined) => year ?? null, -); - -// This kicks everything off, and is called after fetching the server info. +// Called on initial load to check if we need to refresh the report state. export const checkAnnualReport = createAppThunk( `${annualReportSlice.name}/checkAnnualReport`, (_arg: unknown, { dispatch, getState }) => { - const year = selectWrapstodonYear(getState()); + const { state, year } = getState().annualReport; const me = getState().meta.get('me') as string; - if (!year || !me) { + + // If we have a state, we only need to fetch it again to poll for changes. + const needsStateRefresh = !state || state === 'generating'; + + if (!year || !me || !needsStateRefresh) { return; } void dispatch(fetchReportState()); @@ -78,7 +75,7 @@ export const checkAnnualReport = createAppThunk( const fetchReportState = createDataLoadingThunk( `${annualReportSlice.name}/fetchReportState`, async (_arg: unknown, { getState }) => { - const year = selectWrapstodonYear(getState()); + const { year } = getState().annualReport; if (!year) { throw new Error('Year is not set'); } @@ -89,8 +86,6 @@ const fetchReportState = createDataLoadingThunk( window.setTimeout(() => { void dispatch(fetchReportState()); }, 1_000 * refresh.retry); - } else if (state === 'available') { - void dispatch(getReport()); } return state; @@ -102,7 +97,7 @@ const fetchReportState = createDataLoadingThunk( export const generateReport = createDataLoadingThunk( `${annualReportSlice.name}/generateReport`, async (_arg: unknown, { getState }) => { - const year = selectWrapstodonYear(getState()); + const { year } = getState().annualReport; if (!year) { throw new Error('Year is not set'); } @@ -116,7 +111,7 @@ export const generateReport = createDataLoadingThunk( export const getReport = createDataLoadingThunk( `${annualReportSlice.name}/getReport`, async (_arg: unknown, { getState }) => { - const year = selectWrapstodonYear(getState()); + const { year } = getState().annualReport; if (!year) { throw new Error('Year is not set'); } From 92df1c4458b21a1efcfdf09e08598b8e995232c8 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 16 Dec 2025 10:05:26 -0500 Subject: [PATCH 802/853] Add coverage for `Account.representative` from finder concern (#35996) --- .../concerns/account/finder_concern_spec.rb | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/spec/models/concerns/account/finder_concern_spec.rb b/spec/models/concerns/account/finder_concern_spec.rb index b3fae56dfc51e8..18d5c204754c35 100644 --- a/spec/models/concerns/account/finder_concern_spec.rb +++ b/spec/models/concerns/account/finder_concern_spec.rb @@ -3,6 +3,37 @@ require 'rails_helper' RSpec.describe Account::FinderConcern do + describe '.representative' do + context 'with an instance actor using an invalid legacy username' do + let(:legacy_value) { 'localhost:3000' } + + before { Account.find(Account::INSTANCE_ACTOR_ID).update_attribute(:username, legacy_value) } + + it 'updates the username to the new value' do + expect { Account.representative } + .to change { Account.find(Account::INSTANCE_ACTOR_ID).username }.from(legacy_value).to('mastodon.internal') + end + end + + context 'without an instance actor' do + before { Account.find(Account::INSTANCE_ACTOR_ID).destroy! } + + it 'creates an instance actor' do + expect { Account.representative } + .to change(Account.where(id: Account::INSTANCE_ACTOR_ID), :count).from(0).to(1) + end + end + + context 'with a correctly loaded instance actor' do + let(:instance_actor) { Account.find(Account::INSTANCE_ACTOR_ID) } + + it 'returns the instance actor record' do + expect(Account.representative) + .to eq(instance_actor) + end + end + end + describe 'local finders' do let!(:account) { Fabricate(:account, username: 'Alice') } From 7e81e035311db84ea031a4028c3f864f6ffe6867 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 16 Dec 2025 10:26:04 -0500 Subject: [PATCH 803/853] Reduce factory creation across `spec/helpers` (#35527) --- .../admin/account_moderation_notes_helper_spec.rb | 4 ++-- spec/helpers/admin/dashboard_helper_spec.rb | 10 ++-------- spec/helpers/admin/trends/statuses_helper_spec.rb | 2 +- spec/helpers/formatting_helper_spec.rb | 2 +- spec/helpers/home_helper_spec.rb | 2 +- spec/helpers/media_component_helper_spec.rb | 8 +++++--- spec/helpers/statuses_helper_spec.rb | 13 +++++-------- 7 files changed, 17 insertions(+), 24 deletions(-) diff --git a/spec/helpers/admin/account_moderation_notes_helper_spec.rb b/spec/helpers/admin/account_moderation_notes_helper_spec.rb index d8fc0ee233554e..a68c8abba94a50 100644 --- a/spec/helpers/admin/account_moderation_notes_helper_spec.rb +++ b/spec/helpers/admin/account_moderation_notes_helper_spec.rb @@ -17,7 +17,7 @@ end context 'with account' do - let(:account) { Fabricate(:account) } + let(:account) { Fabricate.build(:account, id: 123) } it 'returns a labeled avatar link to the account' do expect(parsed_html.a[:href]).to eq admin_account_path(account.id) @@ -39,7 +39,7 @@ end context 'with account' do - let(:account) { Fabricate(:account) } + let(:account) { Fabricate.build(:account, id: 123) } it 'returns an inline link to the account' do expect(parsed_html.a[:href]).to eq admin_account_path(account.id) diff --git a/spec/helpers/admin/dashboard_helper_spec.rb b/spec/helpers/admin/dashboard_helper_spec.rb index 9c674fb4b9664d..db95eb9f2ce644 100644 --- a/spec/helpers/admin/dashboard_helper_spec.rb +++ b/spec/helpers/admin/dashboard_helper_spec.rb @@ -4,8 +4,9 @@ RSpec.describe Admin::DashboardHelper do describe 'relevant_account_timestamp' do + let(:account) { Fabricate(:account) } + context 'with an account with older sign in' do - let(:account) { Fabricate(:account) } let(:stamp) { 10.days.ago } it 'returns a time element' do @@ -18,8 +19,6 @@ end context 'with an account with newer sign in' do - let(:account) { Fabricate(:account) } - it 'returns a time element' do account.user.update(current_sign_in_at: 10.hours.ago) result = helper.relevant_account_timestamp(account) @@ -29,8 +28,6 @@ end context 'with an account where the user is pending' do - let(:account) { Fabricate(:account) } - it 'returns a time element' do account.user.update(current_sign_in_at: nil) account.user.update(approved: false) @@ -42,7 +39,6 @@ end context 'with an account with a last status value' do - let(:account) { Fabricate(:account) } let(:stamp) { 5.minutes.ago } it 'returns a time element' do @@ -56,8 +52,6 @@ end context 'with an account without sign in or last status or pending' do - let(:account) { Fabricate(:account) } - it 'returns a time element' do account.user.update(current_sign_in_at: nil) result = helper.relevant_account_timestamp(account) diff --git a/spec/helpers/admin/trends/statuses_helper_spec.rb b/spec/helpers/admin/trends/statuses_helper_spec.rb index 6abc4569b41bd6..634b4c94c3904c 100644 --- a/spec/helpers/admin/trends/statuses_helper_spec.rb +++ b/spec/helpers/admin/trends/statuses_helper_spec.rb @@ -54,7 +54,7 @@ context 'with a status that has emoji' do before { Fabricate(:custom_emoji, shortcode: 'florpy') } - let(:status) { Fabricate(:status, text: 'hello there :florpy:') } + let(:status) { Fabricate.build(:status, text: 'hello there :florpy:') } it 'renders a correct preview text' do result = helper.one_line_preview(status) diff --git a/spec/helpers/formatting_helper_spec.rb b/spec/helpers/formatting_helper_spec.rb index 5ff534e4eb3873..4e605850c1a176 100644 --- a/spec/helpers/formatting_helper_spec.rb +++ b/spec/helpers/formatting_helper_spec.rb @@ -18,7 +18,7 @@ end context 'with a spoiler and an emoji and a poll' do - let(:status) { Fabricate(:status, text: 'Hello :world: <>', spoiler_text: 'This is a spoiler<>', poll: Fabricate(:poll, options: %w(Yes<> No))) } + let(:status) { Fabricate(:status, text: 'Hello :world: <>', spoiler_text: 'This is a spoiler<>', poll: Fabricate.build(:poll, options: %w(Yes<> No))) } before { Fabricate :custom_emoji, shortcode: 'world' } diff --git a/spec/helpers/home_helper_spec.rb b/spec/helpers/home_helper_spec.rb index a056eae364dfb2..e63c03528c05c1 100644 --- a/spec/helpers/home_helper_spec.rb +++ b/spec/helpers/home_helper_spec.rb @@ -21,7 +21,7 @@ end context 'with a valid account' do - let(:account) { Fabricate(:account) } + let(:account) { Fabricate.build(:account) } before { helper.extend controller_helpers } diff --git a/spec/helpers/media_component_helper_spec.rb b/spec/helpers/media_component_helper_spec.rb index a44b9b841509b9..60c9f84da219a8 100644 --- a/spec/helpers/media_component_helper_spec.rb +++ b/spec/helpers/media_component_helper_spec.rb @@ -5,8 +5,10 @@ RSpec.describe MediaComponentHelper do before { helper.extend controller_helpers } + let(:media) { Fabricate.build(:media_attachment, type:, status: Fabricate.build(:status)) } + describe 'render_video_component' do - let(:media) { Fabricate(:media_attachment, type: :video, status: Fabricate(:status)) } + let(:type) { :video } let(:result) { helper.render_video_component(media.status) } it 'renders a react component for the video' do @@ -15,7 +17,7 @@ end describe 'render_audio_component' do - let(:media) { Fabricate(:media_attachment, type: :audio, status: Fabricate(:status)) } + let(:type) { :audio } let(:result) { helper.render_audio_component(media.status) } it 'renders a react component for the audio' do @@ -24,7 +26,7 @@ end describe 'render_media_gallery_component' do - let(:media) { Fabricate(:media_attachment, type: :audio, status: Fabricate(:status)) } + let(:type) { :audio } let(:result) { helper.render_media_gallery_component(media.status) } it 'renders a react component for the media gallery' do diff --git a/spec/helpers/statuses_helper_spec.rb b/spec/helpers/statuses_helper_spec.rb index 07ad72eda956f9..dbfc216605a64e 100644 --- a/spec/helpers/statuses_helper_spec.rb +++ b/spec/helpers/statuses_helper_spec.rb @@ -24,16 +24,13 @@ end describe '#media_summary' do - it 'describes the media on a status' do - status = Fabricate :status - Fabricate :media_attachment, status: status, type: :video - Fabricate :media_attachment, status: status, type: :audio - Fabricate :media_attachment, status: status, type: :image + subject { helper.media_summary(status) } - result = helper.media_summary(status) + let(:status) { Fabricate.build :status } - expect(result).to eq('Attached: 1 image · 1 video · 1 audio') - end + before { %i(video audio image).each { |type| Fabricate.build :media_attachment, status:, type: } } + + it { is_expected.to eq('Attached: 1 image · 1 video · 1 audio') } end describe 'visibility_icon' do From e6b0cdcc83750aee357f69f3ff41807b435fe083 Mon Sep 17 00:00:00 2001 From: diondiondion Date: Tue, 16 Dec 2025 16:35:26 +0100 Subject: [PATCH 804/853] Updates Wrapstodon footer with dedicated local server info (#37270) --- app/helpers/wrapstodon_helper.rb | 1 + app/javascript/entrypoints/wrapstodon.tsx | 3 +- .../mastodon/features/annual_report/index.tsx | 2 +- .../annual_report/shared_page.module.scss | 35 ++++++--- .../features/annual_report/shared_page.tsx | 71 ++++++++++++------- app/javascript/mastodon/locales/en.json | 4 +- 6 files changed, 78 insertions(+), 38 deletions(-) diff --git a/app/helpers/wrapstodon_helper.rb b/app/helpers/wrapstodon_helper.rb index 8031c51179eb4b..5a0075a0e58be8 100644 --- a/app/helpers/wrapstodon_helper.rb +++ b/app/helpers/wrapstodon_helper.rb @@ -10,6 +10,7 @@ def render_wrapstodon_share_data(report) ).as_json payload[:me] = current_account.id.to_s if user_signed_in? + payload[:domain] = Addressable::IDNA.to_unicode(Rails.configuration.x.local_domain) json_string = payload.to_json diff --git a/app/javascript/entrypoints/wrapstodon.tsx b/app/javascript/entrypoints/wrapstodon.tsx index e2c8d5a38e59a9..9fff41a1330438 100644 --- a/app/javascript/entrypoints/wrapstodon.tsx +++ b/app/javascript/entrypoints/wrapstodon.tsx @@ -25,7 +25,7 @@ function loaded() { const initialState = JSON.parse( propsNode.textContent, - ) as ApiAnnualReportResponse & { me?: string }; + ) as ApiAnnualReportResponse & { me?: string; domain: string }; const report = initialState.annual_reports[0]; if (!report) { @@ -38,6 +38,7 @@ function loaded() { meta: { locale: document.documentElement.lang, me: initialState.me, + domain: initialState.domain, }, accounts: initialState.accounts, }), diff --git a/app/javascript/mastodon/features/annual_report/index.tsx b/app/javascript/mastodon/features/annual_report/index.tsx index 218d60d26db75b..ef6f73fff28605 100644 --- a/app/javascript/mastodon/features/annual_report/index.tsx +++ b/app/javascript/mastodon/features/annual_report/index.tsx @@ -27,7 +27,7 @@ import { NewPosts } from './new_posts'; const moduleClassNames = classNames.bind(styles); -const accountSelector = createAppSelector( +export const accountSelector = createAppSelector( [(state) => state.accounts, (state) => state.annualReport.report], (accounts, report) => { if (report?.schema_version === 2) { diff --git a/app/javascript/mastodon/features/annual_report/shared_page.module.scss b/app/javascript/mastodon/features/annual_report/shared_page.module.scss index b29ab517070e04..ea3ea471b90153 100644 --- a/app/javascript/mastodon/features/annual_report/shared_page.module.scss +++ b/app/javascript/mastodon/features/annual_report/shared_page.module.scss @@ -16,22 +16,16 @@ $mobile-breakpoint: 540px; display: flex; flex-direction: column; align-items: center; - gap: 0.75rem; + gap: 1.8rem; margin-top: 2rem; font-size: 16px; + line-height: 1.4; text-align: center; color: var(--color-text-secondary); -} -.logo { - width: 2rem; - opacity: 0.6; -} - -.nav { - display: flex; - flex-wrap: wrap; - gap: 12px; + strong { + font-weight: 600; + } a:any-link { color: inherit; @@ -43,3 +37,22 @@ $mobile-breakpoint: 540px; color: var(--color-text-primary); } } + +.logo { + width: 2rem; + opacity: 0.6; +} + +.footerSection { + display: flex; + flex-direction: column; + align-items: center; + gap: 0.5rem; +} + +.linkList { + list-style: none; + display: flex; + flex-wrap: wrap; + gap: 12px; +} diff --git a/app/javascript/mastodon/features/annual_report/shared_page.tsx b/app/javascript/mastodon/features/annual_report/shared_page.tsx index f2b26bf2aac38e..3defe7194a3ec2 100644 --- a/app/javascript/mastodon/features/annual_report/shared_page.tsx +++ b/app/javascript/mastodon/features/annual_report/shared_page.tsx @@ -2,43 +2,66 @@ import type { FC } from 'react'; import { FormattedMessage } from 'react-intl'; +import { DisplayName } from '@/mastodon/components/display_name'; import { IconLogo } from '@/mastodon/components/logo'; import { useAppSelector } from '@/mastodon/store'; -import { AnnualReport } from './index'; +import { AnnualReport, accountSelector } from './index'; import classes from './shared_page.module.scss'; export const WrapstodonSharedPage: FC = () => { - const isLoggedIn = useAppSelector((state) => !!state.meta.get('me')); + const account = useAppSelector(accountSelector); + const domain = useAppSelector((state) => state.meta.get('domain') as string); return (
); diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index bafbb3fafdac73..00b3029587b479 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -121,7 +121,7 @@ "annual_report.nav_item.badge": "New", "annual_report.shared_page.donate": "Donate", "annual_report.shared_page.footer": "Generated with {heart} by the Mastodon team", - "annual_report.shared_page.sign_up": "Sign up", + "annual_report.shared_page.footer_server_info": "{username} uses {domain}, one of many communities powered by Mastodon.", "annual_report.summary.archetype.booster.desc_public": "{name} stayed on the hunt for posts to boost, amplifying other creators with perfect aim.", "annual_report.summary.archetype.booster.desc_self": "You stayed on the hunt for posts to boost, amplifying other creators with perfect aim.", "annual_report.summary.archetype.booster.name": "The Archer", @@ -441,6 +441,8 @@ "follow_suggestions.who_to_follow": "Who to follow", "followed_tags": "Followed hashtags", "footer.about": "About", + "footer.about_mastodon": "About Mastodon", + "footer.about_server": "About {domain}", "footer.about_this_server": "About", "footer.directory": "Profiles directory", "footer.get_app": "Get the app", From dbf8d77cbbf88b8c1cf8c3c3eaaf0c36a4b96693 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 16 Dec 2025 10:43:04 -0500 Subject: [PATCH 805/853] Add spec for missing username value in create account API (#37057) --- spec/requests/api/v1/accounts_spec.rb | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/spec/requests/api/v1/accounts_spec.rb b/spec/requests/api/v1/accounts_spec.rb index c6a131062b3c68..e3416fc3376e3a 100644 --- a/spec/requests/api/v1/accounts_spec.rb +++ b/spec/requests/api/v1/accounts_spec.rb @@ -96,6 +96,28 @@ end end + context 'when missing username value' do + subject do + post '/api/v1/accounts', headers: headers, params: { password: '12345678', email: 'hello@world.tld', agreement: 'true' } + end + + it 'returns http unprocessable entity with username error message' do + expect { subject } + .to not_change(User, :count) + .and not_change(Account, :count) + + expect(response) + .to have_http_status(422) + expect(response.media_type) + .to eq('application/json') + expect(response.parsed_body) + .to include( + error: /Validation failed/, + details: include(username: contain_exactly(include(error: 'ERR_BLANK', description: /can't be blank/))) + ) + end + end + context 'when age verification is enabled' do before do Setting.min_age = 16 From 95432b47ebd7ce0279482759175b39c08d21090f Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 16 Dec 2025 10:58:39 -0500 Subject: [PATCH 806/853] Add coverage for user model registration time validation (#35993) --- spec/models/user_spec.rb | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 7088266b34eb38..4ea2e6a79ca649 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -39,6 +39,15 @@ end it { is_expected.to allow_value('admin@localhost').for(:email) } + + context 'when registration form time is present' do + subject { Fabricate.build :user } + + before { stub_const 'RegistrationFormTimeValidator::REGISTRATION_FORM_MIN_TIME', 3.seconds } + + it { is_expected.to allow_value(10.seconds.ago).for(:registration_form_time) } + it { is_expected.to_not allow_value(1.second.ago).for(:registration_form_time).against(:base) } + end end describe 'Normalizations' do From f118d613349bd43e915c5be58477c7d4d8175371 Mon Sep 17 00:00:00 2001 From: Echo Date: Tue, 16 Dec 2025 17:06:59 +0100 Subject: [PATCH 807/853] Emojis: Show in embedded statuses (#37272) --- .../notifications_v2/components/embedded_status_content.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx b/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx index 9e7f66d112cd72..845a6902a29dd9 100644 --- a/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx +++ b/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx @@ -4,6 +4,7 @@ import type { List } from 'immutable'; import { EmojiHTML } from '@/mastodon/components/emoji/html'; import { useElementHandledLink } from '@/mastodon/components/status/handled_link'; +import type { CustomEmoji } from '@/mastodon/models/custom_emoji'; import type { Status } from '@/mastodon/models/status'; import type { Mention } from './embedded_status'; @@ -33,6 +34,7 @@ export const EmbeddedStatusContent: React.FC<{ className={className} lang={status.get('language') as string} htmlString={status.get('contentHtml') as string} + extraEmojis={status.get('emoji') as List} /> ); }; From 53be8392eceea8c3a576478e209fe82c2ceb458a Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 16 Dec 2025 11:13:03 -0500 Subject: [PATCH 808/853] Add coverage for blocked account scenario in following/followers (#36042) --- .../follower_accounts_controller_spec.rb | 20 +++++++++++++++++++ .../following_accounts_controller_spec.rb | 20 +++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/spec/controllers/follower_accounts_controller_spec.rb b/spec/controllers/follower_accounts_controller_spec.rb index d996761169240a..358341cb7299a3 100644 --- a/spec/controllers/follower_accounts_controller_spec.rb +++ b/spec/controllers/follower_accounts_controller_spec.rb @@ -68,6 +68,26 @@ end end + context 'when request is signed in and user blocks an account' do + let(:account) { Fabricate :account } + + before do + Fabricate :block, account:, target_account: follower_bob + sign_in(account.user) + end + + it 'returns followers without blocked' do + expect(response) + .to have_http_status(200) + expect(response.parsed_body) + .to include( + orderedItems: contain_exactly( + include(follow_from_chris.account.id.to_s) + ) + ) + end + end + context 'when account is permanently suspended' do before do alice.suspend! diff --git a/spec/controllers/following_accounts_controller_spec.rb b/spec/controllers/following_accounts_controller_spec.rb index 576d25d93c85e0..7f11a50395adb3 100644 --- a/spec/controllers/following_accounts_controller_spec.rb +++ b/spec/controllers/following_accounts_controller_spec.rb @@ -68,6 +68,26 @@ end end + context 'when request is signed in and user blocks an account' do + let(:account) { Fabricate :account } + + before do + Fabricate :block, account:, target_account: followee_bob + sign_in(account.user) + end + + it 'returns followers without blocked' do + expect(response) + .to have_http_status(200) + expect(response.parsed_body) + .to include( + orderedItems: contain_exactly( + include(follow_of_chris.target_account.id.to_s) + ) + ) + end + end + context 'when account is permanently suspended' do before do alice.suspend! From 3cd033df0cce1a4f0edc5869b3c36dcb006b0865 Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 16 Dec 2025 10:47:18 +0100 Subject: [PATCH 809/853] [Glitch] Add wrapstodon to initial state and show wrapstodon sidebar item on load Port 550a6d4765e5af144052b9fb6cdc5d3a4e958a87 to glitch-soc Signed-off-by: Claire --- app/javascript/flavours/glitch/initial_state.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/javascript/flavours/glitch/initial_state.ts b/app/javascript/flavours/glitch/initial_state.ts index 1ea3dda468ae58..670969e70d9057 100644 --- a/app/javascript/flavours/glitch/initial_state.ts +++ b/app/javascript/flavours/glitch/initial_state.ts @@ -2,6 +2,11 @@ import type { ApiAccountJSON } from './api_types/accounts'; type InitialStateLanguage = [code: string, name: string, localName: string]; +interface InitialWrapstodonState { + year: number; + state: 'available' | 'generating' | 'eligible' | 'ineligible'; +} + interface InitialStateMeta { access_token: string; advanced_layout?: boolean; @@ -49,6 +54,7 @@ interface InitialStateMeta { status_page_url: string; terms_of_service_enabled: boolean; emoji_style?: string; + wrapstodon?: InitialWrapstodonState | null; default_content_type: string; } @@ -155,6 +161,7 @@ export const criticalUpdatesPending = initialState?.critical_updates_pending; export const statusPageUrl = getMeta('status_page_url'); export const sso_redirect = getMeta('sso_redirect'); export const termsOfServiceEnabled = getMeta('terms_of_service_enabled'); +export const wrapstodon = getMeta('wrapstodon'); const displayNames = // Intl.DisplayNames can be undefined in old browsers From 177479fe3784f9d472ab56ed8c709ad7fb872ea3 Mon Sep 17 00:00:00 2001 From: Echo Date: Tue, 16 Dec 2025 12:27:18 +0100 Subject: [PATCH 810/853] [Glitch] Improve Redux Storybook Port 8c2845906c1f8f60708dad452b056bc7696c1224 to glitch-soc Signed-off-by: Claire --- .../glitch/components/emoji/emoji.stories.tsx | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/app/javascript/flavours/glitch/components/emoji/emoji.stories.tsx b/app/javascript/flavours/glitch/components/emoji/emoji.stories.tsx index d390387a036aba..fcc81db6c3a98e 100644 --- a/app/javascript/flavours/glitch/components/emoji/emoji.stories.tsx +++ b/app/javascript/flavours/glitch/components/emoji/emoji.stories.tsx @@ -4,20 +4,22 @@ import type { Meta, StoryObj } from '@storybook/react-vite'; import { Emoji } from './index'; -type EmojiProps = ComponentProps & { state: string }; +type EmojiProps = ComponentProps & { + style: 'auto' | 'native' | 'twemoji'; +}; const meta = { title: 'Components/Emoji', component: Emoji, args: { code: '🖤', - state: 'auto', + style: 'auto', }, argTypes: { code: { name: 'Emoji', }, - state: { + style: { control: { type: 'select', labels: { @@ -28,11 +30,7 @@ const meta = { }, options: ['auto', 'native', 'twemoji'], name: 'Emoji Style', - mapping: { - auto: { meta: { emoji_style: 'auto' } }, - native: { meta: { emoji_style: 'native' } }, - twemoji: { meta: { emoji_style: 'twemoji' } }, - }, + reduxPath: 'meta.emoji_style', }, }, render(args) { From 59d2a712c52ed596f5a7a4f74763ad7f3c7acc5f Mon Sep 17 00:00:00 2001 From: diondiondion Date: Tue, 16 Dec 2025 12:38:47 +0100 Subject: [PATCH 811/853] [Glitch] Fix bad contrast on disabled dropdown menu items Port 9e97ad04d8e771dd8a618d3b0e1fda6f3efcfec9 to glitch-soc Signed-off-by: Claire --- .../flavours/glitch/styles/mastodon/components.scss | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/app/javascript/flavours/glitch/styles/mastodon/components.scss b/app/javascript/flavours/glitch/styles/mastodon/components.scss index 0ac2884eb90cfd..8ce00051ac39de 100644 --- a/app/javascript/flavours/glitch/styles/mastodon/components.scss +++ b/app/javascript/flavours/glitch/styles/mastodon/components.scss @@ -2913,7 +2913,7 @@ a.account__display-name { cursor: default; &:focus { - color: rgb(from var(--color-text-disabled) r g b / 70%); + color: var(--color-text-on-disabled); background: var(--color-bg-disabled); outline: 0; } @@ -4059,8 +4059,8 @@ a.account__display-name { box-sizing: border-box; &:hover, - &:focus, - &:active { + &:active, + &:focus-visible { color: var(--color-text-primary); } @@ -4078,14 +4078,7 @@ a.account__display-name { } &--logo { - background: transparent; padding: 10px; - - &:hover, - &:focus, - &:active { - background: transparent; - } } } From f56f360a5c537670e0b568e00f5b6d57a35f43fd Mon Sep 17 00:00:00 2001 From: Echo Date: Tue, 16 Dec 2025 14:00:40 +0100 Subject: [PATCH 812/853] [Glitch] Wrapstodon: Load report data only on display Port a9c84529b2c1c2ef3cf5c88521917834f2fe9e1c to glitch-soc Signed-off-by: Claire --- .../flavours/glitch/actions/server.js | 5 --- .../glitch/features/annual_report/index.tsx | 10 +++++- .../glitch/features/annual_report/modal.tsx | 8 ++--- .../features/annual_report/nav_item.tsx | 4 +-- .../features/annual_report/timeline.tsx | 8 ++--- .../flavours/glitch/features/ui/index.jsx | 2 ++ .../flavours/glitch/initial_state.ts | 11 +++--- .../glitch/reducers/slices/annual_report.ts | 34 +++++++++---------- 8 files changed, 39 insertions(+), 43 deletions(-) diff --git a/app/javascript/flavours/glitch/actions/server.js b/app/javascript/flavours/glitch/actions/server.js index e35c25f52423d9..32ee093afa8423 100644 --- a/app/javascript/flavours/glitch/actions/server.js +++ b/app/javascript/flavours/glitch/actions/server.js @@ -1,5 +1,3 @@ -import { checkAnnualReport } from '@/flavours/glitch/reducers/slices/annual_report'; - import api from '../api'; import { importFetchedAccount } from './importer'; @@ -31,9 +29,6 @@ export const fetchServer = () => (dispatch, getState) => { .get('/api/v2/instance').then(({ data }) => { if (data.contact.account) dispatch(importFetchedAccount(data.contact.account)); dispatch(fetchServerSuccess(data)); - if (data.wrapstodon) { - void dispatch(checkAnnualReport()); - } }).catch(err => dispatch(fetchServerFail(err))); }; diff --git a/app/javascript/flavours/glitch/features/annual_report/index.tsx b/app/javascript/flavours/glitch/features/annual_report/index.tsx index f796b0c9676f77..ea88a168cf9feb 100644 --- a/app/javascript/flavours/glitch/features/annual_report/index.tsx +++ b/app/javascript/flavours/glitch/features/annual_report/index.tsx @@ -10,6 +10,7 @@ import classNames from 'classnames/bind'; import { closeModal } from '@/flavours/glitch/actions/modal'; import { IconButton } from '@/flavours/glitch/components/icon_button'; import { LoadingIndicator } from '@/flavours/glitch/components/loading_indicator'; +import { getReport } from '@/flavours/glitch/reducers/slices/annual_report'; import { createAppSelector, useAppDispatch, @@ -43,6 +44,13 @@ export const AnnualReport: FC<{ context?: 'modal' | 'standalone' }> = ({ const dispatch = useAppDispatch(); const report = useAppSelector((state) => state.annualReport.report); const account = useAppSelector(accountSelector); + const needsReport = !report; // Make into boolean to avoid object comparison in deps. + + useEffect(() => { + if (needsReport) { + void dispatch(getReport()); + } + }, [dispatch, needsReport]); const close = useCallback(() => { dispatch(closeModal({ modalType: 'ANNUAL_REPORT', ignoreFocus: false })); @@ -57,7 +65,7 @@ export const AnnualReport: FC<{ context?: 'modal' | 'standalone' }> = ({ } }, [pathname, initialPathname, close]); - if (!report) { + if (needsReport) { return ; } diff --git a/app/javascript/flavours/glitch/features/annual_report/modal.tsx b/app/javascript/flavours/glitch/features/annual_report/modal.tsx index 7c2cec8d89a581..29034de6b9114b 100644 --- a/app/javascript/flavours/glitch/features/annual_report/modal.tsx +++ b/app/javascript/flavours/glitch/features/annual_report/modal.tsx @@ -4,10 +4,7 @@ import { useCallback, useEffect } from 'react'; import classNames from 'classnames'; import { closeModal } from '@/flavours/glitch/actions/modal'; -import { - generateReport, - selectWrapstodonYear, -} from '@/flavours/glitch/reducers/slices/annual_report'; +import { generateReport } from '@/flavours/glitch/reducers/slices/annual_report'; import { useAppDispatch, useAppSelector } from '@/flavours/glitch/store'; import { AnnualReport } from '.'; @@ -21,8 +18,7 @@ const AnnualReportModal: React.FC<{ onChangeBackgroundColor('var(--color-bg-media-base)'); }, [onChangeBackgroundColor]); - const { state } = useAppSelector((state) => state.annualReport); - const year = useAppSelector(selectWrapstodonYear); + const { state, year } = useAppSelector((state) => state.annualReport); const showAnnouncement = year && state && state !== 'available'; diff --git a/app/javascript/flavours/glitch/features/annual_report/nav_item.tsx b/app/javascript/flavours/glitch/features/annual_report/nav_item.tsx index f67b99f01ad6c6..8ac98266129ad8 100644 --- a/app/javascript/flavours/glitch/features/annual_report/nav_item.tsx +++ b/app/javascript/flavours/glitch/features/annual_report/nav_item.tsx @@ -7,7 +7,6 @@ import classNames from 'classnames'; import { openModal } from '@/flavours/glitch/actions/modal'; import { Icon } from '@/flavours/glitch/components/icon'; -import { selectWrapstodonYear } from '@/flavours/glitch/reducers/slices/annual_report'; import { createAppSelector, useAppDispatch, @@ -23,8 +22,7 @@ const selectReportModalOpen = createAppSelector( ); export const AnnualReportNavItem: FC = () => { - const { state } = useAppSelector((state) => state.annualReport); - const year = useAppSelector(selectWrapstodonYear); + const { state, year } = useAppSelector((state) => state.annualReport); const active = useAppSelector(selectReportModalOpen); const dispatch = useAppDispatch(); diff --git a/app/javascript/flavours/glitch/features/annual_report/timeline.tsx b/app/javascript/flavours/glitch/features/annual_report/timeline.tsx index 82b26cdab8f5e3..a56ac379e66758 100644 --- a/app/javascript/flavours/glitch/features/annual_report/timeline.tsx +++ b/app/javascript/flavours/glitch/features/annual_report/timeline.tsx @@ -3,17 +3,13 @@ import type { FC } from 'react'; import { openModal } from '@/flavours/glitch/actions/modal'; import { useDismissible } from '@/flavours/glitch/hooks/useDismissible'; -import { - generateReport, - selectWrapstodonYear, -} from '@/flavours/glitch/reducers/slices/annual_report'; +import { generateReport } from '@/flavours/glitch/reducers/slices/annual_report'; import { useAppDispatch, useAppSelector } from '@/flavours/glitch/store'; import { AnnualReportAnnouncement } from './announcement'; export const AnnualReportTimeline: FC = () => { - const { state } = useAppSelector((state) => state.annualReport); - const year = useAppSelector(selectWrapstodonYear); + const { state, year } = useAppSelector((state) => state.annualReport); const dispatch = useAppDispatch(); const handleBuildRequest = useCallback(() => { diff --git a/app/javascript/flavours/glitch/features/ui/index.jsx b/app/javascript/flavours/glitch/features/ui/index.jsx index 9cf4b2372eb3fa..858bdd1a7b95dd 100644 --- a/app/javascript/flavours/glitch/features/ui/index.jsx +++ b/app/javascript/flavours/glitch/features/ui/index.jsx @@ -24,6 +24,7 @@ import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity import { layoutFromWindow } from 'flavours/glitch/is_mobile'; import { selectUnreadNotificationGroupsCount } from 'flavours/glitch/selectors/notifications'; import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router'; +import { checkAnnualReport } from '@/flavours/glitch/reducers/slices/annual_report'; import { uploadCompose, resetCompose, changeComposeSpoilerness } from '../../actions/compose'; import { clearHeight } from '../../actions/height_cache'; @@ -411,6 +412,7 @@ class UI extends PureComponent { this.props.dispatch(expandHomeTimeline()); this.props.dispatch(fetchNotifications()); this.props.dispatch(fetchServerTranslationLanguages()); + this.props.dispatch(checkAnnualReport()); setTimeout(() => this.props.dispatch(fetchServer()), 3000); } diff --git a/app/javascript/flavours/glitch/initial_state.ts b/app/javascript/flavours/glitch/initial_state.ts index 670969e70d9057..615dc2848ec440 100644 --- a/app/javascript/flavours/glitch/initial_state.ts +++ b/app/javascript/flavours/glitch/initial_state.ts @@ -1,12 +1,8 @@ +import type { ApiAnnualReportState } from './api/annual_report'; import type { ApiAccountJSON } from './api_types/accounts'; type InitialStateLanguage = [code: string, name: string, localName: string]; -interface InitialWrapstodonState { - year: number; - state: 'available' | 'generating' | 'eligible' | 'ineligible'; -} - interface InitialStateMeta { access_token: string; advanced_layout?: boolean; @@ -73,6 +69,11 @@ interface PollLimits { max_expiration: number; } +interface InitialWrapstodonState { + year: number; + state: ApiAnnualReportState; +} + export interface InitialState { accounts: Record; languages: InitialStateLanguage[]; diff --git a/app/javascript/flavours/glitch/reducers/slices/annual_report.ts b/app/javascript/flavours/glitch/reducers/slices/annual_report.ts index 0d159f947e283e..23160a0f89f59b 100644 --- a/app/javascript/flavours/glitch/reducers/slices/annual_report.ts +++ b/app/javascript/flavours/glitch/reducers/slices/annual_report.ts @@ -11,22 +11,25 @@ import { apiGetAnnualReportState, apiRequestGenerateAnnualReport, } from '@/flavours/glitch/api/annual_report'; +import { wrapstodon } from '@/flavours/glitch/initial_state'; import type { AnnualReport } from '@/flavours/glitch/models/annual_report'; - import { - createAppSelector, createAppThunk, createDataLoadingThunk, -} from '../../store/typed_functions'; +} from '@/flavours/glitch/store/typed_functions'; interface AnnualReportState { + year?: number; state?: ApiAnnualReportState; report?: AnnualReport; } const annualReportSlice = createSlice({ name: 'annualReport', - initialState: {} as AnnualReportState, + initialState: { + year: wrapstodon?.year, + state: wrapstodon?.state, + } as AnnualReportState, reducers: { setReport(state, action: PayloadAction) { state.report = action.payload; @@ -52,18 +55,17 @@ const annualReportSlice = createSlice({ export const annualReport = annualReportSlice.reducer; export const { setReport } = annualReportSlice.actions; -export const selectWrapstodonYear = createAppSelector( - [(state) => state.server.getIn(['server', 'wrapstodon'])], - (year: unknown) => (typeof year === 'number' && year > 2000 ? year : null), -); - -// This kicks everything off, and is called after fetching the server info. +// Called on initial load to check if we need to refresh the report state. export const checkAnnualReport = createAppThunk( `${annualReportSlice.name}/checkAnnualReport`, (_arg: unknown, { dispatch, getState }) => { - const year = selectWrapstodonYear(getState()); + const { state, year } = getState().annualReport; const me = getState().meta.get('me') as string; - if (!year || !me) { + + // If we have a state, we only need to fetch it again to poll for changes. + const needsStateRefresh = !state || state === 'generating'; + + if (!year || !me || !needsStateRefresh) { return; } void dispatch(fetchReportState()); @@ -73,7 +75,7 @@ export const checkAnnualReport = createAppThunk( const fetchReportState = createDataLoadingThunk( `${annualReportSlice.name}/fetchReportState`, async (_arg: unknown, { getState }) => { - const year = selectWrapstodonYear(getState()); + const { year } = getState().annualReport; if (!year) { throw new Error('Year is not set'); } @@ -84,8 +86,6 @@ const fetchReportState = createDataLoadingThunk( window.setTimeout(() => { void dispatch(fetchReportState()); }, 1_000 * refresh.retry); - } else if (state === 'available') { - void dispatch(getReport()); } return state; @@ -97,7 +97,7 @@ const fetchReportState = createDataLoadingThunk( export const generateReport = createDataLoadingThunk( `${annualReportSlice.name}/generateReport`, async (_arg: unknown, { getState }) => { - const year = selectWrapstodonYear(getState()); + const { year } = getState().annualReport; if (!year) { throw new Error('Year is not set'); } @@ -111,7 +111,7 @@ export const generateReport = createDataLoadingThunk( export const getReport = createDataLoadingThunk( `${annualReportSlice.name}/getReport`, async (_arg: unknown, { getState }) => { - const year = selectWrapstodonYear(getState()); + const { year } = getState().annualReport; if (!year) { throw new Error('Year is not set'); } From fbacb5ae7a10093592c3ea24c0da9f3298619366 Mon Sep 17 00:00:00 2001 From: Echo Date: Tue, 16 Dec 2025 17:06:59 +0100 Subject: [PATCH 813/853] [Glitch] Emojis: Show in embedded statuses Port f118d613349bd43e915c5be58477c7d4d8175371 to glitch-soc Signed-off-by: Claire --- .../notifications_v2/components/embedded_status_content.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/javascript/flavours/glitch/features/notifications_v2/components/embedded_status_content.tsx b/app/javascript/flavours/glitch/features/notifications_v2/components/embedded_status_content.tsx index baf2e5e921011d..0c9a96fccaa2fe 100644 --- a/app/javascript/flavours/glitch/features/notifications_v2/components/embedded_status_content.tsx +++ b/app/javascript/flavours/glitch/features/notifications_v2/components/embedded_status_content.tsx @@ -4,6 +4,7 @@ import type { List } from 'immutable'; import { EmojiHTML } from '@/flavours/glitch/components/emoji/html'; import { useElementHandledLink } from '@/flavours/glitch/components/status/handled_link'; +import type { CustomEmoji } from '@/flavours/glitch/models/custom_emoji'; import type { Status } from '@/flavours/glitch/models/status'; import type { Mention } from './embedded_status'; @@ -33,6 +34,7 @@ export const EmbeddedStatusContent: React.FC<{ className={className} lang={status.get('language') as string} htmlString={status.get('contentHtml') as string} + extraEmojis={status.get('emoji') as List} /> ); }; From cfc64a2ea9cef499d22695c41fc2c3ab65b11e11 Mon Sep 17 00:00:00 2001 From: diondiondion Date: Tue, 16 Dec 2025 16:35:26 +0100 Subject: [PATCH 814/853] [Glitch] Updates Wrapstodon footer with dedicated local server info Port e6b0cdcc83750aee357f69f3ff41807b435fe083 to glitch-soc Signed-off-by: Claire --- .../glitch/entrypoints/wrapstodon.tsx | 3 +- .../glitch/features/annual_report/index.tsx | 2 +- .../annual_report/shared_page.module.scss | 35 ++++++--- .../features/annual_report/shared_page.tsx | 71 ++++++++++++------- 4 files changed, 74 insertions(+), 37 deletions(-) diff --git a/app/javascript/flavours/glitch/entrypoints/wrapstodon.tsx b/app/javascript/flavours/glitch/entrypoints/wrapstodon.tsx index 972e5dac038e0d..4efcf619addc83 100644 --- a/app/javascript/flavours/glitch/entrypoints/wrapstodon.tsx +++ b/app/javascript/flavours/glitch/entrypoints/wrapstodon.tsx @@ -25,7 +25,7 @@ function loaded() { const initialState = JSON.parse( propsNode.textContent, - ) as ApiAnnualReportResponse & { me?: string }; + ) as ApiAnnualReportResponse & { me?: string; domain: string }; const report = initialState.annual_reports[0]; if (!report) { @@ -38,6 +38,7 @@ function loaded() { meta: { locale: document.documentElement.lang, me: initialState.me, + domain: initialState.domain, }, accounts: initialState.accounts, }), diff --git a/app/javascript/flavours/glitch/features/annual_report/index.tsx b/app/javascript/flavours/glitch/features/annual_report/index.tsx index ea88a168cf9feb..5345cbdb725f1a 100644 --- a/app/javascript/flavours/glitch/features/annual_report/index.tsx +++ b/app/javascript/flavours/glitch/features/annual_report/index.tsx @@ -27,7 +27,7 @@ import { NewPosts } from './new_posts'; const moduleClassNames = classNames.bind(styles); -const accountSelector = createAppSelector( +export const accountSelector = createAppSelector( [(state) => state.accounts, (state) => state.annualReport.report], (accounts, report) => { if (report?.schema_version === 2) { diff --git a/app/javascript/flavours/glitch/features/annual_report/shared_page.module.scss b/app/javascript/flavours/glitch/features/annual_report/shared_page.module.scss index b29ab517070e04..ea3ea471b90153 100644 --- a/app/javascript/flavours/glitch/features/annual_report/shared_page.module.scss +++ b/app/javascript/flavours/glitch/features/annual_report/shared_page.module.scss @@ -16,22 +16,16 @@ $mobile-breakpoint: 540px; display: flex; flex-direction: column; align-items: center; - gap: 0.75rem; + gap: 1.8rem; margin-top: 2rem; font-size: 16px; + line-height: 1.4; text-align: center; color: var(--color-text-secondary); -} -.logo { - width: 2rem; - opacity: 0.6; -} - -.nav { - display: flex; - flex-wrap: wrap; - gap: 12px; + strong { + font-weight: 600; + } a:any-link { color: inherit; @@ -43,3 +37,22 @@ $mobile-breakpoint: 540px; color: var(--color-text-primary); } } + +.logo { + width: 2rem; + opacity: 0.6; +} + +.footerSection { + display: flex; + flex-direction: column; + align-items: center; + gap: 0.5rem; +} + +.linkList { + list-style: none; + display: flex; + flex-wrap: wrap; + gap: 12px; +} diff --git a/app/javascript/flavours/glitch/features/annual_report/shared_page.tsx b/app/javascript/flavours/glitch/features/annual_report/shared_page.tsx index 8e0881792420d0..634f5c2d120075 100644 --- a/app/javascript/flavours/glitch/features/annual_report/shared_page.tsx +++ b/app/javascript/flavours/glitch/features/annual_report/shared_page.tsx @@ -2,43 +2,66 @@ import type { FC } from 'react'; import { FormattedMessage } from 'react-intl'; +import { DisplayName } from '@/flavours/glitch/components/display_name'; import { IconLogo } from '@/flavours/glitch/components/logo'; import { useAppSelector } from '@/flavours/glitch/store'; -import { AnnualReport } from './index'; +import { AnnualReport, accountSelector } from './index'; import classes from './shared_page.module.scss'; export const WrapstodonSharedPage: FC = () => { - const isLoggedIn = useAppSelector((state) => !!state.meta.get('me')); + const account = useAppSelector(accountSelector); + const domain = useAppSelector((state) => state.meta.get('domain') as string); return (
); From a292162c5f4ae835ccbbbd161f8f6b597ae75df1 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 17 Dec 2025 03:32:24 -0500 Subject: [PATCH 815/853] Mark `Form::AdminSettings#persisted?` as true (#35872) --- app/models/form/admin_settings.rb | 4 ++++ app/views/admin/settings/about/show.html.haml | 2 +- app/views/admin/settings/appearance/show.html.haml | 2 +- app/views/admin/settings/branding/show.html.haml | 2 +- app/views/admin/settings/content_retention/show.html.haml | 2 +- app/views/admin/settings/discovery/show.html.haml | 2 +- app/views/admin/settings/registrations/show.html.haml | 2 +- spec/models/form/admin_settings_spec.rb | 4 ++++ 8 files changed, 14 insertions(+), 6 deletions(-) diff --git a/app/models/form/admin_settings.rb b/app/models/form/admin_settings.rb index af4ad38ae941ec..142b0b45603271 100644 --- a/app/models/form/admin_settings.rb +++ b/app/models/form/admin_settings.rb @@ -154,6 +154,10 @@ def save end end + def persisted? + true + end + private def cache_digest_value(key) diff --git a/app/views/admin/settings/about/show.html.haml b/app/views/admin/settings/about/show.html.haml index adc8f1ff04ac36..c4df98e7041091 100644 --- a/app/views/admin/settings/about/show.html.haml +++ b/app/views/admin/settings/about/show.html.haml @@ -5,7 +5,7 @@ %h2= t('admin.settings.title') = render partial: 'admin/settings/shared/links' -= simple_form_for @admin_settings, url: admin_settings_about_path, html: { method: :patch } do |f| += simple_form_for @admin_settings, url: admin_settings_about_path do |f| = render 'shared/error_messages', object: @admin_settings %p.lead= t('admin.settings.about.preamble') diff --git a/app/views/admin/settings/appearance/show.html.haml b/app/views/admin/settings/appearance/show.html.haml index c610f9f94174c3..20208df15248f1 100644 --- a/app/views/admin/settings/appearance/show.html.haml +++ b/app/views/admin/settings/appearance/show.html.haml @@ -5,7 +5,7 @@ %h2= t('admin.settings.title') = render partial: 'admin/settings/shared/links' -= simple_form_for @admin_settings, url: admin_settings_appearance_path, html: { method: :patch } do |f| += simple_form_for @admin_settings, url: admin_settings_appearance_path do |f| = render 'shared/error_messages', object: @admin_settings %p.lead= t('admin.settings.appearance.preamble') diff --git a/app/views/admin/settings/branding/show.html.haml b/app/views/admin/settings/branding/show.html.haml index 05795a19745281..22116167eb36b8 100644 --- a/app/views/admin/settings/branding/show.html.haml +++ b/app/views/admin/settings/branding/show.html.haml @@ -5,7 +5,7 @@ %h2= t('admin.settings.title') = render partial: 'admin/settings/shared/links' -= simple_form_for @admin_settings, url: admin_settings_branding_path, html: { method: :patch } do |f| += simple_form_for @admin_settings, url: admin_settings_branding_path do |f| = render 'shared/error_messages', object: @admin_settings %p.lead= t('admin.settings.branding.preamble') diff --git a/app/views/admin/settings/content_retention/show.html.haml b/app/views/admin/settings/content_retention/show.html.haml index 57485c1108ff3e..c6c39fdf44496a 100644 --- a/app/views/admin/settings/content_retention/show.html.haml +++ b/app/views/admin/settings/content_retention/show.html.haml @@ -5,7 +5,7 @@ %h2= t('admin.settings.title') = render partial: 'admin/settings/shared/links' -= simple_form_for @admin_settings, url: admin_settings_content_retention_path, html: { method: :patch } do |f| += simple_form_for @admin_settings, url: admin_settings_content_retention_path do |f| = render 'shared/error_messages', object: @admin_settings %p.lead= t('admin.settings.content_retention.preamble') diff --git a/app/views/admin/settings/discovery/show.html.haml b/app/views/admin/settings/discovery/show.html.haml index 04c242597d3d84..5b9aab3fedc2ca 100644 --- a/app/views/admin/settings/discovery/show.html.haml +++ b/app/views/admin/settings/discovery/show.html.haml @@ -5,7 +5,7 @@ %h2= t('admin.settings.title') = render partial: 'admin/settings/shared/links' -= simple_form_for @admin_settings, url: admin_settings_discovery_path, html: { method: :patch } do |f| += simple_form_for @admin_settings, url: admin_settings_discovery_path do |f| = render 'shared/error_messages', object: @admin_settings %p.lead= t('admin.settings.discovery.preamble') diff --git a/app/views/admin/settings/registrations/show.html.haml b/app/views/admin/settings/registrations/show.html.haml index 7303eca662ab99..92f755e9e5831c 100644 --- a/app/views/admin/settings/registrations/show.html.haml +++ b/app/views/admin/settings/registrations/show.html.haml @@ -5,7 +5,7 @@ %h2= t('admin.settings.title') = render partial: 'admin/settings/shared/links' -= simple_form_for @admin_settings, url: admin_settings_registrations_path, html: { method: :patch } do |f| += simple_form_for @admin_settings, url: admin_settings_registrations_path do |f| = render 'shared/error_messages', object: @admin_settings %p.lead= t('admin.settings.registrations.preamble') diff --git a/spec/models/form/admin_settings_spec.rb b/spec/models/form/admin_settings_spec.rb index 899d56703a9a63..e734734e000376 100644 --- a/spec/models/form/admin_settings_spec.rb +++ b/spec/models/form/admin_settings_spec.rb @@ -53,4 +53,8 @@ end end end + + describe '#persisted?' do + it { is_expected.to be_persisted } + end end From db62d704925c452bb412d62b5ba4e7fa7b206a17 Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 17 Dec 2025 10:47:02 +0100 Subject: [PATCH 816/853] Change Wrapstodon switch from feature flag to admin setting (#37273) --- app/lib/annual_report.rb | 2 +- app/models/form/admin_settings.rb | 2 ++ app/views/admin/settings/discovery/show.html.haml | 7 +++++++ config/locales/en.yml | 1 + config/locales/simple_form.en.yml | 2 ++ config/settings.yml | 1 + spec/requests/api/v1/annual_reports_spec.rb | 10 +++++++--- spec/requests/api/v2/instance_spec.rb | 2 +- spec/system/settings/applications_spec.rb | 7 ++++++- 9 files changed, 28 insertions(+), 6 deletions(-) diff --git a/app/lib/annual_report.rb b/app/lib/annual_report.rb index f487cb883f87e0..689fbca399f74e 100644 --- a/app/lib/annual_report.rb +++ b/app/lib/annual_report.rb @@ -17,7 +17,7 @@ def self.table_name_prefix end def self.current_campaign - return unless Mastodon::Feature.wrapstodon_enabled? + return unless Setting.wrapstodon datetime = Time.now.utc datetime.year if datetime.month == 12 && (10..31).cover?(datetime.day) diff --git a/app/models/form/admin_settings.rb b/app/models/form/admin_settings.rb index 142b0b45603271..77f23ae5a474bb 100644 --- a/app/models/form/admin_settings.rb +++ b/app/models/form/admin_settings.rb @@ -44,6 +44,7 @@ class Form::AdminSettings local_topic_feed_access remote_topic_feed_access landing_page + wrapstodon ).freeze INTEGER_KEYS = %i( @@ -66,6 +67,7 @@ class Form::AdminSettings require_invite_text captcha_enabled authorized_fetch + wrapstodon ).freeze UPLOAD_KEYS = %i( diff --git a/app/views/admin/settings/discovery/show.html.haml b/app/views/admin/settings/discovery/show.html.haml index 5b9aab3fedc2ca..9ed0bca801510a 100644 --- a/app/views/admin/settings/discovery/show.html.haml +++ b/app/views/admin/settings/discovery/show.html.haml @@ -110,5 +110,12 @@ as: :boolean, wrapper: :with_label + %h4= t('admin.settings.discovery.wrapstodon') + + .fields-group + = f.input :wrapstodon, + as: :boolean, + wrapper: :with_label + .actions = f.button :button, t('generic.save_changes'), type: :submit diff --git a/config/locales/en.yml b/config/locales/en.yml index abce180d57dcbf..84a556292f77a9 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -848,6 +848,7 @@ en: publish_statistics: Publish statistics title: Discovery trends: Trends + wrapstodon: Wrapstodon domain_blocks: all: To everyone disabled: To no one diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index 077f53cbcde7d5..74550782036e82 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -111,6 +111,7 @@ en: thumbnail: A roughly 2:1 image displayed alongside your server information. trendable_by_default: Skip manual review of trending content. Individual items can still be removed from trends after the fact. trends: Trends show which posts, hashtags and news stories are gaining traction on your server. + wrapstodon: Offer local users to generate a playful summary of their Mastodon use during the year. This feature is available between the 10th and 31st of December of each year, and is offered to users who made at least one Public or Quiet Public post and used at least one hashtag within the year. form_challenge: current_password: You are entering a secure area imports: @@ -312,6 +313,7 @@ en: thumbnail: Server thumbnail trendable_by_default: Allow trends without prior review trends: Enable trends + wrapstodon: Enable Wrapstodon interactions: must_be_follower: Block notifications from non-followers must_be_following: Block notifications from people you don't follow diff --git a/config/settings.yml b/config/settings.yml index 3d4b57b5c350a7..ae7548df2678f3 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -33,6 +33,7 @@ defaults: &defaults captcha_enabled: false allow_referrer_origin: false landing_page: 'trends' + wrapstodon: true development: <<: *defaults diff --git a/spec/requests/api/v1/annual_reports_spec.rb b/spec/requests/api/v1/annual_reports_spec.rb index 482e91736c91a4..e79309145e3a54 100644 --- a/spec/requests/api/v1/annual_reports_spec.rb +++ b/spec/requests/api/v1/annual_reports_spec.rb @@ -85,6 +85,10 @@ end context 'when the feature is not enabled' do + before do + Setting.wrapstodon = false + end + it 'returns http success and ineligible status' do get '/api/v1/annual_reports/2025/state', headers: headers @@ -99,7 +103,7 @@ end end - context 'when the feature is enabled and time is within window', feature: :wrapstodon do + context 'when the feature is enabled and time is within window' do before do travel_to Time.utc(2025, 12, 20) @@ -121,7 +125,7 @@ end end - context 'when the feature is enabled but we are out of the time window', feature: :wrapstodon do + context 'when the feature is enabled but we are out of the time window' do before do travel_to Time.utc(2025, 6, 20) @@ -168,7 +172,7 @@ context 'with correct scope' do let(:scopes) { 'write:accounts' } - context 'when the feature is enabled and time is within window', feature: :wrapstodon do + context 'when the feature is enabled and time is within window' do before do travel_to Time.utc(2025, 12, 20) diff --git a/spec/requests/api/v2/instance_spec.rb b/spec/requests/api/v2/instance_spec.rb index 50798612e83b22..39e7105f095dc7 100644 --- a/spec/requests/api/v2/instance_spec.rb +++ b/spec/requests/api/v2/instance_spec.rb @@ -42,7 +42,7 @@ end end - context 'when wrapstodon is enabled', feature: :wrapstodon do + context 'when wrapstodon is enabled' do before do travel_to Time.utc(2025, 12, 20) end diff --git a/spec/system/settings/applications_spec.rb b/spec/system/settings/applications_spec.rb index 62656c2b8e0a41..024a6403555d77 100644 --- a/spec/system/settings/applications_spec.rb +++ b/spec/system/settings/applications_spec.rb @@ -104,7 +104,12 @@ def submit_form let(:redis_pipeline_stub) { instance_double(Redis::PipelinedConnection, publish: nil) } let!(:access_token) { Fabricate(:accessible_access_token, application: application) } - before { stub_redis_pipeline } + before do + # Disable wrapstodon to avoid redis calls that we don't want to stub + Setting.wrapstodon = false + + stub_redis_pipeline + end it 'destroys the record and tells the broader universe about that' do visit settings_applications_path From 5e8b8f9c23c43763a8a3e673adc44bca1a88a458 Mon Sep 17 00:00:00 2001 From: David Roetzel Date: Wed, 17 Dec 2025 11:12:43 +0100 Subject: [PATCH 817/853] Extract interaction policy class (#37277) --- .../api/interaction_policies_concern.rb | 4 +- app/lib/activitypub/parser/status_parser.rb | 8 ++-- app/lib/interaction_policy.rb | 39 ++++++++++++++++++ .../status/interaction_policy_concern.rb | 38 +++++++---------- .../activitypub/note_serializer.rb | 8 ++-- .../rest/scheduled_status_serializer.rb | 2 +- .../activity/quote_request_spec.rb | 4 +- .../activitypub/parser/status_parser_spec.rb | 4 +- spec/lib/interaction_policy_spec.rb | 41 +++++++++++++++++++ spec/lib/status_cache_hydrator_spec.rb | 2 +- spec/policies/status_policy_spec.rb | 6 +-- .../v1/statuses/interaction_policies_spec.rb | 2 +- spec/requests/api/v1/statuses_spec.rb | 8 ++-- .../activitypub/note_serializer_spec.rb | 2 +- .../rest/scheduled_status_serializer_spec.rb | 2 +- .../fetch_remote_status_service_spec.rb | 2 +- .../process_status_update_service_spec.rb | 4 +- spec/services/post_status_service_spec.rb | 4 +- 18 files changed, 126 insertions(+), 54 deletions(-) create mode 100644 app/lib/interaction_policy.rb create mode 100644 spec/lib/interaction_policy_spec.rb diff --git a/app/controllers/concerns/api/interaction_policies_concern.rb b/app/controllers/concerns/api/interaction_policies_concern.rb index f1e1480c0c0cb9..0679c3c691e41f 100644 --- a/app/controllers/concerns/api/interaction_policies_concern.rb +++ b/app/controllers/concerns/api/interaction_policies_concern.rb @@ -6,9 +6,9 @@ module Api::InteractionPoliciesConcern def quote_approval_policy case status_params[:quote_approval_policy].presence || current_user.setting_default_quote_policy when 'public' - Status::QUOTE_APPROVAL_POLICY_FLAGS[:public] << 16 + InteractionPolicy::POLICY_FLAGS[:public] << 16 when 'followers' - Status::QUOTE_APPROVAL_POLICY_FLAGS[:followers] << 16 + InteractionPolicy::POLICY_FLAGS[:followers] << 16 when 'nobody' 0 else diff --git a/app/lib/activitypub/parser/status_parser.rb b/app/lib/activitypub/parser/status_parser.rb index 83f03756ef3220..bc2abc0f1a64e6 100644 --- a/app/lib/activitypub/parser/status_parser.rb +++ b/app/lib/activitypub/parser/status_parser.rb @@ -174,15 +174,15 @@ def quote_subpolicy(subpolicy) allowed_actors = as_array(subpolicy).dup allowed_actors.uniq! - flags |= Status::QUOTE_APPROVAL_POLICY_FLAGS[:public] if allowed_actors.delete('as:Public') || allowed_actors.delete('Public') || allowed_actors.delete('https://www.w3.org/ns/activitystreams#Public') - flags |= Status::QUOTE_APPROVAL_POLICY_FLAGS[:followers] if allowed_actors.delete(@options[:followers_collection]) - flags |= Status::QUOTE_APPROVAL_POLICY_FLAGS[:following] if allowed_actors.delete(@options[:following_collection]) + flags |= InteractionPolicy::POLICY_FLAGS[:public] if allowed_actors.delete('as:Public') || allowed_actors.delete('Public') || allowed_actors.delete('https://www.w3.org/ns/activitystreams#Public') + flags |= InteractionPolicy::POLICY_FLAGS[:followers] if allowed_actors.delete(@options[:followers_collection]) + flags |= InteractionPolicy::POLICY_FLAGS[:following] if allowed_actors.delete(@options[:following_collection]) # Remove the special-meaning actor URI allowed_actors.delete(@options[:actor_uri]) # Any unrecognized actor is marked as unsupported - flags |= Status::QUOTE_APPROVAL_POLICY_FLAGS[:unsupported_policy] unless allowed_actors.empty? + flags |= InteractionPolicy::POLICY_FLAGS[:unsupported_policy] unless allowed_actors.empty? flags end diff --git a/app/lib/interaction_policy.rb b/app/lib/interaction_policy.rb new file mode 100644 index 00000000000000..8d0b8dd060b47c --- /dev/null +++ b/app/lib/interaction_policy.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +class InteractionPolicy + POLICY_FLAGS = { + unsupported_policy: (1 << 0), # Not supported by Mastodon + public: (1 << 1), # Everyone is allowed to interact + followers: (1 << 2), # Only followers may interact + following: (1 << 3), # Only accounts followed by the target may interact + disabled: (1 << 4), # All interaction explicitly disabled + }.freeze + + class SubPolicy + def initialize(bitmap) + @bitmap = bitmap + end + + def as_keys + POLICY_FLAGS.keys.select { |key| @bitmap.anybits?(POLICY_FLAGS[key]) }.map(&:to_s) + end + + POLICY_FLAGS.each_key do |key| + define_method :"#{key}?" do + @bitmap.anybits?(POLICY_FLAGS[key]) + end + end + + def missing? + @bitmap.zero? + end + end + + attr_reader :automatic, :manual + + def initialize(bitmap) + @bitmap = bitmap + @automatic = SubPolicy.new(@bitmap >> 16) + @manual = SubPolicy.new(@bitmap & 0xFFFF) + end +end diff --git a/app/models/concerns/status/interaction_policy_concern.rb b/app/models/concerns/status/interaction_policy_concern.rb index ed1e7a237fc2fd..332feef86b87a5 100644 --- a/app/models/concerns/status/interaction_policy_concern.rb +++ b/app/models/concerns/status/interaction_policy_concern.rb @@ -3,26 +3,17 @@ module Status::InteractionPolicyConcern extend ActiveSupport::Concern - QUOTE_APPROVAL_POLICY_FLAGS = { - unsupported_policy: (1 << 0), - public: (1 << 1), - followers: (1 << 2), - following: (1 << 3), - }.freeze - included do + composed_of :quote_interaction_policy, class_name: 'InteractionPolicy', mapping: { quote_approval_policy: :bitmap } + before_validation :downgrade_quote_policy, if: -> { local? && !distributable? } end def quote_policy_as_keys(kind) - case kind - when :automatic - policy = quote_approval_policy >> 16 - when :manual - policy = quote_approval_policy & 0xFFFF - end + raise ArgumentError unless kind.in?(%i(automatic manual)) - QUOTE_APPROVAL_POLICY_FLAGS.keys.select { |key| policy.anybits?(QUOTE_APPROVAL_POLICY_FLAGS[key]) }.map(&:to_s) + sub_policy = quote_interaction_policy.send(kind) + sub_policy.as_keys end # Returns `:automatic`, `:manual`, `:unknown` or `:denied` @@ -35,35 +26,36 @@ def quote_policy_for_account(other_account) # Post author is always allowed to quote themselves return :automatic if account_id == other_account.id - automatic_policy = quote_approval_policy >> 16 - manual_policy = quote_approval_policy & 0xFFFF + automatic_policy = quote_interaction_policy.automatic - return :automatic if automatic_policy.anybits?(QUOTE_APPROVAL_POLICY_FLAGS[:public]) + return :automatic if automatic_policy.public? - if automatic_policy.anybits?(QUOTE_APPROVAL_POLICY_FLAGS[:followers]) + if automatic_policy.followers? following_author = other_account.following?(account) if following_author.nil? return :automatic if following_author end - if automatic_policy.anybits?(QUOTE_APPROVAL_POLICY_FLAGS[:following]) + if automatic_policy.following? followed_by_author = account.following?(other_account) if followed_by_author.nil? return :automatic if followed_by_author end # We don't know we are allowed by the automatic policy, considering the manual one - return :manual if manual_policy.anybits?(QUOTE_APPROVAL_POLICY_FLAGS[:public]) + manual_policy = quote_interaction_policy.manual + + return :manual if manual_policy.public? - if manual_policy.anybits?(QUOTE_APPROVAL_POLICY_FLAGS[:followers]) + if manual_policy.followers? following_author = other_account.following?(account) if following_author.nil? return :manual if following_author end - if manual_policy.anybits?(QUOTE_APPROVAL_POLICY_FLAGS[:following]) + if manual_policy.following? followed_by_author = account.following?(other_account) if followed_by_author.nil? return :manual if followed_by_author end - return :unknown if (automatic_policy | manual_policy).anybits?(QUOTE_APPROVAL_POLICY_FLAGS[:unsupported_policy]) + return :unknown if [automatic_policy, manual_policy].any?(&:unsupported_policy?) :denied end diff --git a/app/serializers/activitypub/note_serializer.rb b/app/serializers/activitypub/note_serializer.rb index f162f4ee243ec8..455f8d72db75f2 100644 --- a/app/serializers/activitypub/note_serializer.rb +++ b/app/serializers/activitypub/note_serializer.rb @@ -235,10 +235,10 @@ def interaction_policy approved_uris = [] # On outgoing posts, only automatic approval is supported - policy = object.quote_approval_policy >> 16 - approved_uris << ActivityPub::TagManager::COLLECTIONS[:public] if policy.anybits?(Status::QUOTE_APPROVAL_POLICY_FLAGS[:public]) - approved_uris << ActivityPub::TagManager.instance.followers_uri_for(object.account) if policy.anybits?(Status::QUOTE_APPROVAL_POLICY_FLAGS[:followers]) - approved_uris << ActivityPub::TagManager.instance.following_uri_for(object.account) if policy.anybits?(Status::QUOTE_APPROVAL_POLICY_FLAGS[:following]) + policy = object.quote_interaction_policy.automatic + approved_uris << ActivityPub::TagManager::COLLECTIONS[:public] if policy.public? + approved_uris << ActivityPub::TagManager.instance.followers_uri_for(object.account) if policy.followers? + approved_uris << ActivityPub::TagManager.instance.following_uri_for(object.account) if policy.following? approved_uris << ActivityPub::TagManager.instance.uri_for(object.account) if approved_uris.empty? { diff --git a/app/serializers/rest/scheduled_status_serializer.rb b/app/serializers/rest/scheduled_status_serializer.rb index 71ddb7b3e1707b..cc66c7cc95f218 100644 --- a/app/serializers/rest/scheduled_status_serializer.rb +++ b/app/serializers/rest/scheduled_status_serializer.rb @@ -12,7 +12,7 @@ def id def params object.params.merge( quoted_status_id: object.params['quoted_status_id']&.to_s, - quote_approval_policy: Status::QUOTE_APPROVAL_POLICY_FLAGS.keys.find { |key| object.params['quote_approval_policy']&.anybits?(Status::QUOTE_APPROVAL_POLICY_FLAGS[key] << 16) }&.to_s || 'nobody' + quote_approval_policy: InteractionPolicy::POLICY_FLAGS.keys.find { |key| object.params['quote_approval_policy']&.anybits?(InteractionPolicy::POLICY_FLAGS[key] << 16) }&.to_s || 'nobody' ) end end diff --git a/spec/lib/activitypub/activity/quote_request_spec.rb b/spec/lib/activitypub/activity/quote_request_spec.rb index aae4ce0338329f..db80448a80b6a4 100644 --- a/spec/lib/activitypub/activity/quote_request_spec.rb +++ b/spec/lib/activitypub/activity/quote_request_spec.rb @@ -87,7 +87,7 @@ context 'when trying to quote a quotable local status' do before do stub_request(:get, 'https://example.com/unknown-status').to_return(status: 200, body: Oj.dump(status_json), headers: { 'Content-Type': 'application/activity+json' }) - quoted_post.update(quote_approval_policy: Status::QUOTE_APPROVAL_POLICY_FLAGS[:public] << 16) + quoted_post.update(quote_approval_policy: InteractionPolicy::POLICY_FLAGS[:public] << 16) end it 'accepts the quote and sends an Accept activity' do @@ -105,7 +105,7 @@ let(:instrument) { status_json.without('@context') } before do - quoted_post.update(quote_approval_policy: Status::QUOTE_APPROVAL_POLICY_FLAGS[:public] << 16) + quoted_post.update(quote_approval_policy: InteractionPolicy::POLICY_FLAGS[:public] << 16) end it 'accepts the quote and sends an Accept activity' do diff --git a/spec/lib/activitypub/parser/status_parser_spec.rb b/spec/lib/activitypub/parser/status_parser_spec.rb index b251b63f43cfb5..3084f3ffd611e9 100644 --- a/spec/lib/activitypub/parser/status_parser_spec.rb +++ b/spec/lib/activitypub/parser/status_parser_spec.rb @@ -148,7 +148,7 @@ end it 'returns a policy not allowing anyone to quote' do - expect(subject).to eq(Status::QUOTE_APPROVAL_POLICY_FLAGS[:public] << 16) + expect(subject).to eq(InteractionPolicy::POLICY_FLAGS[:public] << 16) end end @@ -174,7 +174,7 @@ end it 'returns a policy allowing everyone including followers' do - expect(subject).to eq Status::QUOTE_APPROVAL_POLICY_FLAGS[:public] | (Status::QUOTE_APPROVAL_POLICY_FLAGS[:followers] << 16) + expect(subject).to eq InteractionPolicy::POLICY_FLAGS[:public] | (InteractionPolicy::POLICY_FLAGS[:followers] << 16) end end end diff --git a/spec/lib/interaction_policy_spec.rb b/spec/lib/interaction_policy_spec.rb new file mode 100644 index 00000000000000..2382c74349a45c --- /dev/null +++ b/spec/lib/interaction_policy_spec.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe InteractionPolicy do + subject { described_class.new(bitmap) } + + let(:bitmap) { (0b0101 << 16) | 0b0010 } + + describe described_class::SubPolicy do + subject { InteractionPolicy.new(bitmap) } + + describe '#as_keys' do + it 'returns the expected values' do + expect(subject.automatic.as_keys).to eq ['unsupported_policy', 'followers'] + expect(subject.manual.as_keys).to eq ['public'] + end + end + + describe '#public?' do + it 'returns the expected values' do + expect(subject.automatic.public?).to be false + expect(subject.manual.public?).to be true + end + end + + describe '#unsupported_policy?' do + it 'returns the expected values' do + expect(subject.automatic.unsupported_policy?).to be true + expect(subject.manual.unsupported_policy?).to be false + end + end + + describe '#followers?' do + it 'returns the expected values' do + expect(subject.automatic.followers?).to be true + expect(subject.manual.followers?).to be false + end + end + end +end diff --git a/spec/lib/status_cache_hydrator_spec.rb b/spec/lib/status_cache_hydrator_spec.rb index 8ad4e5614ef868..a6fea36397a0ca 100644 --- a/spec/lib/status_cache_hydrator_spec.rb +++ b/spec/lib/status_cache_hydrator_spec.rb @@ -29,7 +29,7 @@ end context 'when handling a status with a quote policy' do - let(:status) { Fabricate(:status, quote_approval_policy: Status::QUOTE_APPROVAL_POLICY_FLAGS[:followers] << 16) } + let(:status) { Fabricate(:status, quote_approval_policy: InteractionPolicy::POLICY_FLAGS[:followers] << 16) } before do account.follow!(status.account) diff --git a/spec/policies/status_policy_spec.rb b/spec/policies/status_policy_spec.rb index eb79aa6fcd1a1b..9690984317d554 100644 --- a/spec/policies/status_policy_spec.rb +++ b/spec/policies/status_policy_spec.rb @@ -152,19 +152,19 @@ end it 'grants access when public and policy allows everyone' do - status.quote_approval_policy = Status::QUOTE_APPROVAL_POLICY_FLAGS[:public] + status.quote_approval_policy = InteractionPolicy::POLICY_FLAGS[:public] viewer = Fabricate(:account) expect(subject).to permit(viewer, status) end it 'denies access when public and policy allows followers but viewer is not one' do - status.quote_approval_policy = Status::QUOTE_APPROVAL_POLICY_FLAGS[:followers] + status.quote_approval_policy = InteractionPolicy::POLICY_FLAGS[:followers] viewer = Fabricate(:account) expect(subject).to_not permit(viewer, status) end it 'grants access when public and policy allows followers and viewer is one' do - status.quote_approval_policy = Status::QUOTE_APPROVAL_POLICY_FLAGS[:followers] + status.quote_approval_policy = InteractionPolicy::POLICY_FLAGS[:followers] viewer = Fabricate(:account) viewer.follow!(status.account) expect(subject).to permit(viewer, status) diff --git a/spec/requests/api/v1/statuses/interaction_policies_spec.rb b/spec/requests/api/v1/statuses/interaction_policies_spec.rb index 321a68cd2519a0..aa5819cdd70518 100644 --- a/spec/requests/api/v1/statuses/interaction_policies_spec.rb +++ b/spec/requests/api/v1/statuses/interaction_policies_spec.rb @@ -46,7 +46,7 @@ context 'when changing the interaction policy' do it 'changes the interaction policy, returns the updated status, and schedules distribution jobs' do expect { subject } - .to change { status.reload.quote_approval_policy }.to(Status::QUOTE_APPROVAL_POLICY_FLAGS[:followers] << 16) + .to change { status.reload.quote_approval_policy }.to(InteractionPolicy::POLICY_FLAGS[:followers] << 16) expect(response).to have_http_status(200) expect(response.content_type) diff --git a/spec/requests/api/v1/statuses_spec.rb b/spec/requests/api/v1/statuses_spec.rb index e63437cc66fdec..5cfd4eaa4865bc 100644 --- a/spec/requests/api/v1/statuses_spec.rb +++ b/spec/requests/api/v1/statuses_spec.rb @@ -264,7 +264,7 @@ end context 'with a quote to a non-mentioned user in a Private Mention' do - let!(:quoted_status) { Fabricate(:status, quote_approval_policy: Status::QUOTE_APPROVAL_POLICY_FLAGS[:public] << 16) } + let!(:quoted_status) { Fabricate(:status, quote_approval_policy: InteractionPolicy::POLICY_FLAGS[:public] << 16) } let(:params) do { status: 'Hello, this is a quote', @@ -283,7 +283,7 @@ end context 'with a quote to a mentioned user in a Private Mention' do - let!(:quoted_status) { Fabricate(:status, quote_approval_policy: Status::QUOTE_APPROVAL_POLICY_FLAGS[:public] << 16) } + let!(:quoted_status) { Fabricate(:status, quote_approval_policy: InteractionPolicy::POLICY_FLAGS[:public] << 16) } let(:params) do { status: "Hello @#{quoted_status.account.acct}, this is a quote", @@ -305,7 +305,7 @@ end context 'with a quote of a reblog' do - let(:quoted_status) { Fabricate(:status, quote_approval_policy: Status::QUOTE_APPROVAL_POLICY_FLAGS[:public] << 16) } + let(:quoted_status) { Fabricate(:status, quote_approval_policy: InteractionPolicy::POLICY_FLAGS[:public] << 16) } let(:reblog) { Fabricate(:status, reblog: quoted_status) } let(:params) do { @@ -501,7 +501,7 @@ it 'updates the status', :aggregate_failures do expect { subject } - .to change { status.reload.quote_approval_policy }.to(Status::QUOTE_APPROVAL_POLICY_FLAGS[:public] << 16) + .to change { status.reload.quote_approval_policy }.to(InteractionPolicy::POLICY_FLAGS[:public] << 16) expect(response).to have_http_status(200) expect(response.content_type) diff --git a/spec/serializers/activitypub/note_serializer_spec.rb b/spec/serializers/activitypub/note_serializer_spec.rb index 0d11386d57b777..4970de709d1154 100644 --- a/spec/serializers/activitypub/note_serializer_spec.rb +++ b/spec/serializers/activitypub/note_serializer_spec.rb @@ -74,7 +74,7 @@ def reply_items end context 'with a quote policy' do - let(:parent) { Fabricate(:status, quote_approval_policy: Status::QUOTE_APPROVAL_POLICY_FLAGS[:followers] << 16) } + let(:parent) { Fabricate(:status, quote_approval_policy: InteractionPolicy::POLICY_FLAGS[:followers] << 16) } it 'has the expected shape' do expect(subject).to include({ diff --git a/spec/serializers/rest/scheduled_status_serializer_spec.rb b/spec/serializers/rest/scheduled_status_serializer_spec.rb index 6fc2f2eca9cd67..9eb27035d3fd44 100644 --- a/spec/serializers/rest/scheduled_status_serializer_spec.rb +++ b/spec/serializers/rest/scheduled_status_serializer_spec.rb @@ -10,7 +10,7 @@ ) end - let(:scheduled_status) { Fabricate.build(:scheduled_status, scheduled_at: 4.minutes.from_now, params: { application_id: 123, quoted_status_id: 456, quote_approval_policy: Status::QUOTE_APPROVAL_POLICY_FLAGS[:public] << 16 }) } + let(:scheduled_status) { Fabricate.build(:scheduled_status, scheduled_at: 4.minutes.from_now, params: { application_id: 123, quoted_status_id: 456, quote_approval_policy: InteractionPolicy::POLICY_FLAGS[:public] << 16 }) } describe 'serialization' do it 'returns expected values and removes application_id from params' do diff --git a/spec/services/activitypub/fetch_remote_status_service_spec.rb b/spec/services/activitypub/fetch_remote_status_service_spec.rb index 07d05d762f102a..6afee5f25ef263 100644 --- a/spec/services/activitypub/fetch_remote_status_service_spec.rb +++ b/spec/services/activitypub/fetch_remote_status_service_spec.rb @@ -330,7 +330,7 @@ end it 'updates status' do - expect(existing_status.reload.quote_approval_policy).to eq(Status::QUOTE_APPROVAL_POLICY_FLAGS[:public] << 16) + expect(existing_status.reload.quote_approval_policy).to eq(InteractionPolicy::POLICY_FLAGS[:public] << 16) end end end diff --git a/spec/services/activitypub/process_status_update_service_spec.rb b/spec/services/activitypub/process_status_update_service_spec.rb index 9d63c5f1fe2aab..1a19cbb782bf10 100644 --- a/spec/services/activitypub/process_status_update_service_spec.rb +++ b/spec/services/activitypub/process_status_update_service_spec.rb @@ -602,7 +602,7 @@ context 'when an approved quote of a local post gets updated through an explicit update, removing text' do let(:quoted_account) { Fabricate(:account) } - let(:quoted_status) { Fabricate(:status, account: quoted_account, quote_approval_policy: Status::QUOTE_APPROVAL_POLICY_FLAGS[:public] << 16) } + let(:quoted_status) { Fabricate(:status, account: quoted_account, quote_approval_policy: InteractionPolicy::POLICY_FLAGS[:public] << 16) } let!(:quote) { Fabricate(:quote, status: status, quoted_status: quoted_status, state: :accepted) } let(:approval_uri) { ActivityPub::TagManager.instance.approval_uri_for(quote) } @@ -638,7 +638,7 @@ context 'when an approved quote of a local post gets updated through an explicit update' do let(:quoted_account) { Fabricate(:account) } - let(:quoted_status) { Fabricate(:status, account: quoted_account, quote_approval_policy: Status::QUOTE_APPROVAL_POLICY_FLAGS[:public] << 16) } + let(:quoted_status) { Fabricate(:status, account: quoted_account, quote_approval_policy: InteractionPolicy::POLICY_FLAGS[:public] << 16) } let!(:quote) { Fabricate(:quote, status: status, quoted_status: quoted_status, state: :accepted) } let(:approval_uri) { ActivityPub::TagManager.instance.approval_uri_for(quote) } diff --git a/spec/services/post_status_service_spec.rb b/spec/services/post_status_service_spec.rb index 96289cdeee1acf..d226d77167a818 100644 --- a/spec/services/post_status_service_spec.rb +++ b/spec/services/post_status_service_spec.rb @@ -161,9 +161,9 @@ end it 'creates a status with the quote approval policy set' do - status = create_status_with_options(quote_approval_policy: Status::QUOTE_APPROVAL_POLICY_FLAGS[:followers] << 16) + status = create_status_with_options(quote_approval_policy: InteractionPolicy::POLICY_FLAGS[:followers] << 16) - expect(status.quote_approval_policy).to eq(Status::QUOTE_APPROVAL_POLICY_FLAGS[:followers] << 16) + expect(status.quote_approval_policy).to eq(InteractionPolicy::POLICY_FLAGS[:followers] << 16) end it 'processes mentions' do From 8debc5760b25443a57cad687b47561cb08d13a97 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 12:18:17 +0100 Subject: [PATCH 818/853] New Crowdin Translations (automated) (#37174) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/ar.json | 14 --- app/javascript/mastodon/locales/ast.json | 4 - app/javascript/mastodon/locales/az.json | 14 --- app/javascript/mastodon/locales/be.json | 52 +++++++--- app/javascript/mastodon/locales/bg.json | 14 --- app/javascript/mastodon/locales/br.json | 7 -- app/javascript/mastodon/locales/ca.json | 27 +++-- app/javascript/mastodon/locales/cs.json | 29 +++--- app/javascript/mastodon/locales/cy.json | 54 +++++++--- app/javascript/mastodon/locales/da.json | 54 +++++++--- app/javascript/mastodon/locales/de.json | 64 ++++++++---- app/javascript/mastodon/locales/el.json | 110 +++++++++++++-------- app/javascript/mastodon/locales/en-GB.json | 82 +++++++++------ app/javascript/mastodon/locales/eo.json | 21 ++-- app/javascript/mastodon/locales/es-AR.json | 49 ++++++--- app/javascript/mastodon/locales/es-MX.json | 52 +++++++--- app/javascript/mastodon/locales/es.json | 29 +++--- app/javascript/mastodon/locales/et.json | 20 +--- app/javascript/mastodon/locales/eu.json | 61 +++++++++--- app/javascript/mastodon/locales/fa.json | 14 --- app/javascript/mastodon/locales/fi.json | 53 +++++++--- app/javascript/mastodon/locales/fo.json | 52 +++++++--- app/javascript/mastodon/locales/fr-CA.json | 52 +++++++--- app/javascript/mastodon/locales/fr.json | 52 +++++++--- app/javascript/mastodon/locales/fy.json | 14 --- app/javascript/mastodon/locales/ga.json | 71 ++++++++----- app/javascript/mastodon/locales/gd.json | 14 --- app/javascript/mastodon/locales/gl.json | 49 ++++++--- app/javascript/mastodon/locales/he.json | 49 ++++++--- app/javascript/mastodon/locales/hu.json | 46 ++++++--- app/javascript/mastodon/locales/ia.json | 14 --- app/javascript/mastodon/locales/io.json | 14 --- app/javascript/mastodon/locales/is.json | 52 +++++++--- app/javascript/mastodon/locales/it.json | 54 +++++++--- app/javascript/mastodon/locales/ja.json | 14 --- app/javascript/mastodon/locales/kab.json | 4 - app/javascript/mastodon/locales/kk.json | 7 ++ app/javascript/mastodon/locales/ko.json | 42 +++++--- app/javascript/mastodon/locales/ku.json | 3 - app/javascript/mastodon/locales/lad.json | 9 -- app/javascript/mastodon/locales/lt.json | 14 --- app/javascript/mastodon/locales/lv.json | 18 ++-- app/javascript/mastodon/locales/ms.json | 14 --- app/javascript/mastodon/locales/nan.json | 49 ++++++--- app/javascript/mastodon/locales/ne.json | 2 - app/javascript/mastodon/locales/nl.json | 52 +++++++--- app/javascript/mastodon/locales/nn.json | 14 --- app/javascript/mastodon/locales/no.json | 14 --- app/javascript/mastodon/locales/oc.json | 2 - app/javascript/mastodon/locales/pa.json | 8 -- app/javascript/mastodon/locales/pl.json | 14 --- app/javascript/mastodon/locales/pt-BR.json | 94 +++++++++++------- app/javascript/mastodon/locales/pt-PT.json | 55 ++++++++--- app/javascript/mastodon/locales/ro.json | 11 --- app/javascript/mastodon/locales/ru.json | 28 +++--- app/javascript/mastodon/locales/sc.json | 6 -- app/javascript/mastodon/locales/si.json | 14 --- app/javascript/mastodon/locales/sk.json | 14 --- app/javascript/mastodon/locales/sl.json | 14 --- app/javascript/mastodon/locales/sq.json | 45 +++++++-- app/javascript/mastodon/locales/sv.json | 22 ++--- app/javascript/mastodon/locales/th.json | 13 --- app/javascript/mastodon/locales/tok.json | 14 --- app/javascript/mastodon/locales/tr.json | 48 ++++++--- app/javascript/mastodon/locales/uk.json | 14 --- app/javascript/mastodon/locales/vi.json | 52 +++++++--- app/javascript/mastodon/locales/zh-CN.json | 49 ++++++--- app/javascript/mastodon/locales/zh-HK.json | 1 - app/javascript/mastodon/locales/zh-TW.json | 78 ++++++++++----- config/locales/activerecord.ca.yml | 6 ++ config/locales/activerecord.en-GB.yml | 8 +- config/locales/activerecord.eu.yml | 6 ++ config/locales/activerecord.ko.yml | 4 + config/locales/be.yml | 3 + config/locales/ca.yml | 3 + config/locales/cs.yml | 3 + config/locales/cy.yml | 11 +++ config/locales/da.yml | 3 + config/locales/de.yml | 35 ++++--- config/locales/devise.el.yml | 2 +- config/locales/devise.en-GB.yml | 30 +++--- config/locales/doorkeeper.de.yml | 2 +- config/locales/doorkeeper.en-GB.yml | 4 +- config/locales/el.yml | 27 ++--- config/locales/en-GB.yml | 107 ++++++++++---------- config/locales/es-AR.yml | 3 + config/locales/es-MX.yml | 37 +++---- config/locales/es.yml | 3 + config/locales/fi.yml | 5 + config/locales/fo.yml | 3 + config/locales/fr-CA.yml | 3 + config/locales/fr.yml | 3 + config/locales/ga.yml | 3 + config/locales/gl.yml | 3 + config/locales/he.yml | 3 + config/locales/hu.yml | 5 + config/locales/is.yml | 3 + config/locales/it.yml | 3 + config/locales/ko.yml | 4 + config/locales/nan.yml | 30 ++++++ config/locales/nl.yml | 3 + config/locales/pt-BR.yml | 3 + config/locales/pt-PT.yml | 7 +- config/locales/ru.yml | 2 + config/locales/simple_form.el.yml | 6 +- config/locales/simple_form.en-GB.yml | 60 +++++------ config/locales/simple_form.ko.yml | 1 + config/locales/simple_form.zh-TW.yml | 6 +- config/locales/sq.yml | 4 + config/locales/tr.yml | 3 + config/locales/vi.yml | 3 + config/locales/zh-CN.yml | 3 + config/locales/zh-TW.yml | 3 + 113 files changed, 1571 insertions(+), 1107 deletions(-) diff --git a/app/javascript/mastodon/locales/ar.json b/app/javascript/mastodon/locales/ar.json index dd29e459b0773f..2ef46af6d70f28 100644 --- a/app/javascript/mastodon/locales/ar.json +++ b/app/javascript/mastodon/locales/ar.json @@ -107,25 +107,11 @@ "alt_text_modal.describe_for_people_with_visual_impairments": "قم بوصفها للأشخاص ذوي الإعاقة البصرية…", "alt_text_modal.done": "تمّ", "announcement.announcement": "إعلان", - "annual_report.summary.archetype.booster": "The cool-hunter", - "annual_report.summary.archetype.lurker": "المتصفح الصامت", - "annual_report.summary.archetype.oracle": "الحكيم", - "annual_report.summary.archetype.pollster": "مستطلع للرأي", - "annual_report.summary.archetype.replier": "الفراشة الاجتماعية", - "annual_report.summary.followers.followers": "المُتابِعُون", - "annual_report.summary.followers.total": "{count} في المجمل", - "annual_report.summary.here_it_is": "فيما يلي ملخصك لسنة {year}:", - "annual_report.summary.highlighted_post.by_favourites": "المنشور ذو أعلى عدد تفضيلات", - "annual_report.summary.highlighted_post.by_reblogs": "أكثر منشور مُعاد نشره", - "annual_report.summary.highlighted_post.by_replies": "المنشور بأعلى عدد تعليقات", - "annual_report.summary.highlighted_post.possessive": "من قبل {name}", "annual_report.summary.most_used_app.most_used_app": "التطبيق الأكثر استخداماً", "annual_report.summary.most_used_hashtag.most_used_hashtag": "الهاشتاق الأكثر استخداماً", - "annual_report.summary.most_used_hashtag.none": "لا شيء", "annual_report.summary.new_posts.new_posts": "المنشورات الجديدة", "annual_report.summary.percentile.text": "هذا يجعلك من بين أكثر مستخدمي {domain} نشاطاً ", "annual_report.summary.percentile.we_wont_tell_bernie": "سيبقى هذا الأمر بيننا.", - "annual_report.summary.thanks": "شكرا لكونك جزءاً من ماستدون!", "attachments_list.unprocessed": "(غير معالَج)", "audio.hide": "إخفاء المقطع الصوتي", "block_modal.remote_users_caveat": "سوف نطلب من الخادم {domain} أن يحترم قرارك، لكن الالتزام غير مضمون لأن بعض الخواديم قد تتعامل مع نصوص الكتل بشكل مختلف. قد تظل المنشورات العامة مرئية للمستخدمين غير المسجلين الدخول.", diff --git a/app/javascript/mastodon/locales/ast.json b/app/javascript/mastodon/locales/ast.json index 50b0122297d525..b14b0a302730e0 100644 --- a/app/javascript/mastodon/locales/ast.json +++ b/app/javascript/mastodon/locales/ast.json @@ -71,11 +71,7 @@ "alt_text_modal.cancel": "Encaboxar", "alt_text_modal.done": "Fecho", "announcement.announcement": "Anunciu", - "annual_report.summary.followers.followers": "siguidores", - "annual_report.summary.here_it_is": "Equí ta'l to resume de {year}:", - "annual_report.summary.highlighted_post.possessive": "de {name}", "annual_report.summary.new_posts.new_posts": "artículos nuevos", - "annual_report.summary.thanks": "Gracies por ser parte de Mastodon!", "attachments_list.unprocessed": "(ensin procesar)", "block_modal.show_less": "Amosar menos", "block_modal.show_more": "Amosar más", diff --git a/app/javascript/mastodon/locales/az.json b/app/javascript/mastodon/locales/az.json index e895e71921973b..59466034e32559 100644 --- a/app/javascript/mastodon/locales/az.json +++ b/app/javascript/mastodon/locales/az.json @@ -107,25 +107,11 @@ "alt_text_modal.describe_for_people_with_visual_impairments": "Görmə məhdudiyyətli insanlar üçün bunu təsvir et…", "alt_text_modal.done": "Oldu", "announcement.announcement": "Elan", - "annual_report.summary.archetype.booster": "Trend ovçusu", - "annual_report.summary.archetype.lurker": "Lurker", - "annual_report.summary.archetype.oracle": "Orakl", - "annual_report.summary.archetype.pollster": "Sorğu ustası", - "annual_report.summary.archetype.replier": "Sosial kəpənək", - "annual_report.summary.followers.followers": "izləyici", - "annual_report.summary.followers.total": "Cəmi {count}", - "annual_report.summary.here_it_is": "{year} icmalınız:", - "annual_report.summary.highlighted_post.by_favourites": "ən çox sevilən postu", - "annual_report.summary.highlighted_post.by_reblogs": "ən çox təkrar paylaşılan göndəriş", - "annual_report.summary.highlighted_post.by_replies": "ən çox cavabı olan paylaşımı", - "annual_report.summary.highlighted_post.possessive": "{name} istifadəçisinin", "annual_report.summary.most_used_app.most_used_app": "ən çox istifadə etdiyi tətbiq", "annual_report.summary.most_used_hashtag.most_used_hashtag": "ən çox istifadə etdiyi heşteq", - "annual_report.summary.most_used_hashtag.none": "Yoxdur", "annual_report.summary.new_posts.new_posts": "yeni paylaşım", "annual_report.summary.percentile.text": "Bu sizi {domain} istifadəçilərinin ilkqoyur.", "annual_report.summary.percentile.we_wont_tell_bernie": "Bunu Berniyə deməyəcəyik.", - "annual_report.summary.thanks": "Mastodonun bir parçası olduğunuz üçün təşəkkür edirik!", "attachments_list.unprocessed": "(emal edilməyib)", "audio.hide": "Audionu gizlət", "block_modal.remote_users_caveat": "{domain} serverindən qərarınıza hörmət etməsini xahiş edəcəyik. Ancaq, bəzi serverlər əngəlləmələri fərqli şəkildə idarə edə bilər deyə, qərarınıza uymağına zəmanət verilmir. Hər kəsə açıq göndərişlər, hələ də sistemə giriş etməmiş istifadəçilərə görünə bilər.", diff --git a/app/javascript/mastodon/locales/be.json b/app/javascript/mastodon/locales/be.json index ed22eda8d4570f..eb209f2d41936f 100644 --- a/app/javascript/mastodon/locales/be.json +++ b/app/javascript/mastodon/locales/be.json @@ -114,29 +114,51 @@ "alt_text_modal.done": "Гатова", "announcement.announcement": "Аб'ява", "annual_report.announcement.action_build": "Старыць мне Вынікадон", + "annual_report.announcement.action_dismiss": "Не, дзякуй", "annual_report.announcement.action_view": "Паглядзець мой Вынікадон", "annual_report.announcement.description": "Даведайцеся больш пра Вашыя ўзаемадзеянні ў Mastodon за апошні год.", "annual_report.announcement.title": "Вынікадон {year} ужо тут", - "annual_report.summary.archetype.booster": "Паляўнічы на трэнды", - "annual_report.summary.archetype.lurker": "Назіральнік", - "annual_report.summary.archetype.oracle": "Аракул", - "annual_report.summary.archetype.pollster": "Апытвальнік", - "annual_report.summary.archetype.replier": "Душа кампаніі", - "annual_report.summary.followers.followers": "падпісчыкі", - "annual_report.summary.followers.total": "Агулам {count}", - "annual_report.summary.here_it_is": "Вось Вашы вынікі {year} за год:", - "annual_report.summary.highlighted_post.by_favourites": "самы ўпадабаны допіс", - "annual_report.summary.highlighted_post.by_reblogs": "самы пашыраны допіс", - "annual_report.summary.highlighted_post.by_replies": "самы каментаваны допіс", - "annual_report.summary.highlighted_post.possessive": "{name}", + "annual_report.nav_item.badge": "Новы", + "annual_report.shared_page.donate": "Ахвяраваць", + "annual_report.shared_page.footer": "З {heart} згенеравала каманда Mastodon", + "annual_report.shared_page.footer_server_info": "{username} карыстаецца {domain}, адной са шматлікіх супольнасцяў, якія ўтрымлівае Mastodon.", + "annual_report.summary.archetype.booster.desc_public": "{name} увесь час паляваў(-ла) на допісы, каб пашырыць іх і разгаласіць аб іх аўтарах ідэальнымі стрэламі.", + "annual_report.summary.archetype.booster.desc_self": "Вы ўвесь час палявалі на допісы, каб пашырыць іх і разгаласіць аб іх аўтарах ідэальнымі стрэламі.", + "annual_report.summary.archetype.booster.name": "Лучнік", + "annual_report.summary.archetype.die_drei_fragezeichen": "???", + "annual_report.summary.archetype.lurker.desc_public": "Мы ведаем, што {name} быў(-ла) дзесьці тут і па-свойму атрымліваў(-ла) асалоду ад Mastodon.", + "annual_report.summary.archetype.lurker.desc_self": "Мы ведаем, што Вы былі дзесьці тут і па-свойму атрымлівалі асалоду ад Mastodon.", + "annual_report.summary.archetype.lurker.name": "Стоік", + "annual_report.summary.archetype.oracle.desc_public": "Новых допісаў у {name} было больш, чым адказаў, і гэткім чынам ён (яна) пакідаў(-ла) Mastodon свежым і накіраваным у будучыню.", + "annual_report.summary.archetype.oracle.desc_self": "Новых допісаў у Вас было больш, чым адказаў, і гэткім чынам Вы пакідалі Mastodon свежым і накіраваным у будучыню.", + "annual_report.summary.archetype.oracle.name": "Аракул", + "annual_report.summary.archetype.pollster.desc_public": "Сярод допісаў {name} было найбольш апытанак, якімі ён (яна) падымаў(-ла) цікаўнасць у Mastodon.", + "annual_report.summary.archetype.pollster.desc_self": "Сярод Вашых допісаў было найбольш апытанак, якімі Вы падымалі цікаўнасць у Mastodon.", + "annual_report.summary.archetype.pollster.name": "Даследчык", + "annual_report.summary.archetype.replier.desc_public": "{name} часта адказваў(-ла) на допісы іншых людзей, апыляючы Mastodon новымі дыскусіямі.", + "annual_report.summary.archetype.replier.desc_self": "Вы часта адказвалі на допісы іншых людзей, апыляючы Mastodon новымі дыскусіямі.", + "annual_report.summary.archetype.replier.name": "Матыль", + "annual_report.summary.archetype.reveal": "Раскрыць мой архетып", + "annual_report.summary.archetype.reveal_description": "Дзякуй за тое, што Вы былі і застаяцеся часткай Mastodon! Час даведацца, які архетып Вы ўвасобілі ў {year}-ым годзе.", + "annual_report.summary.archetype.title_public": "Архетып {name}", + "annual_report.summary.archetype.title_self": "Ваш архетып", + "annual_report.summary.close": "Закрыць", + "annual_report.summary.copy_link": "Скапіраваць", + "annual_report.summary.followers.new_followers": "{count, plural, one {новы падпісчык} few {новыя падпісчыкі} other {новых падпісчыкаў}}", + "annual_report.summary.highlighted_post.boost_count": "Гэты допіс пашырылі {count, plural, one {адзін раз} few {# разы} other {# разоў}}.", + "annual_report.summary.highlighted_post.favourite_count": "Гэты допіс упадабалі {count, plural, one {адзін раз} few {# разы} other {# разоў}}.", + "annual_report.summary.highlighted_post.reply_count": "На гэты допіс адказалі {count, plural, one {адзін раз} few {# разы} other {# разоў}}.", + "annual_report.summary.highlighted_post.title": "Самы папулярны допіс", "annual_report.summary.most_used_app.most_used_app": "праграма, якой карысталіся найчасцей", "annual_report.summary.most_used_hashtag.most_used_hashtag": "хэштэг, якім карысталіся найчасцей", - "annual_report.summary.most_used_hashtag.none": "Няма", + "annual_report.summary.most_used_hashtag.used_count": "Вы выкарысталі гэты хэштэг у {count, plural, one {адным допісе} other {# допісах}}.", + "annual_report.summary.most_used_hashtag.used_count_public": "{name} выкарыстаў(-ла) гэты хэштэг у {count, plural, one {адным допісе} other {# допісах}}.", "annual_report.summary.new_posts.new_posts": "новыя допісы", "annual_report.summary.percentile.text": "Гэта падымае Вас у топ карыстальнікаў {domain}.", "annual_report.summary.percentile.we_wont_tell_bernie": "КДБ пра гэта не даведаецца.", + "annual_report.summary.share_elsewhere": "Падзяліцца ў іншым месцы", "annual_report.summary.share_message": "Мой архетып – {archetype}!", - "annual_report.summary.thanks": "Дзякуй за ўдзел у Mastodon!", + "annual_report.summary.share_on_mastodon": "Падзяліцца ў Mastodon", "attachments_list.unprocessed": "(неапрацаваны)", "audio.hide": "Схаваць аўдыя", "block_modal.remote_users_caveat": "Мы папросім сервер {domain} паважаць Ваш выбар. Аднак гэта не гарантуецца, паколькі некаторыя серверы могуць апрацоўваць блакіроўкі іншым чынам. Публічныя паведамленні могуць заставацца бачнымі для ананімных карыстальнікаў.", @@ -419,6 +441,8 @@ "follow_suggestions.who_to_follow": "На каго падпісацца", "followed_tags": "Падпіскі", "footer.about": "Пра нас", + "footer.about_mastodon": "Пра Mastodon", + "footer.about_server": "Пра {domain}", "footer.about_this_server": "Пра сервер", "footer.directory": "Дырэкторыя профіляў", "footer.get_app": "Спампаваць праграму", diff --git a/app/javascript/mastodon/locales/bg.json b/app/javascript/mastodon/locales/bg.json index 7e8f132d39a266..c6b0f373aa0a7a 100644 --- a/app/javascript/mastodon/locales/bg.json +++ b/app/javascript/mastodon/locales/bg.json @@ -111,25 +111,11 @@ "alt_text_modal.describe_for_people_with_visual_impairments": "Опишете това за хора със зрителни увреждания…", "alt_text_modal.done": "Готово", "announcement.announcement": "Оповестяване", - "annual_report.summary.archetype.booster": "Якият подсилвател", - "annual_report.summary.archetype.lurker": "Дебнещото", - "annual_report.summary.archetype.oracle": "Оракул", - "annual_report.summary.archetype.pollster": "Анкетьорче", - "annual_report.summary.archetype.replier": "Социална пеперуда", - "annual_report.summary.followers.followers": "последователи", - "annual_report.summary.followers.total": "{count} общо", - "annual_report.summary.here_it_is": "Ето преглед на вашата {year} година:", - "annual_report.summary.highlighted_post.by_favourites": "най-правено като любима публикация", - "annual_report.summary.highlighted_post.by_reblogs": "най-подсилваната публикация", - "annual_report.summary.highlighted_post.by_replies": "публикация с най-много отговори", - "annual_report.summary.highlighted_post.possessive": "на {name}", "annual_report.summary.most_used_app.most_used_app": "най-употребявано приложение", "annual_report.summary.most_used_hashtag.most_used_hashtag": "най-употребяван хаштаг", - "annual_report.summary.most_used_hashtag.none": "Няма", "annual_report.summary.new_posts.new_posts": "нови публикации", "annual_report.summary.percentile.text": "Това ви слага най-отгоресред потребителите на {domain}.", "annual_report.summary.percentile.we_wont_tell_bernie": "Няма да кажем на Бърни Сандърс.", - "annual_report.summary.thanks": "Благодарим, че сте част от Mastodon!", "attachments_list.unprocessed": "(необработено)", "audio.hide": "Скриване на звука", "block_modal.remote_users_caveat": "Ще приканим сървъра {domain} да уважава решението ви. За съжаление не можем да гарантираме това защото някои сървъри могат да третират блокиранията по различен начин. Публичните постове може да продължат да бъдат видими за потребители, които не са се регистрирали.", diff --git a/app/javascript/mastodon/locales/br.json b/app/javascript/mastodon/locales/br.json index d58e8764ed88c4..564630e2d2d08c 100644 --- a/app/javascript/mastodon/locales/br.json +++ b/app/javascript/mastodon/locales/br.json @@ -106,15 +106,8 @@ "alt_text_modal.change_thumbnail": "Kemmañ ar velvenn", "alt_text_modal.done": "Graet", "announcement.announcement": "Kemennad", - "annual_report.summary.followers.followers": "heulier", - "annual_report.summary.followers.total": "{count} en holl", - "annual_report.summary.highlighted_post.by_favourites": "embannadur karet ar muiañ", - "annual_report.summary.highlighted_post.by_reblogs": "embannadur skignet ar muiañ", - "annual_report.summary.highlighted_post.by_replies": "embannadur gant ar muiañ a respontoù", - "annual_report.summary.highlighted_post.possessive": "{name}", "annual_report.summary.most_used_app.most_used_app": "arload muiañ implijet", "annual_report.summary.most_used_hashtag.most_used_hashtag": "ar gerioù-klik implijet ar muiañ", - "annual_report.summary.most_used_hashtag.none": "Hini ebet", "annual_report.summary.new_posts.new_posts": "embannadurioù nevez", "attachments_list.unprocessed": "(ket meret)", "audio.hide": "Kuzhat ar c'hleved", diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json index d546426cf22ac8..29ac3879c4c8a3 100644 --- a/app/javascript/mastodon/locales/ca.json +++ b/app/javascript/mastodon/locales/ca.json @@ -114,29 +114,24 @@ "alt_text_modal.done": "Fet", "announcement.announcement": "Anunci", "annual_report.announcement.action_build": "El meu Wrapstodon s'ha fet", + "annual_report.announcement.action_dismiss": "No, gràcies", "annual_report.announcement.action_view": "Vegeu el meu Wrapstodon", "annual_report.announcement.description": "Descobriu més sobre el vostre involucrament a Mastodon durant l'any passat.", "annual_report.announcement.title": "Ha arribat Wrapstodon {year}", - "annual_report.summary.archetype.booster": "Sempre a la moda", - "annual_report.summary.archetype.lurker": "Tot ho llegeix", - "annual_report.summary.archetype.oracle": "L'Oracle", - "annual_report.summary.archetype.pollster": "Tot són enquestes", - "annual_report.summary.archetype.replier": "Tot ho respon", - "annual_report.summary.followers.followers": "seguidors", - "annual_report.summary.followers.total": "{count} en total", - "annual_report.summary.here_it_is": "El repàs del vostre {year}:", - "annual_report.summary.highlighted_post.by_favourites": "la publicació més afavorida", - "annual_report.summary.highlighted_post.by_reblogs": "la publicació més impulsada", - "annual_report.summary.highlighted_post.by_replies": "la publicació amb més respostes", - "annual_report.summary.highlighted_post.possessive": "de {name}", + "annual_report.nav_item.badge": "Nou", + "annual_report.shared_page.donate": "Fer una donació", + "annual_report.shared_page.footer": "Generat amb {heart} per l'equip de Mastodon", + "annual_report.summary.archetype.die_drei_fragezeichen": "???", + "annual_report.summary.copy_link": "Copia l'enllaç", "annual_report.summary.most_used_app.most_used_app": "l'aplicació més utilitzada", "annual_report.summary.most_used_hashtag.most_used_hashtag": "l'etiqueta més utilitzada", - "annual_report.summary.most_used_hashtag.none": "Cap", + "annual_report.summary.most_used_hashtag.used_count_public": "{name} ha inclòs aquesta etiqueta a {count, plural, one {una publicació} other {# publicacions}}.", "annual_report.summary.new_posts.new_posts": "publicacions noves", "annual_report.summary.percentile.text": "Que us posa alcapdamunt dels usuaris de {domain}.", "annual_report.summary.percentile.we_wont_tell_bernie": "No li ho direm al Bernie.", + "annual_report.summary.share_elsewhere": "Compartir a una altra banda", "annual_report.summary.share_message": "Tinc l'arquetip {archetype}!", - "annual_report.summary.thanks": "Gràcies per formar part de Mastodon!", + "annual_report.summary.share_on_mastodon": "Compartir a Mastodon", "attachments_list.unprocessed": "(sense processar)", "audio.hide": "Amaga l'àudio", "block_modal.remote_users_caveat": "Li demanarem al servidor {domain} que respecti la vostra decisió, tot i que no podem garantir-ho, ja que alguns servidors gestionen de forma diferent els blocatges. És possible que els usuaris no autenticats puguin veure les publicacions públiques.", @@ -362,6 +357,7 @@ "empty_column.notification_requests": "Tot net, ja no hi ha res aquí! Quan rebeu notificacions noves, segons la vostra configuració, apareixeran aquí.", "empty_column.notifications": "Encara no tens notificacions. Quan altre gent interactuï amb tu, les veuràs aquí.", "empty_column.public": "Aquí no hi ha res! Escriu públicament alguna cosa o segueix manualment usuaris d'altres servidors per omplir-ho", + "error.no_hashtag_feed_access": "Creeu un compte o accediu per a veure i seguir aquesta etiqueta.", "error.unexpected_crash.explanation": "A causa d'un error en el nostre codi o d'un problema de compatibilitat amb el navegador, aquesta pàgina no s'ha pogut mostrar correctament.", "error.unexpected_crash.explanation_addons": "Aquesta pàgina no s'ha pogut mostrar correctament. És probable que aquest error sigui causat per un complement del navegador o per eines de traducció automàtica.", "error.unexpected_crash.next_steps": "Prova d'actualitzar la pàgina. Si això no serveix, és possible que encara puguis fer servir Mastodon a través d'un navegador diferent o amb una aplicació nativa.", @@ -908,6 +904,7 @@ "status.edited_x_times": "Editat {count, plural, one {{count} vegada} other {{count} vegades}}", "status.embed": "Obté el codi encastat", "status.favourite": "Favorit", + "status.favourites_count": "{count, plural, one {{counter} favorit} other {{counter} favorits}}", "status.filter": "Filtra aquest tut", "status.history.created": "creat per {name} {date}", "status.history.edited": "editat per {name} {date}", @@ -942,12 +939,14 @@ "status.quotes.empty": "Encara no ha citat aquesta publicació ningú. Quan ho faci algú apareixerà aquí.", "status.quotes.local_other_disclaimer": "No es mostraran les cites rebutjades per l'autor.", "status.quotes.remote_other_disclaimer": "Només es garanteix que es mostraran aquí les cites de {domain}. No es mostraran les rebutjades per l'autor.", + "status.quotes_count": "{count, plural, one {{counter} citació} other {{counter} citacions}}", "status.read_more": "Més informació", "status.reblog": "Impulsa", "status.reblog_or_quote": "Impuls or cita", "status.reblog_private": "Compartiu de nou amb els vostres seguidors", "status.reblogged_by": "impulsat per {name}", "status.reblogs.empty": "Encara no ha impulsat ningú aquest tut. Quan algú ho faci, apareixerà aquí.", + "status.reblogs_count": "{count, plural, one {{counter} impuls} other {{counter} impulsos}}", "status.redraft": "Esborra i reescriu", "status.remove_bookmark": "Elimina el marcador", "status.remove_favourite": "Elimina dels preferits", diff --git a/app/javascript/mastodon/locales/cs.json b/app/javascript/mastodon/locales/cs.json index b5d594058fec89..3aeb92ec6e5a4e 100644 --- a/app/javascript/mastodon/locales/cs.json +++ b/app/javascript/mastodon/locales/cs.json @@ -114,29 +114,30 @@ "alt_text_modal.done": "Hotovo", "announcement.announcement": "Oznámení", "annual_report.announcement.action_build": "Sestavit můj Wrapstodon", + "annual_report.announcement.action_dismiss": "Ne, děkuji", "annual_report.announcement.action_view": "Zobrazit můj Wrapstodon", "annual_report.announcement.description": "Zjistěte více o vaší aktivitě na Mastodonu za poslední rok.", "annual_report.announcement.title": "Je zde Wrapstodon {year}", - "annual_report.summary.archetype.booster": "Lovec obsahu", - "annual_report.summary.archetype.lurker": "Špión", - "annual_report.summary.archetype.oracle": "Vědma", - "annual_report.summary.archetype.pollster": "Průzkumník", - "annual_report.summary.archetype.replier": "Sociální motýlek", - "annual_report.summary.followers.followers": "sledujících", - "annual_report.summary.followers.total": "{count} celkem", - "annual_report.summary.here_it_is": "Zde je tvůj rok {year} v přehledu:", - "annual_report.summary.highlighted_post.by_favourites": "nejvíce oblíbený příspěvek", - "annual_report.summary.highlighted_post.by_reblogs": "nejvíce boostovaný příspěvek", - "annual_report.summary.highlighted_post.by_replies": "příspěvek s nejvíce odpověďmi", - "annual_report.summary.highlighted_post.possessive": "{name}", + "annual_report.nav_item.badge": "Nový", + "annual_report.shared_page.donate": "Podpořit", + "annual_report.shared_page.footer": "Vytvořeno s {heart} týmem Mastodon", + "annual_report.summary.archetype.reveal": "Odhalit můj archetyp", + "annual_report.summary.archetype.reveal_description": "Děkujeme, že jste součástí Mastodonu! Čas zjistit, který archetype jste ztělesnili v roce {year}.", + "annual_report.summary.archetype.title_public": "Archetyp {name}", + "annual_report.summary.archetype.title_self": "Váš archetyp", + "annual_report.summary.close": "Zavřít", + "annual_report.summary.copy_link": "Zkopírovat odkaz", + "annual_report.summary.highlighted_post.title": "Nejpopulárnější příspěvek", "annual_report.summary.most_used_app.most_used_app": "nejpoužívanější aplikace", "annual_report.summary.most_used_hashtag.most_used_hashtag": "nejpoužívanější hashtag", - "annual_report.summary.most_used_hashtag.none": "Žádné", + "annual_report.summary.most_used_hashtag.used_count": "Tento hashtag jste vložili do {count, plural, one {jednoho příspěvku} few {# příspěvků} many {# příspěvků} other {# příspěvků}}.", + "annual_report.summary.most_used_hashtag.used_count_public": "{name} vložili tento hashtag do {count, plural, one {jednoho příspěveku} few {# příspěvků} many {# příspěvků} other {# příspěvků}}.", "annual_report.summary.new_posts.new_posts": "nové příspěvky", "annual_report.summary.percentile.text": "To vás umisťuje do horních uživatelů domény {domain}.", "annual_report.summary.percentile.we_wont_tell_bernie": "To, že jste zdejší smetánka, zůstane mezi námi ;).", + "annual_report.summary.share_elsewhere": "Sdílet jinde", "annual_report.summary.share_message": "Mám archetyp {archetype}!", - "annual_report.summary.thanks": "Děkujeme, že jste součástí Mastodonu!", + "annual_report.summary.share_on_mastodon": "Sdílet na Mastodonu", "attachments_list.unprocessed": "(nezpracováno)", "audio.hide": "Skrýt zvuk", "block_modal.remote_users_caveat": "Požádáme server {domain}, aby respektoval vaše rozhodnutí. Úplné dodržování nastavení však není zaručeno, protože některé servery mohou řešit blokování různě. Veřejné příspěvky mohou být stále viditelné pro nepřihlášené uživatele.", diff --git a/app/javascript/mastodon/locales/cy.json b/app/javascript/mastodon/locales/cy.json index fcf33e4635d529..e96a63ff424666 100644 --- a/app/javascript/mastodon/locales/cy.json +++ b/app/javascript/mastodon/locales/cy.json @@ -113,25 +113,50 @@ "alt_text_modal.describe_for_people_with_visual_impairments": "Disgrifiwch hyn ar gyfer pobl â nam ar eu golwg…", "alt_text_modal.done": "Gorffen", "announcement.announcement": "Cyhoeddiad", - "annual_report.summary.archetype.booster": "Y hyrwyddwr", - "annual_report.summary.archetype.lurker": "Y crwydryn", - "annual_report.summary.archetype.oracle": "Yr oracl", - "annual_report.summary.archetype.pollster": "Yr arholwr", - "annual_report.summary.archetype.replier": "Y sbardunwr", - "annual_report.summary.followers.followers": "dilynwyr", - "annual_report.summary.followers.total": "Cyfanswm o{count}", - "annual_report.summary.here_it_is": "Dyma eich {year} yn gryno:", - "annual_report.summary.highlighted_post.by_favourites": "postiad wedi'i ffefrynu fwyaf", - "annual_report.summary.highlighted_post.by_reblogs": "postiad wedi'i hybu fwyaf", - "annual_report.summary.highlighted_post.by_replies": "postiad gyda'r nifer fwyaf o ymatebion", - "annual_report.summary.highlighted_post.possessive": "{name}", + "annual_report.announcement.action_build": "Adeiladu fy Wrapstodon", + "annual_report.announcement.action_dismiss": "Dim diolch", + "annual_report.announcement.action_view": "Gweld fy Wrapstodon", + "annual_report.announcement.description": "Darganfod mwy am eich ymgysylltiad â Mastodon dros y flwyddyn ddiwethaf.", + "annual_report.announcement.title": "Mae Wrapstodon {year} wedi cyrraedd", + "annual_report.nav_item.badge": "Newydd", + "annual_report.shared_page.donate": "Cyfrannu", + "annual_report.shared_page.footer": "Wedi'i gynhyrchu gyda {heart} gan dîm Mastodon", + "annual_report.summary.archetype.booster.desc_public": "Parhaodd {name} i chwilio am bostiadau i'w hybu, gan hyrwyddo crewyr eraill yn effeithiol.", + "annual_report.summary.archetype.booster.desc_self": "Fe wnaethoch chi aros ar y chwilio am bostiadau i'w hybu, gan chwyddo crewyr eraill yn effeithiol.", + "annual_report.summary.archetype.booster.name": "Y Saethydd", + "annual_report.summary.archetype.lurker.desc_public": "Rydyn ni'n gwybod bod {name} allan yna, yn rhywle, yn mwynhau Mastodon yn eu ffordd dawel eu hunain.", + "annual_report.summary.archetype.lurker.desc_self": "Rydyn ni'n gwybod eich bod chi allan yna, yn rhywle, yn mwynhau Mastodon yn eich ffordd dawel eich hun.", + "annual_report.summary.archetype.lurker.name": "Y Stoicaidd", + "annual_report.summary.archetype.oracle.desc_public": "Creodd {name} fwy o bostiadau newydd nag atebion, gan gadw Mastodon yn ffres ac yn edrych i'r dyfodol.", + "annual_report.summary.archetype.oracle.desc_self": "Fe wnaethoch chi greu mwy o bostiadau newydd nag atebion, gan gadw Mastodon yn ffres ac yn edrych i'r dyfodol.", + "annual_report.summary.archetype.oracle.name": "Yr Oracl", + "annual_report.summary.archetype.pollster.desc_public": "Creodd {name} fwy o arolygon barn na mathau eraill o bostiadau, gan feithrin chwilfrydedd am Mastodon.", + "annual_report.summary.archetype.pollster.desc_self": "Fe greoch chi fwy o arolygon barn na mathau eraill o bostiadau, gan feithrin chwilfrydedd ar Mastodon.", + "annual_report.summary.archetype.pollster.name": "Y Syfrdanwr", + "annual_report.summary.archetype.replier.desc_public": "Roedd {name} yn aml yn ymateb i bostiadau pobl eraill, gan beillio Mastodon gyda thrafodaethau newydd.", + "annual_report.summary.archetype.replier.desc_self": "Roeddech chi'n aml yn ymateb i bostiadau pobl eraill, gan hau Mastodon gyda thrafodaethau newydd.", + "annual_report.summary.archetype.replier.name": "Y Pili-pala", + "annual_report.summary.archetype.reveal": "Datgelu fy nhuedd", + "annual_report.summary.archetype.reveal_description": "Diolch am fod yn rhan o Mastodon! Amser darganfod pa duedd oeddech chi'n ei ymgorffori yn {year}.", + "annual_report.summary.archetype.title_public": "Tuedd {name}", + "annual_report.summary.archetype.title_self": "Eich tuedd", + "annual_report.summary.close": "Cau", + "annual_report.summary.copy_link": "Copïo dolen", + "annual_report.summary.followers.new_followers": "{count, plural, one {dilynwr newydd} other {dilynwr newydd}}", + "annual_report.summary.highlighted_post.boost_count": "Cafodd y postiad hwn hwb {count, plural, one {unwaith} other {# gwaith}}.", + "annual_report.summary.highlighted_post.favourite_count": "Cafodd y postiad hwn ei ffefrynnu {count, plural, one {unwaith} other {# gwaith}}.", + "annual_report.summary.highlighted_post.reply_count": "Cafodd y post hwn {count, plural, one {un ateb} other {# ateb}}.", + "annual_report.summary.highlighted_post.title": "Postiad mwyaf poblogaidd", "annual_report.summary.most_used_app.most_used_app": "ap a ddefnyddiwyd fwyaf", "annual_report.summary.most_used_hashtag.most_used_hashtag": "hashnod a ddefnyddiwyd fwyaf", - "annual_report.summary.most_used_hashtag.none": "Dim", + "annual_report.summary.most_used_hashtag.used_count": "Fe wnaethoch chi gynnwys yr hashnod hwn yn {count, plural, one {un postiad} other {# postiad}}.", + "annual_report.summary.most_used_hashtag.used_count_public": "Mae {name} wedi cynnwys yr hashnod hwn yn {count, plural, one {un postiad} other {# postiad}}.", "annual_report.summary.new_posts.new_posts": "postiadau newydd", "annual_report.summary.percentile.text": "Mae hynny'n eich rhoi chi ymysg yuchaf o ddefnyddwyr {domain}.", "annual_report.summary.percentile.we_wont_tell_bernie": "Fyddwn ni ddim yn dweud wrth Bernie.", - "annual_report.summary.thanks": "Diolch am fod yn rhan o Mastodon!", + "annual_report.summary.share_elsewhere": "Rhannu mewn mannau eraill", + "annual_report.summary.share_message": "Fy arddull i yw {archetype}!", + "annual_report.summary.share_on_mastodon": "Rhannwch ar Mastodon", "attachments_list.unprocessed": "(heb eu prosesu)", "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 rhwystrau mewn ffyrdd gwahanol. Mae'n bosibl y bydd postiadau cyhoeddus yn dal i fod yn weladwy i ddefnyddwyr nad ydynt wedi mewngofnodi.", @@ -516,6 +541,7 @@ "keyboard_shortcuts.toggle_hidden": "Dangos/cuddio testun tu ôl i CW", "keyboard_shortcuts.toggle_sensitivity": "Dangos/cuddio cyfryngau", "keyboard_shortcuts.toot": "Dechrau post newydd", + "keyboard_shortcuts.top": "Symud i frig y rhestr", "keyboard_shortcuts.translate": "i gyfieithu postiad", "keyboard_shortcuts.unfocus": "Dad-ffocysu ardal cyfansoddi testun/chwilio", "keyboard_shortcuts.up": "Symud yn uwch yn y rhestr", diff --git a/app/javascript/mastodon/locales/da.json b/app/javascript/mastodon/locales/da.json index eca4a8b6eb8329..f60719d0ed1b5c 100644 --- a/app/javascript/mastodon/locales/da.json +++ b/app/javascript/mastodon/locales/da.json @@ -114,29 +114,51 @@ "alt_text_modal.done": "Færdig", "announcement.announcement": "Bekendtgørelse", "annual_report.announcement.action_build": "Byg min Wrapstodon", + "annual_report.announcement.action_dismiss": "Nej tak", "annual_report.announcement.action_view": "Vis min Wrapstodon", "annual_report.announcement.description": "Få mere at vide om dit engagement på Mastodon i det forgangne år.", "annual_report.announcement.title": "Wrapstodon {year} er her", - "annual_report.summary.archetype.booster": "Fremhæveren", - "annual_report.summary.archetype.lurker": "Lureren", - "annual_report.summary.archetype.oracle": "Oraklet", - "annual_report.summary.archetype.pollster": "Afstemningsmageren", - "annual_report.summary.archetype.replier": "Den sociale sommerfugl", - "annual_report.summary.followers.followers": "følgere", - "annual_report.summary.followers.total": "{count} i alt", - "annual_report.summary.here_it_is": "Her er dit {year} i sammendrag:", - "annual_report.summary.highlighted_post.by_favourites": "mest favoritmarkerede indlæg", - "annual_report.summary.highlighted_post.by_reblogs": "mest fremhævede indlæg", - "annual_report.summary.highlighted_post.by_replies": "indlæg med flest svar", - "annual_report.summary.highlighted_post.possessive": "{name}s", + "annual_report.nav_item.badge": "Ny", + "annual_report.shared_page.donate": "Donér", + "annual_report.shared_page.footer": "Genereret med {heart} af Mastodon-teamet", + "annual_report.shared_page.footer_server_info": "{username} bruger {domain}, et af mange fællesskaber drevet af Mastodon.", + "annual_report.summary.archetype.booster.desc_public": "{name} fortsatte med at jagte indlæg, der kunne fremhæves, og styrkede andre skabere med perfekt sigte.", + "annual_report.summary.archetype.booster.desc_self": "Du fortsatte med at jagte indlæg, der kunne fremhæves, og styrkede andre skabere med perfekt sigte.", + "annual_report.summary.archetype.booster.name": "Bueskytten", + "annual_report.summary.archetype.die_drei_fragezeichen": "???", + "annual_report.summary.archetype.lurker.desc_public": "Vi ved, at {name} var derude et eller andet sted og nød Mastodon på sin egen stille måde.", + "annual_report.summary.archetype.lurker.desc_self": "Vi ved, at du var derude et eller andet sted og nød Mastodon på din egen stille måde.", + "annual_report.summary.archetype.lurker.name": "Den stoiske", + "annual_report.summary.archetype.oracle.desc_public": "{name} oprettede flere nye indlæg end svar og holdt dermed Mastodon frisk og fremtidsorienteret.", + "annual_report.summary.archetype.oracle.desc_self": "Du oprettede flere nye indlæg end svar og holdt dermed Mastodon frisk og fremtidsorienteret.", + "annual_report.summary.archetype.oracle.name": "Oraklet", + "annual_report.summary.archetype.pollster.desc_public": "{name} oprettede flere afstemninger end andre indlægstyper og opdyrkede nysgerrighed på Mastodon.", + "annual_report.summary.archetype.pollster.desc_self": "Du oprettede flere afstemninger end andre indlægstyper og opdyrkede nysgerrighed på Mastodon.", + "annual_report.summary.archetype.pollster.name": "Den undrende", + "annual_report.summary.archetype.replier.desc_public": "{name} svarede ofte på andres indlæg og berigede Mastodon med nye diskussioner.", + "annual_report.summary.archetype.replier.desc_self": "Du svarede ofte på andres indlæg og berigede Mastodon med nye diskussioner.", + "annual_report.summary.archetype.replier.name": "Sommerfuglen", + "annual_report.summary.archetype.reveal": "Afslør min arketype", + "annual_report.summary.archetype.reveal_description": "Tak fordi du er en del af Mastodon! Nu er det tid til at finde ud af, hvilken arketype du var i {year}.", + "annual_report.summary.archetype.title_public": "{name}'s arketype", + "annual_report.summary.archetype.title_self": "Din arketype", + "annual_report.summary.close": "Luk", + "annual_report.summary.copy_link": "Kopiér link", + "annual_report.summary.followers.new_followers": "{count, plural, one {ny følger} other {nye følgere}}", + "annual_report.summary.highlighted_post.boost_count": "Dette indlæg blev fremhævet {count, plural, one {én gang} other {# gange}}.", + "annual_report.summary.highlighted_post.favourite_count": "Dette indlæg blev favoritmarkeret {count, plural, one {én gang} other {# gange}}.", + "annual_report.summary.highlighted_post.reply_count": "Dette indlæg fik {count, plural, one {ét svar} other {# svar}}.", + "annual_report.summary.highlighted_post.title": "Mest populært indlæg", "annual_report.summary.most_used_app.most_used_app": "mest benyttede app", "annual_report.summary.most_used_hashtag.most_used_hashtag": "mest benyttede hashtag", - "annual_report.summary.most_used_hashtag.none": "Intet", + "annual_report.summary.most_used_hashtag.used_count": "Du har inkluderet dette hashtag i {count, plural, one {ét indlæg} other {# indlæg}}.", + "annual_report.summary.most_used_hashtag.used_count_public": "{name} inkluderede dette hashtag i {count, plural, one {ét indlæg} other {# indlæg}}.", "annual_report.summary.new_posts.new_posts": "nye indlæg", "annual_report.summary.percentile.text": "Dermed er du i topaf {domain}-brugere.", "annual_report.summary.percentile.we_wont_tell_bernie": "Vi fortæller det ikke til nogen.", + "annual_report.summary.share_elsewhere": "Del andetsteds", "annual_report.summary.share_message": "Min arketype er {archetype}!", - "annual_report.summary.thanks": "Tak for at være en del af Mastodon!", + "annual_report.summary.share_on_mastodon": "Del på Mastodon", "attachments_list.unprocessed": "(ubehandlet)", "audio.hide": "Skjul lyd", "block_modal.remote_users_caveat": "Serveren {domain} vil blive bedt om at respektere din beslutning. Overholdelse er dog ikke garanteret, da nogle servere kan håndtere blokke forskelligt. Offentlige indlæg kan stadig være synlige for ikke-indloggede brugere.", @@ -413,12 +435,14 @@ "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.popular_suggestion": "Populært forslag", - "follow_suggestions.popular_suggestion_longer": "Populært på {domain}", + "follow_suggestions.popular_suggestion_longer": "Populær på {domain}", "follow_suggestions.similar_to_recently_followed_longer": "Minder om profiler, du har fulgt for nylig", "follow_suggestions.view_all": "Vis alle", "follow_suggestions.who_to_follow": "Hvem, som skal følges", "followed_tags": "Hashtags, som følges", "footer.about": "Om", + "footer.about_mastodon": "Om Mastodon", + "footer.about_server": "Om {domain}", "footer.about_this_server": "Om", "footer.directory": "Profiloversigt", "footer.get_app": "Hent appen", diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json index d467dcf7c0f373..6db0567c811cce 100644 --- a/app/javascript/mastodon/locales/de.json +++ b/app/javascript/mastodon/locales/de.json @@ -57,7 +57,7 @@ "account.go_to_profile": "Profil aufrufen", "account.hide_reblogs": "Geteilte Beiträge von @{name} ausblenden", "account.in_memoriam": "Zum Andenken.", - "account.joined_short": "Mitglied seit", + "account.joined_short": "Registriert am", "account.languages": "Ausgewählte Sprachen ändern", "account.link_verified_on": "Das Profil mit dieser E-Mail-Adresse wurde bereits am {date} bestätigt", "account.locked_info": "Die Privatsphäre dieses Kontos wurde auf „geschützt“ gesetzt. Die Person bestimmt manuell, wer ihrem Profil folgen darf.", @@ -114,29 +114,51 @@ "alt_text_modal.done": "Fertig", "announcement.announcement": "Ankündigung", "annual_report.announcement.action_build": "Erstelle mein Wrapstodon", + "annual_report.announcement.action_dismiss": "Nein danke", "annual_report.announcement.action_view": "Mein Wrapstodon anschauen", "annual_report.announcement.description": "Erfahre mehr über deine Aktivitäten auf Mastodon im vergangenen Jahr.", "annual_report.announcement.title": "Wrapstodon {year} ist fertiggestellt", - "annual_report.summary.archetype.booster": "Trendjäger*in", - "annual_report.summary.archetype.lurker": "Beobachter*in", - "annual_report.summary.archetype.oracle": "Universaltalent", - "annual_report.summary.archetype.pollster": "Meinungsforscher*in", - "annual_report.summary.archetype.replier": "Gesellige*r", - "annual_report.summary.followers.followers": "Follower", - "annual_report.summary.followers.total": "{count} insgesamt", - "annual_report.summary.here_it_is": "Dein Jahresrückblick für {year}:", - "annual_report.summary.highlighted_post.by_favourites": "am häufigsten favorisierter Beitrag", - "annual_report.summary.highlighted_post.by_reblogs": "am häufigsten geteilter Beitrag", - "annual_report.summary.highlighted_post.by_replies": "Beitrag mit den meisten Antworten", - "annual_report.summary.highlighted_post.possessive": "{name}", + "annual_report.nav_item.badge": "Neu", + "annual_report.shared_page.donate": "Spenden", + "annual_report.shared_page.footer": "Mit {heart} vom Mastodon-Team erstellt", + "annual_report.shared_page.footer_server_info": "{username} verwendet {domain} – eine von vielen Mastodon-Gemeinschaften.", + "annual_report.summary.archetype.booster.desc_public": "{name} hielt Ausschau nach Beiträgen, um sie zu teilen und den Autor*innen mehr Reichweite zu bescheren.", + "annual_report.summary.archetype.booster.desc_self": "Du hieltest Ausschau nach Beiträgen, um sie zu teilen und den Autor*innen mehr Reichweite zu bescheren.", + "annual_report.summary.archetype.booster.name": "Flitzebogen", + "annual_report.summary.archetype.die_drei_fragezeichen": "???", + "annual_report.summary.archetype.lurker.desc_public": "{name} befand sich irgendwo in den Tiefen von Mastodon und genoss das stille Dasein.", + "annual_report.summary.archetype.lurker.desc_self": "Du befandest dich irgendwo in den Tiefen von Mastodon und genossest das stille Dasein.", + "annual_report.summary.archetype.lurker.name": "Unerschütterliche*r", + "annual_report.summary.archetype.oracle.desc_public": "{name} verfasste mehr Beiträge als Antworten, damit Mastodon abwechslungsreich blieb.", + "annual_report.summary.archetype.oracle.desc_self": "Du verfasstest mehr Beiträge als Antworten, damit Mastodon abwechslungsreich blieb.", + "annual_report.summary.archetype.oracle.name": "Orakel", + "annual_report.summary.archetype.pollster.desc_public": "{name} erstellte mehr Umfragen als alles andere und förderte die Neugier auf Mastodon.", + "annual_report.summary.archetype.pollster.desc_self": "Du erstelltest mehr Umfragen als alles andere und fördertest die Neugier auf Mastodon.", + "annual_report.summary.archetype.pollster.name": "Grübler*in", + "annual_report.summary.archetype.replier.desc_public": "{name} antwortete regelmäßig auf die Beiträge anderer und sorgte für blühende Diskussionen auf Mastodon.", + "annual_report.summary.archetype.replier.desc_self": "Du antwortetest regelmäßig auf die Beiträge anderer und sorgtest für blühende Diskussionen auf Mastodon.", + "annual_report.summary.archetype.replier.name": "Schmetterling", + "annual_report.summary.archetype.reveal": "Enthülle mein Wesen", + "annual_report.summary.archetype.reveal_description": "Danke, dass du Teil von Mastodon bist! Zeit herauszufinden, welches Wesen du {year} verkörpert hast.", + "annual_report.summary.archetype.title_public": "Wesen von {name}", + "annual_report.summary.archetype.title_self": "Mein Wesen", + "annual_report.summary.close": "Schließen", + "annual_report.summary.copy_link": "Link kopieren", + "annual_report.summary.followers.new_followers": "{count, plural, one {neuer Follower} other {neue Follower}}", + "annual_report.summary.highlighted_post.boost_count": "Dieser Beitrag wurde {count, plural, one {1 ×} other {# ×}} geteilt.", + "annual_report.summary.highlighted_post.favourite_count": "Dieser Beitrag wurde {count, plural, one {1 ×} other {# ×}} favorisiert.", + "annual_report.summary.highlighted_post.reply_count": "Dieser Beitrag erhielt {count, plural, one {1 Antwort} other {# Antworten}}.", + "annual_report.summary.highlighted_post.title": "Beliebtester Beitrag", "annual_report.summary.most_used_app.most_used_app": "am häufigsten verwendete App", "annual_report.summary.most_used_hashtag.most_used_hashtag": "am häufigsten verwendeter Hashtag", - "annual_report.summary.most_used_hashtag.none": "Keiner", + "annual_report.summary.most_used_hashtag.used_count": "Du verwendetest diesen Hashtag in {count, plural, one {1 Beitrag} other {# Beiträgen}}.", + "annual_report.summary.most_used_hashtag.used_count_public": "{name} verwendete diesen Hashtag in {count, plural, one {1 Beitrag} other {# Beiträgen}}.", "annual_report.summary.new_posts.new_posts": "neue Beiträge", "annual_report.summary.percentile.text": "Damit gehörst du zu den oberstender Nutzer*innen auf {domain}.", "annual_report.summary.percentile.we_wont_tell_bernie": "Wir werden Bernie nichts verraten.", - "annual_report.summary.share_message": "Ich habe den {archetype} Archetyp!", - "annual_report.summary.thanks": "Danke, dass du Teil von Mastodon bist!", + "annual_report.summary.share_elsewhere": "Woanders teilen", + "annual_report.summary.share_message": "Ich bin vom Wesen {archetype}!", + "annual_report.summary.share_on_mastodon": "Auf Mastodon teilen", "attachments_list.unprocessed": "(ausstehend)", "audio.hide": "Audio ausblenden", "block_modal.remote_users_caveat": "Wir werden den Server {domain} bitten, deine Entscheidung zu respektieren. Allerdings kann nicht garantiert werden, dass sie eingehalten wird, weil einige Server Blockierungen unterschiedlich handhaben können. Öffentliche Beiträge können für nicht angemeldete Nutzer*innen weiterhin sichtbar sein.", @@ -419,6 +441,8 @@ "follow_suggestions.who_to_follow": "Wem folgen?", "followed_tags": "Abonnierte Hashtags", "footer.about": "Über", + "footer.about_mastodon": "Über Mastodon", + "footer.about_server": "Über {domain}", "footer.about_this_server": "Über", "footer.directory": "Profilverzeichnis", "footer.get_app": "App herunterladen", @@ -937,7 +961,7 @@ "status.quote_error.pending_approval_popout.body": "Auf Mastodon kannst du selbst bestimmen, ob du von anderen zitiert werden darfst oder nicht – oder nur nach individueller Genehmigung. Wir warten in diesem Fall noch auf die Genehmigung des ursprünglichen Profils. Bis dahin steht die Veröffentlichung deines Beitrags mit dem zitierten Post noch aus.", "status.quote_error.revoked": "Beitrag durch Autor*in entfernt", "status.quote_followers_only": "Nur Follower können diesen Beitrag zitieren", - "status.quote_manual_review": "Zitierte*r überprüft manuell", + "status.quote_manual_review": "Autor*in wird deine Anfrage manuell überprüfen", "status.quote_noun": "Zitat", "status.quote_policy_change": "Ändern, wer zitieren darf", "status.quote_post_author": "Zitierter Beitrag von @{name}", @@ -955,7 +979,7 @@ "status.reblogs_count": "{count, plural, one {{counter} × geteilt} other {{counter} × geteilt}}", "status.redraft": "Löschen und neu erstellen", "status.remove_bookmark": "Lesezeichen entfernen", - "status.remove_favourite": "Aus Favoriten entfernen", + "status.remove_favourite": "Favorisierung entfernen", "status.remove_quote": "Entfernen", "status.replied_in_thread": "Antwortete im Thread", "status.replied_to": "Antwortete {name}", @@ -972,7 +996,7 @@ "status.title.with_attachments": "{user} veröffentlichte {attachmentCount, plural, one {ein Medium} other {{attachmentCount} Medien}}", "status.translate": "Übersetzen", "status.translated_from_with": "Aus {lang} mittels {provider} übersetzt", - "status.uncached_media_warning": "Vorschau nicht verfügbar", + "status.uncached_media_warning": "Vorschau noch nicht verfügbar", "status.unmute_conversation": "Stummschaltung der Unterhaltung aufheben", "status.unpin": "Vom Profil lösen", "subscribed_languages.lead": "Nach der Änderung werden nur noch Beiträge in den ausgewählten Sprachen in den Timelines deiner Startseite und deiner Listen angezeigt. Wähle keine Sprache aus, um alle Beiträge zu sehen.", @@ -1008,7 +1032,7 @@ "upload_form.drag_and_drop.on_drag_over": "Der Medienanhang {item} wurde bewegt.", "upload_form.drag_and_drop.on_drag_start": "Der Medienanhang {item} wurde aufgenommen.", "upload_form.edit": "Bearbeiten", - "upload_progress.label": "Wird hochgeladen …", + "upload_progress.label": "Upload läuft …", "upload_progress.processing": "Wird verarbeitet …", "username.taken": "Dieser Profilname ist vergeben. Versuche einen anderen", "video.close": "Video schließen", diff --git a/app/javascript/mastodon/locales/el.json b/app/javascript/mastodon/locales/el.json index 48aad8c926d90b..1e07e97b5152a2 100644 --- a/app/javascript/mastodon/locales/el.json +++ b/app/javascript/mastodon/locales/el.json @@ -47,12 +47,12 @@ "account.follow_request_cancel_short": "Ακύρωση", "account.follow_request_short": "Αίτημα", "account.followers": "Ακόλουθοι", - "account.followers.empty": "Κανείς δεν ακολουθεί αυτόν τον χρήστη ακόμα.", + "account.followers.empty": "Κανείς δεν ακολουθεί αυτόν τον χρήστη ακόμη.", "account.followers_counter": "{count, plural, one {{counter} ακόλουθος} other {{counter} ακόλουθοι}}", "account.followers_you_know_counter": "{counter} που ξέρεις", "account.following": "Ακολουθείτε", "account.following_counter": "{count, plural, one {{counter} ακολουθεί} other {{counter} ακολουθούν}}", - "account.follows.empty": "Αυτός ο χρήστης δεν ακολουθεί κανέναν ακόμα.", + "account.follows.empty": "Αυτός ο χρήστης δεν ακολουθεί κανέναν ακόμη.", "account.follows_you": "Σε ακολουθεί", "account.go_to_profile": "Μετάβαση στο προφίλ", "account.hide_reblogs": "Απόκρυψη ενισχύσεων από @{name}", @@ -114,29 +114,51 @@ "alt_text_modal.done": "Ολοκληρώθηκε", "announcement.announcement": "Ανακοίνωση", "annual_report.announcement.action_build": "Φτιάξε το Wrapstodon μου", + "annual_report.announcement.action_dismiss": "Όχι, ευχαριστώ", "annual_report.announcement.action_view": "Προβολή του Wrapstodon μου", "annual_report.announcement.description": "Ανακαλύψτε περισσότερα για την αλληλεπίδραση σας στο Mastodon κατά τη διάρκεια του περασμένου έτους.", "annual_report.announcement.title": "Το Wrapstodon του {year} έφτασε", - "annual_report.summary.archetype.booster": "Ο κυνηγός των φοβερών", - "annual_report.summary.archetype.lurker": "Ο διακριτικός", - "annual_report.summary.archetype.oracle": "Η Πυθία", - "annual_report.summary.archetype.pollster": "Ο δημοσκόπος", - "annual_report.summary.archetype.replier": "Η κοινωνική πεταλούδα", - "annual_report.summary.followers.followers": "ακόλουθοι", - "annual_report.summary.followers.total": "{count} συνολικά", - "annual_report.summary.here_it_is": "Εδώ είναι το {year} σου σε ανασκόπηση:", - "annual_report.summary.highlighted_post.by_favourites": "πιο αγαπημένη ανάρτηση", - "annual_report.summary.highlighted_post.by_reblogs": "πιο ενισχυμένη ανάρτηση", - "annual_report.summary.highlighted_post.by_replies": "ανάρτηση με τις περισσότερες απαντήσεις", - "annual_report.summary.highlighted_post.possessive": "του χρήστη {name}", + "annual_report.nav_item.badge": "Νέο", + "annual_report.shared_page.donate": "Δωρεά", + "annual_report.shared_page.footer": "Παράχθηκε με {heart} από την ομάδα του Mastodon", + "annual_report.shared_page.footer_server_info": "Ο/Η {username} χρησιμοποιεί το {domain}, μία από τις πολλές κοινότητες που βασίζονται στο Mastodon.", + "annual_report.summary.archetype.booster.desc_public": "Ο/Η {name} έμεινε στο κυνήγι για αναρτήσεις για να τις ενισχύσει, ενισχύοντας άλλους δημιουργούς με τέλειο στόχο.", + "annual_report.summary.archetype.booster.desc_self": "Έμεινες στο κυνήγι για αναρτήσεις για να τις ενισχύσεις, ενισχύοντας άλλους δημιουργούς με τέλειο στόχο.", + "annual_report.summary.archetype.booster.name": "Ο Τοξότης", + "annual_report.summary.archetype.die_drei_fragezeichen": "???", + "annual_report.summary.archetype.lurker.desc_public": "Ξέρουμε ότι ο/η {name} ήταν εκεί έξω, κάπου, απολαμβάνοντας το Mastodon με τον δικό του/της ήσυχο τρόπο.", + "annual_report.summary.archetype.lurker.desc_self": "Ξέρουμε ότι ήσουν εκεί έξω, κάπου, απολαμβάνοντας το Mastodon με τον δικό σου ήσυχο τρόπο.", + "annual_report.summary.archetype.lurker.name": "Ο Στωϊκός", + "annual_report.summary.archetype.oracle.desc_public": "O/H {name} δημιούργησε νέες αναρτήσεις περισσότερο από ότι απαντήσεις, κρατώντας το Mastodon φρέσκο και κοιτώντας προς το μέλλον.", + "annual_report.summary.archetype.oracle.desc_self": "Δημιούργησες νέες αναρτήσεις περισσότερο από ότι απαντήσεις, κρατώντας το Mastodon φρέσκο και κοιτώντας προς το μέλλον.", + "annual_report.summary.archetype.oracle.name": "Η Πυθία", + "annual_report.summary.archetype.pollster.desc_public": "Ο/Η {name} δημιούργησε περισσότερες δημοσκοπήσεις από άλλα είδη αναρτήσεων, καλλιεργώντας περιέργεια στο Mastodon.", + "annual_report.summary.archetype.pollster.desc_self": "Δημιούργησες περισσότερες δημοσκοπήσεις από άλλα είδη αναρτήσεων, καλλιεργώντας περιέργεια στο Mastodon.", + "annual_report.summary.archetype.pollster.name": "Ο Θαυμαστής", + "annual_report.summary.archetype.replier.desc_public": "Ο/Η {name} συχνά απαντούσε σε αναρτήσεις άλλων ανθρώπων, επικονίαζοντας το Mastodon με νέες συζητήσεις.", + "annual_report.summary.archetype.replier.desc_self": "Συχνά απαντούσες σε αναρτήσεις άλλων ανθρώπων, επικονίαζοντας το Mastodon με νέες συζητήσεις.", + "annual_report.summary.archetype.replier.name": "Η Πεταλούδα", + "annual_report.summary.archetype.reveal": "Αποκάλυψε το αρχέτυπο μου", + "annual_report.summary.archetype.reveal_description": "Ευχαριστούμε που είσαι μέρος του Mastodon! Ώρα να μάθεις ποιο αρχέτυπο έχεις ενσαρκώσει το {year}.", + "annual_report.summary.archetype.title_public": "Αρχέτυπο του/της {name}", + "annual_report.summary.archetype.title_self": "Το αρχέτυπο σου", + "annual_report.summary.close": "Κλείσιμο", + "annual_report.summary.copy_link": "Αντιγραφή συνδέσμου", + "annual_report.summary.followers.new_followers": "{count, plural, one {νέος ακόλουθος} other {νέοι ακόλουθοι}}", + "annual_report.summary.highlighted_post.boost_count": "Αυτή η ανάρτηση ενισχύθηκε {count, plural, one {μια φορά} other {# φορές}}.", + "annual_report.summary.highlighted_post.favourite_count": "Αυτή η ανάρτηση αγαπήθηκε {count, plural, one {μια φορά} other {# φορές}}.", + "annual_report.summary.highlighted_post.reply_count": "Αυτή η ανάρτηση πήρε {count, plural, one {μια απάντηση} other {# απαντήσεις}}.", + "annual_report.summary.highlighted_post.title": "Πιο δημοφιλής ανάρτηση", "annual_report.summary.most_used_app.most_used_app": "πιο χρησιμοποιημένη εφαρμογή", "annual_report.summary.most_used_hashtag.most_used_hashtag": "πιο χρησιμοποιημένη ετικέτα", - "annual_report.summary.most_used_hashtag.none": "Κανένα", + "annual_report.summary.most_used_hashtag.used_count": "Έχεις συμπεριλάβει αυτήν την ετικέτα σε {count, plural, one {μια ανάρτηση} other {# αναρτήσεις}}.", + "annual_report.summary.most_used_hashtag.used_count_public": "Ο/Η {name} έχει συμπεριλάβει αυτήν την ετικέτα σε {count, plural, one {μια ανάρτηση} other {# αναρτήσεις}}.", "annual_report.summary.new_posts.new_posts": "νέες αναρτήσεις", "annual_report.summary.percentile.text": "Αυτό σε βάζει στο των κορυφαίων χρηστών του {domain}.", "annual_report.summary.percentile.we_wont_tell_bernie": "Δεν θα το πούμε στον Bernie.", + "annual_report.summary.share_elsewhere": "Κοινοποίηση αλλού", "annual_report.summary.share_message": "Πήρα το αρχέτυπο {archetype}!", - "annual_report.summary.thanks": "Ευχαριστούμε που συμμετέχεις στο Mastodon!", + "annual_report.summary.share_on_mastodon": "Κοινοποίηση στο Mastodon", "attachments_list.unprocessed": "(μη επεξεργασμένο)", "audio.hide": "Απόκρυψη αρχείου ήχου", "block_modal.remote_users_caveat": "Θα ζητήσουμε από τον διακομιστή {domain} να σεβαστεί την απόφασή σου. Ωστόσο, η συμμόρφωση δεν είναι εγγυημένη δεδομένου ότι ορισμένοι διακομιστές ενδέχεται να χειρίζονται τους αποκλεισμούς διαφορετικά. Οι δημόσιες αναρτήσεις ενδέχεται να είναι ορατές σε μη συνδεδεμένους χρήστες.", @@ -337,30 +359,30 @@ "emoji_button.search_results": "Αποτελέσματα αναζήτησης", "emoji_button.symbols": "Σύμβολα", "emoji_button.travel": "Ταξίδια & Τοποθεσίες", - "empty_column.account_featured.me": "Δεν έχεις αναδείξει τίποτα ακόμα. Γνώριζες ότι μπορείς να αναδείξεις τις ετικέτες που χρησιμοποιείς περισσότερο, ακόμη και τους λογαριασμούς των φίλων σου στο προφίλ σου;", - "empty_column.account_featured.other": "Ο λογαριασμός {acct} δεν αναδείξει τίποτα ακόμα. Γνώριζες ότι μπορείς να αναδείξεις τις ετικέτες που χρησιμοποιείς περισσότερο, ακόμη και τους λογαριασμούς των φίλων σου στο προφίλ σου;", - "empty_column.account_featured_other.unknown": "Αυτός ο λογαριασμός δεν έχει αναδείξει τίποτα ακόμα.", + "empty_column.account_featured.me": "Δεν έχεις αναδείξει τίποτα ακόμη. Γνώριζες ότι μπορείς να αναδείξεις τις ετικέτες που χρησιμοποιείς περισσότερο, ακόμη και τους λογαριασμούς των φίλων σου στο προφίλ σου;", + "empty_column.account_featured.other": "Ο/Η {acct} δεν έχει αναδείξει τίποτα ακόμη. Γνώριζες ότι μπορείς να αναδείξεις τις ετικέτες που χρησιμοποιείς περισσότερο, ακόμη και τους λογαριασμούς των φίλων σου στο προφίλ σου;", + "empty_column.account_featured_other.unknown": "Αυτός ο λογαριασμός δεν έχει αναδείξει τίποτα ακόμη.", "empty_column.account_hides_collections": "Αυτός ο χρήστης έχει επιλέξει να μην καταστήσει αυτές τις πληροφορίες διαθέσιμες", "empty_column.account_suspended": "Λογαριασμός σε αναστολή", "empty_column.account_timeline": "Δεν έχει αναρτήσεις εδώ!", "empty_column.account_unavailable": "Μη διαθέσιμο προφίλ", - "empty_column.blocks": "Δεν έχεις αποκλείσει κανέναν χρήστη ακόμα.", - "empty_column.bookmarked_statuses": "Δεν έχεις καμία ανάρτηση με σελιδοδείκτη ακόμα. Μόλις βάλεις κάποιον, θα εμφανιστεί εδώ.", + "empty_column.blocks": "Δεν έχεις αποκλείσει κανέναν χρήστη ακόμη.", + "empty_column.bookmarked_statuses": "Δεν έχεις καμία ανάρτηση με σελιδοδείκτη ακόμη. Μόλις βάλεις κάποιον, θα εμφανιστεί εδώ.", "empty_column.community": "Η τοπική ροή είναι κενή. Γράψε κάτι δημόσια για να αρχίσει να κυλά η μπάλα!", - "empty_column.direct": "Δεν έχεις καμία προσωπική επισήμανση ακόμα. Όταν στείλεις ή λάβεις μία, θα εμφανιστεί εδώ.", + "empty_column.direct": "Δεν έχεις καμία προσωπική επισήμανση ακόμη. Όταν στείλεις ή λάβεις μία, θα εμφανιστεί εδώ.", "empty_column.disabled_feed": "Αυτή η ροή έχει απενεργοποιηθεί από τους διαχειριστές του διακομιστή σας.", - "empty_column.domain_blocks": "Δεν υπάρχουν αποκλεισμένοι τομείς ακόμα.", + "empty_column.domain_blocks": "Δεν υπάρχουν αποκλεισμένοι τομείς ακόμη.", "empty_column.explore_statuses": "Τίποτα δεν βρίσκεται στις τάσεις αυτή τη στιγμή. Έλεγξε αργότερα!", - "empty_column.favourited_statuses": "Δεν έχεις καμία αγαπημένη ανάρτηση ακόμα. Μόλις αγαπήσεις κάποια, θα εμφανιστεί εδώ.", - "empty_column.favourites": "Κανείς δεν έχει αγαπήσει αυτή την ανάρτηση ακόμα. Μόλις το κάνει κάποιος, θα εμφανιστεί εδώ.", - "empty_column.follow_requests": "Δεν έχεις κανένα αίτημα παρακολούθησης ακόμα. Μόλις λάβεις κάποιο, θα εμφανιστεί εδώ.", - "empty_column.followed_tags": "Δεν έχετε ακολουθήσει ακόμα καμία ετικέτα. Όταν το κάνετε, θα εμφανιστούν εδώ.", - "empty_column.hashtag": "Δεν υπάρχει ακόμα κάτι για αυτή την ετικέτα.", + "empty_column.favourited_statuses": "Δεν έχεις καμία αγαπημένη ανάρτηση ακόμη. Μόλις αγαπήσεις κάποια, θα εμφανιστεί εδώ.", + "empty_column.favourites": "Κανείς δεν έχει αγαπήσει αυτή την ανάρτηση ακόμη. Μόλις το κάνει κάποιος, θα εμφανιστεί εδώ.", + "empty_column.follow_requests": "Δεν έχεις κανένα αίτημα παρακολούθησης ακόμη. Μόλις λάβεις κάποιο, θα εμφανιστεί εδώ.", + "empty_column.followed_tags": "Δεν έχεις ακολουθήσει καμία ετικέτα ακόμη. Όταν το κάνεις, θα εμφανιστούν εδώ.", + "empty_column.hashtag": "Δεν υπάρχει τίποτα σε αυτή την ετικέτα ακόμη.", "empty_column.home": "Η τοπική σου ροή είναι κενή! Πήγαινε στο {public} ή κάνε αναζήτηση για να ξεκινήσεις και να γνωρίσεις άλλους χρήστες.", - "empty_column.list": "Δεν υπάρχει τίποτα σε αυτή τη λίστα ακόμα. Όταν τα μέλη της δημοσιεύσουν νέες καταστάσεις, θα εμφανιστούν εδώ.", - "empty_column.mutes": "Δεν έχεις κανένα χρήστη σε σίγαση ακόμα.", + "empty_column.list": "Δεν υπάρχει τίποτα σε αυτή τη λίστα ακόμη. Όταν τα μέλη της δημοσιεύσουν νέες αναρτήσεις, θα εμφανιστούν εδώ.", + "empty_column.mutes": "Δεν έχεις κανένα χρήστη σε σίγαση ακόμη.", "empty_column.notification_requests": "Όλα καθαρά! Δεν υπάρχει τίποτα εδώ. Όταν λαμβάνεις νέες ειδοποιήσεις, αυτές θα εμφανίζονται εδώ σύμφωνα με τις ρυθμίσεις σου.", - "empty_column.notifications": "Δεν έχεις ειδοποιήσεις ακόμα. Όταν άλλα άτομα αλληλεπιδράσουν μαζί σου, θα το δεις εδώ.", + "empty_column.notifications": "Δεν έχεις ειδοποιήσεις ακόμη. Όταν άλλα άτομα αλληλεπιδράσουν μαζί σου, θα το δεις εδώ.", "empty_column.public": "Δεν υπάρχει τίποτα εδώ! Γράψε κάτι δημόσιο ή ακολούθησε χειροκίνητα χρήστες από άλλους διακομιστές για να τη γεμίσεις", "error.no_hashtag_feed_access": "Γίνετε μέλος ή συνδεθείτε για να δείτε και να ακολουθήσετε αυτήν την ετικέτα.", "error.unexpected_crash.explanation": "Είτε λόγω σφάλματος στον κώδικά μας ή λόγω ασυμβατότητας με τον περιηγητή, η σελίδα δε μπόρεσε να εμφανιστεί σωστά.", @@ -419,6 +441,8 @@ "follow_suggestions.who_to_follow": "Ποιον να ακολουθήσεις", "followed_tags": "Ακολουθούμενες ετικέτες", "footer.about": "Σχετικά με", + "footer.about_mastodon": "Σχετικά με το Mastodon", + "footer.about_server": "Σχετικά με το {domain}", "footer.about_this_server": "Σχετικά με", "footer.directory": "Κατάλογος προφίλ", "footer.get_app": "Αποκτήστε την εφαρμογή", @@ -449,7 +473,7 @@ "hashtag.mute": "Σίγαση #{hashtag}", "hashtag.unfeature": "Να μην αναδεικνύεται στο προφίλ", "hashtag.unfollow": "Διακοπή παρακολούθησης ετικέτας", - "hashtags.and_other": "…και {count, plural, other {# ακόμη}}", + "hashtags.and_other": "…και {count, plural, other {# ακόμα}}", "hints.profiles.followers_may_be_missing": "Μπορεί να λείπουν ακόλουθοι για αυτό το προφίλ.", "hints.profiles.follows_may_be_missing": "Άτομα που ακολουθούνται μπορεί να λείπουν απ' αυτό το προφίλ.", "hints.profiles.posts_may_be_missing": "Κάποιες αναρτήσεις από αυτό το προφίλ μπορεί να λείπουν.", @@ -466,7 +490,7 @@ "home.show_announcements": "Εμφάνιση ανακοινώσεων", "ignore_notifications_modal.disclaimer": "Το Mastodon δε μπορεί να ενημερώσει τους χρήστες ότι αγνόησες τις ειδοποιήσεις του. Η αγνόηση ειδοποιήσεων δεν θα εμποδίσει την αποστολή των ίδιων των μηνυμάτων.", "ignore_notifications_modal.filter_instead": "Φίλτρο αντ' αυτού", - "ignore_notifications_modal.filter_to_act_users": "Θα μπορείς ακόμα να αποδεχθείς, να απορρίψεις ή να αναφέρεις χρήστες", + "ignore_notifications_modal.filter_to_act_users": "Θα μπορείς ακόμη να αποδεχθείς, να απορρίψεις ή να αναφέρεις χρήστες", "ignore_notifications_modal.filter_to_avoid_confusion": "Το φιλτράρισμα βοηθά στην αποφυγή πιθανής σύγχυσης", "ignore_notifications_modal.filter_to_review_separately": "Μπορείς να δεις τις φιλτραρισμένες ειδοποιήσεις ξεχωριστά", "ignore_notifications_modal.ignore": "Αγνόηση ειδοποιήσεων", @@ -552,8 +576,8 @@ "lists.list_members_count": "{count, plural, one {# μέλος} other {# μέλη}}", "lists.list_name": "Όνομα λίστας", "lists.new_list_name": "Νέο όνομα λίστας", - "lists.no_lists_yet": "Δεν υπάρχουν λίστες ακόμα.", - "lists.no_members_yet": "Κανένα μέλος ακόμα.", + "lists.no_lists_yet": "Καμία λίστα ακόμη.", + "lists.no_members_yet": "Κανένα μέλος ακόμη.", "lists.no_results_found": "Δεν βρέθηκαν αποτελέσματα.", "lists.remove_member": "Αφαίρεση", "lists.replies_policy.followed": "Οποιοσδήποτε χρήστης που ακολουθείς", @@ -613,15 +637,15 @@ "notification.admin.report_statuses": "Ο χρήστης {name} ανέφερε τον χρήστη {target} για {category}", "notification.admin.report_statuses_other": "Ο χρήστης {name} ανέφερε τον χρήστη {target}", "notification.admin.sign_up": "{name} έχει εγγραφεί", - "notification.admin.sign_up.name_and_others": "{name} και {count, plural, one {# ακόμη} other {# ακόμη}} έχουν εγγραφεί", + "notification.admin.sign_up.name_and_others": "{name} και {count, plural, one {# ακόμα} other {# ακόμα}} έχουν εγγραφεί", "notification.annual_report.message": "Το #Wrapstodon {year} σε περιμένει! Αποκάλυψε τα στιγμιότυπα της χρονιάς και αξέχαστες στιγμές σου στο Mastodon!", "notification.annual_report.view": "Προβολή #Wrapstodon", "notification.favourite": "{name} αγάπησε την ανάρτηση σου", - "notification.favourite.name_and_others_with_link": "{name} και {count, plural, one {# ακόμη} other {# ακόμη}} αγάπησαν την ανάρτησή σου", + "notification.favourite.name_and_others_with_link": "{name} και {count, plural, one {# ακόμα} other {# ακόμα}} αγάπησαν την ανάρτησή σου", "notification.favourite_pm": "Ο χρήστης {name} αγάπησε την ιδιωτική σου επισήμανση", - "notification.favourite_pm.name_and_others_with_link": "Ο χρήστης {name} και {count, plural, one {# ακόμη} other {# ακόμη}} αγάπησαν την ιδωτική σου επισήμανση", + "notification.favourite_pm.name_and_others_with_link": "Ο χρήστης {name} και {count, plural, one {# ακόμα} other {# ακόμα}} αγάπησαν την ιδωτική σου επισήμανση", "notification.follow": "Ο χρήστης {name} σε ακολούθησε", - "notification.follow.name_and_others": "Ο χρήστης {name} και {count, plural, one {# ακόμη} other {# ακόμη}} σε ακολούθησαν", + "notification.follow.name_and_others": "Ο χρήστης {name} και {count, plural, one {# ακόμα} other {# ακόμα}} σε ακολούθησαν", "notification.follow_request": "Ο/H {name} ζήτησε να σε ακολουθήσει", "notification.follow_request.name_and_others": "{name} και {count, plural, one {# άλλος} other {# άλλοι}} ζήτησαν να σε ακολουθήσουν", "notification.label.mention": "Επισήμανση", @@ -644,7 +668,7 @@ "notification.poll": "Μία ψηφοφορία στην οποία συμμετείχες έχει τελειώσει", "notification.quoted_update": "Ο χρήστης {name} επεξεργάστηκε μία ανάρτηση που παρέθεσες", "notification.reblog": "Ο/Η {name} ενίσχυσε την ανάρτηση σου", - "notification.reblog.name_and_others_with_link": "{name} και {count, plural, one {# ακόμη} other {# ακόμη}} ενίσχυσαν την ανάρτησή σου", + "notification.reblog.name_and_others_with_link": "{name} και {count, plural, one {# ακόμα} other {# ακόμα}} ενίσχυσαν την ανάρτησή σου", "notification.relationships_severance_event": "Χάθηκε η σύνδεση με το {name}", "notification.relationships_severance_event.account_suspension": "Ένας διαχειριστής από το {from} ανέστειλε το {target}, πράγμα που σημαίνει ότι δεν μπορείς πλέον να λαμβάνεις ενημερώσεις από αυτούς ή να αλληλεπιδράς μαζί τους.", "notification.relationships_severance_event.domain_block": "Ένας διαχειριστής από {from} έχει μπλοκάρει το {target}, συμπεριλαμβανομένων {followersCount} από τους ακόλουθούς σου και {followingCount, plural, one {# λογαριασμό} other {# λογαριασμοί}} που ακολουθείς.", @@ -812,7 +836,7 @@ "report.forward": "Προώθηση προς {target}", "report.forward_hint": "Ο λογαριασμός είναι από διαφορετικό διακομιστή. Να σταλεί ανώνυμο αντίγραφο της αναφοράς και εκεί;", "report.mute": "Σίγαση", - "report.mute_explanation": "Δεν θα βλέπεις τις αναρτήσεις του. Εκείνοι μπορούν ακόμα να σε ακολουθούν και να βλέπουν τις αναρτήσεις σου χωρίς να γνωρίζουν ότι είναι σε σίγαση.", + "report.mute_explanation": "Δεν θα βλέπεις τις αναρτήσεις τους. Εκείνοι μπορούν ακόμη να σε ακολουθούν και να βλέπουν τις αναρτήσεις σου χωρίς να γνωρίζουν ότι είναι σε σίγαση.", "report.next": "Επόμενο", "report.placeholder": "Επιπλέον σχόλια", "report.reasons.dislike": "Δεν μου αρέσει", @@ -942,7 +966,7 @@ "status.quote_policy_change": "Αλλάξτε ποιός μπορεί να κάνει παράθεση", "status.quote_post_author": "Παρατίθεται μια ανάρτηση από @{name}", "status.quote_private": "Ιδιωτικές αναρτήσεις δεν μπορούν να παρατεθούν", - "status.quotes.empty": "Κανείς δεν έχει παραθέσει αυτή την ανάρτηση ακόμα. Μόλις το κάνει, θα εμφανιστεί εδώ.", + "status.quotes.empty": "Κανείς δεν έχει παραθέσει αυτή την ανάρτηση ακόμη. Μόλις το κάνει, θα εμφανιστεί εδώ.", "status.quotes.local_other_disclaimer": "Οι παραθέσεις που απορρίφθηκαν από τον συντάκτη δε θα εμφανιστούν.", "status.quotes.remote_other_disclaimer": "Μόνο παραθέσεις από το {domain} είναι εγγυημένες ότι θα εμφανιστούν εδώ. Παραθέσεις που απορρίφθηκαν από τον συντάκτη δε θα εμφανιστούν.", "status.quotes_count": "{count, plural, one {{counter} παράθεση} other {{counter} παραθέσεις}}", @@ -951,7 +975,7 @@ "status.reblog_or_quote": "Ενίσχυση ή παράθεση", "status.reblog_private": "Μοιράσου ξανά με τους ακόλουθούς σου", "status.reblogged_by": "{name} προώθησε", - "status.reblogs.empty": "Κανείς δεν ενίσχυσε αυτή την ανάρτηση ακόμα. Μόλις το κάνει κάποιος, θα εμφανιστεί εδώ.", + "status.reblogs.empty": "Κανείς δεν ενίσχυσε αυτή την ανάρτηση ακόμη. Μόλις το κάνει κάποιος, θα εμφανιστεί εδώ.", "status.reblogs_count": "{count, plural, one {{counter} ενίσχυση} other {{counter} ενισχύσεις}}", "status.redraft": "Σβήσε & ξαναγράψε", "status.remove_bookmark": "Αφαίρεση σελιδοδείκτη", diff --git a/app/javascript/mastodon/locales/en-GB.json b/app/javascript/mastodon/locales/en-GB.json index d49b7d36297c19..9b4a79d32cc5e5 100644 --- a/app/javascript/mastodon/locales/en-GB.json +++ b/app/javascript/mastodon/locales/en-GB.json @@ -114,29 +114,51 @@ "alt_text_modal.done": "Done", "announcement.announcement": "Announcement", "annual_report.announcement.action_build": "Build my Wrapstodon", + "annual_report.announcement.action_dismiss": "No thanks", "annual_report.announcement.action_view": "View my Wrapstodon", "annual_report.announcement.description": "Discover more about your engagement on Mastodon over the past year.", "annual_report.announcement.title": "Wrapstodon {year} has arrived", - "annual_report.summary.archetype.booster": "The cool-hunter", - "annual_report.summary.archetype.lurker": "The lurker", - "annual_report.summary.archetype.oracle": "The oracle", - "annual_report.summary.archetype.pollster": "The pollster", - "annual_report.summary.archetype.replier": "The social butterfly", - "annual_report.summary.followers.followers": "followers", - "annual_report.summary.followers.total": "{count} total", - "annual_report.summary.here_it_is": "Here is your {year} in review:", - "annual_report.summary.highlighted_post.by_favourites": "most favourited post", - "annual_report.summary.highlighted_post.by_reblogs": "most boosted post", - "annual_report.summary.highlighted_post.by_replies": "post with the most replies", - "annual_report.summary.highlighted_post.possessive": "{name}'s", + "annual_report.nav_item.badge": "New", + "annual_report.shared_page.donate": "Donate", + "annual_report.shared_page.footer": "Generated with {heart} by the Mastodon team", + "annual_report.shared_page.footer_server_info": "{username} uses {domain}, one of many communities powered by Mastodon.", + "annual_report.summary.archetype.booster.desc_public": "{name} stayed on the hunt for posts to boost, amplifying other creators with perfect aim.", + "annual_report.summary.archetype.booster.desc_self": "You stayed on the hunt for posts to boost, amplifying other creators with perfect aim.", + "annual_report.summary.archetype.booster.name": "The Archer", + "annual_report.summary.archetype.die_drei_fragezeichen": "???", + "annual_report.summary.archetype.lurker.desc_public": "We know {name} was out there, somewhere, enjoying Mastodon in their own quiet way.", + "annual_report.summary.archetype.lurker.desc_self": "We know you were out there, somewhere, enjoying Mastodon in your own quiet way.", + "annual_report.summary.archetype.lurker.name": "The Stoic", + "annual_report.summary.archetype.oracle.desc_public": "{name} created new posts more than replies, keeping Mastodon fresh and future-facing.", + "annual_report.summary.archetype.oracle.desc_self": "You created new posts more than replies, keeping Mastodon fresh and future-facing.", + "annual_report.summary.archetype.oracle.name": "The Oracle", + "annual_report.summary.archetype.pollster.desc_public": "{name} created more polls than other post types, cultivating curiosity on Mastodon.", + "annual_report.summary.archetype.pollster.desc_self": "You created more polls than other post types, cultivating curiosity on Mastodon.", + "annual_report.summary.archetype.pollster.name": "The Wonderer", + "annual_report.summary.archetype.replier.desc_public": "{name} frequently replied to other people’s posts, pollinating Mastodon with new discussions.", + "annual_report.summary.archetype.replier.desc_self": "You frequently replied to other people’s posts, pollinating Mastodon with new discussions.", + "annual_report.summary.archetype.replier.name": "The Butterfly", + "annual_report.summary.archetype.reveal": "Reveal my archetype", + "annual_report.summary.archetype.reveal_description": "Thanks for being part of Mastodon! Time to find out which archetype you embodied in {year}.", + "annual_report.summary.archetype.title_public": "{name}'s archetype", + "annual_report.summary.archetype.title_self": "Your archetype", + "annual_report.summary.close": "Close", + "annual_report.summary.copy_link": "Copy link", + "annual_report.summary.followers.new_followers": "{count, plural, one {new follower} other {new followers}}", + "annual_report.summary.highlighted_post.boost_count": "This post was boosted {count, plural, one {once} other {# times}}.", + "annual_report.summary.highlighted_post.favourite_count": "This post was favourited {count, plural, one {once} other {# times}}.", + "annual_report.summary.highlighted_post.reply_count": "This post got {count, plural, one {one reply} other {# replies}}.", + "annual_report.summary.highlighted_post.title": "Most popular post", "annual_report.summary.most_used_app.most_used_app": "most used app", "annual_report.summary.most_used_hashtag.most_used_hashtag": "most used hashtag", - "annual_report.summary.most_used_hashtag.none": "None", + "annual_report.summary.most_used_hashtag.used_count": "You included this hashtag in {count, plural, one {one post} other {# posts}}.", + "annual_report.summary.most_used_hashtag.used_count_public": "{name} included this hashtag in {count, plural, one {one post} other {# posts}}.", "annual_report.summary.new_posts.new_posts": "new posts", "annual_report.summary.percentile.text": "That puts you in the topof {domain} users.", "annual_report.summary.percentile.we_wont_tell_bernie": "We won't tell Bernie.", + "annual_report.summary.share_elsewhere": "Share elsewhere", "annual_report.summary.share_message": "I got the {archetype} archetype!", - "annual_report.summary.thanks": "Thanks for being part of Mastodon!", + "annual_report.summary.share_on_mastodon": "Share on Mastodon", "attachments_list.unprocessed": "(unprocessed)", "audio.hide": "Hide audio", "block_modal.remote_users_caveat": "We will ask the server {domain} to respect your decision. However, compliance is not guaranteed since some servers may handle blocks differently. Public posts may still be visible to non-logged-in users.", @@ -265,7 +287,7 @@ "confirmations.quiet_post_quote_info.title": "Quoting quiet public posts", "confirmations.redraft.confirm": "Delete & redraft", "confirmations.redraft.message": "Are you sure you want to delete this post and re-draft it? Favourites and boosts will be lost, and replies to the original post will be orphaned.", - "confirmations.redraft.title": "Delete & redraft post?", + "confirmations.redraft.title": "Delete and redraft post?", "confirmations.remove_from_followers.confirm": "Remove follower", "confirmations.remove_from_followers.message": "{name} will stop following you. Are you sure you want to proceed?", "confirmations.remove_from_followers.title": "Remove follower?", @@ -306,7 +328,7 @@ "domain_block_modal.you_will_lose_num_followers": "You will lose {followersCount, plural, one {{followersCountDisplay} follower} other {{followersCountDisplay} followers}} and {followingCount, plural, one {{followingCountDisplay} person you follow} other {{followingCountDisplay} people you follow}}.", "domain_block_modal.you_will_lose_relationships": "You will lose all followers and people you follow from this server.", "domain_block_modal.you_wont_see_posts": "You won't see posts or notifications from users on this server.", - "domain_pill.activitypub_lets_connect": "It lets you connect and interact with people not just on Mastodon, but across different social apps too.", + "domain_pill.activitypub_lets_connect": "It lets you connect and interact with people, not just on Mastodon, but across different social apps too.", "domain_pill.activitypub_like_language": "ActivityPub is like the language Mastodon speaks with other social networks.", "domain_pill.server": "Server", "domain_pill.their_handle": "Their handle:", @@ -317,7 +339,7 @@ "domain_pill.who_they_are": "Since handles say who someone is and where they are, you can interact with people across the social web of .", "domain_pill.who_you_are": "Because your handle says who you are and where you are, people can interact with you across the social web of .", "domain_pill.your_handle": "Your handle:", - "domain_pill.your_server": "Your digital home, where all of your posts live. Don’t like this one? Transfer servers at any time and bring your followers, too.", + "domain_pill.your_server": "Your digital home, where all of your posts live. Don’t like this one? Transfer servers at any time and bring your followers too.", "domain_pill.your_username": "Your unique identifier on this server. It’s possible to find users with the same username on different servers.", "dropdown.empty": "Select an option", "embed.instructions": "Embed this post on your website by copying the code below.", @@ -340,7 +362,7 @@ "empty_column.account_featured.me": "You have not featured anything yet. Did you know that you can feature your hashtags you use the most, and even your friend’s accounts on your profile?", "empty_column.account_featured.other": "{acct} has not featured anything yet. Did you know that you can feature your hashtags you use the most, and even your friend’s accounts on your profile?", "empty_column.account_featured_other.unknown": "This account has not featured anything yet.", - "empty_column.account_hides_collections": "This user has chosen to not make this information available", + "empty_column.account_hides_collections": "This user has chosen not to make this information available", "empty_column.account_suspended": "Account suspended", "empty_column.account_timeline": "No posts here!", "empty_column.account_unavailable": "Profile unavailable", @@ -359,7 +381,7 @@ "empty_column.home": "Your home timeline is empty! Follow more people to fill it up.", "empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.", "empty_column.mutes": "You haven't muted any users yet.", - "empty_column.notification_requests": "All clear! There is nothing here. When you receive new notifications, they will appear here according to your settings.", + "empty_column.notification_requests": "All clear! There is nothing here. When you receive new notifications, they will appear here, according to your settings.", "empty_column.notifications": "You don't have any notifications yet. When other people interact with you, you will see it here.", "empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other servers to fill it up", "error.no_hashtag_feed_access": "Join or log in to view and follow this hashtag.", @@ -419,6 +441,8 @@ "follow_suggestions.who_to_follow": "Who to follow", "followed_tags": "Followed hashtags", "footer.about": "About", + "footer.about_mastodon": "About Mastodon", + "footer.about_server": "About {domain}", "footer.about_this_server": "About", "footer.directory": "Profiles directory", "footer.get_app": "Get the app", @@ -483,7 +507,7 @@ "interaction_modal.on_another_server": "On a different server", "interaction_modal.on_this_server": "On this server", "interaction_modal.title": "Sign in to continue", - "interaction_modal.username_prompt": "E.g. {example}", + "interaction_modal.username_prompt": "Eg {example}", "intervals.full.days": "{number, plural, one {# day} other {# days}}", "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}", "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}", @@ -601,7 +625,7 @@ "navigation_bar.preferences": "Preferences", "navigation_bar.privacy_and_reach": "Privacy and reach", "navigation_bar.search": "Search", - "navigation_bar.search_trends": "Search / Trending", + "navigation_bar.search_trends": "Search/Trending", "navigation_panel.collapse_followed_tags": "Collapse followed hashtags menu", "navigation_panel.collapse_lists": "Collapse list menu", "navigation_panel.expand_followed_tags": "Expand followed hashtags menu", @@ -641,7 +665,7 @@ "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.poll": "A poll you voted in has ended", + "notification.poll": "A poll in which you voted has ended", "notification.quoted_update": "{name} edited a post you have quoted", "notification.reblog": "{name} boosted your post", "notification.reblog.name_and_others_with_link": "{name} and {count, plural, one {# other} other {# others}} boosted your post", @@ -667,7 +691,7 @@ "notification_requests.explainer_for_limited_account": "Notifications from this account have been filtered because the account has been limited by a moderator.", "notification_requests.explainer_for_limited_remote_account": "Notifications from this account have been filtered because the account or its server has been limited by a moderator.", "notification_requests.maximize": "Maximise", - "notification_requests.minimize_banner": "Minimize filtered notifications banner", + "notification_requests.minimize_banner": "Minimise filtered notifications banner", "notification_requests.notifications_from": "Notifications from {name}", "notification_requests.title": "Filtered notifications", "notification_requests.view": "View notifications", @@ -717,11 +741,11 @@ "notifications.policy.filter_limited_accounts_title": "Moderated accounts", "notifications.policy.filter_new_accounts.hint": "Created within the past {days, plural, one {one day} other {# days}}", "notifications.policy.filter_new_accounts_title": "New accounts", - "notifications.policy.filter_not_followers_hint": "Including people who have been following you fewer than {days, plural, one {one day} other {# days}}", + "notifications.policy.filter_not_followers_hint": "Including people who have been following you for fewer than {days, plural, one {one day} other {# days}}", "notifications.policy.filter_not_followers_title": "People not following you", "notifications.policy.filter_not_following_hint": "Until you manually approve them", "notifications.policy.filter_not_following_title": "People you don't follow", - "notifications.policy.filter_private_mentions_hint": "Filtered unless it's in reply to your own mention or if you follow the sender", + "notifications.policy.filter_private_mentions_hint": "Filtered, unless it's in reply to your own mention, or if you follow the sender", "notifications.policy.filter_private_mentions_title": "Unsolicited private mentions", "notifications.policy.title": "Manage notifications from…", "notifications_permission_banner.enable": "Enable desktop notifications", @@ -868,17 +892,17 @@ "search_results.all": "All", "search_results.hashtags": "Hashtags", "search_results.no_results": "No results.", - "search_results.no_search_yet": "Try searching for posts, profiles or hashtags.", + "search_results.no_search_yet": "Try searching for posts, profiles, or hashtags.", "search_results.see_all": "See all", "search_results.statuses": "Posts", "search_results.title": "Search for \"{q}\"", "server_banner.about_active_users": "People using this server during the last 30 days (Monthly Active Users)", "server_banner.active_users": "active users", "server_banner.administered_by": "Administered by:", - "server_banner.is_one_of_many": "{domain} is one of the many independent Mastodon servers you can use to participate in the fediverse.", + "server_banner.is_one_of_many": "{domain} is one of the many independent Mastodon servers you can use to participate in the Fediverse.", "server_banner.server_stats": "Server stats:", "sign_in_banner.create_account": "Create account", - "sign_in_banner.follow_anyone": "Follow anyone across the fediverse and see it all in chronological order. No algorithms, ads, or clickbait in sight.", + "sign_in_banner.follow_anyone": "Follow anyone across the Fediverse and see it all in chronological order. No algorithms, ads, or clickbait in sight.", "sign_in_banner.mastodon_is": "Mastodon is the best way to keep up with what's happening.", "sign_in_banner.sign_in": "Sign in", "sign_in_banner.sso_redirect": "Login or Register", @@ -1020,7 +1044,7 @@ "video.mute": "Mute", "video.pause": "Pause", "video.play": "Play", - "video.skip_backward": "Skip backward", + "video.skip_backward": "Skip backwards", "video.skip_forward": "Skip forward", "video.unmute": "Unmute", "video.volume_down": "Volume down", diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json index f8cfa07f9c787a..f5904154538b50 100644 --- a/app/javascript/mastodon/locales/eo.json +++ b/app/javascript/mastodon/locales/eo.json @@ -28,6 +28,7 @@ "account.disable_notifications": "Ĉesu sciigi min kiam @{name} afiŝas", "account.domain_blocking": "Blokas domajnon", "account.edit_profile": "Redakti la profilon", + "account.edit_profile_short": "Redakti", "account.enable_notifications": "Sciigu min kiam @{name} afiŝos", "account.endorse": "Montri en profilo", "account.familiar_followers_one": "Sekvita de {name1}", @@ -40,6 +41,7 @@ "account.follow": "Sekvi", "account.follow_back": "Sekvu reen", "account.follow_back_short": "Sekvu reen", + "account.follow_request_cancel_short": "Nuligi", "account.followers": "Sekvantoj", "account.followers.empty": "Ankoraŭ neniu sekvas ĉi tiun uzanton.", "account.followers_counter": "{count, plural, one{{counter} sekvanto} other {{counter} sekvantoj}}", @@ -107,25 +109,16 @@ "alt_text_modal.describe_for_people_with_visual_impairments": "Priskribi ĉi tion por homoj kun vidaj malkapabloj…", "alt_text_modal.done": "Farita", "announcement.announcement": "Anonco", - "annual_report.summary.archetype.booster": "La ĉasanto de mojoso", - "annual_report.summary.archetype.lurker": "La vidanto", - "annual_report.summary.archetype.oracle": "La orakolo", - "annual_report.summary.archetype.pollster": "La balotenketisto", - "annual_report.summary.archetype.replier": "La plej societema", - "annual_report.summary.followers.followers": "sekvantoj", - "annual_report.summary.followers.total": "{count} tute", - "annual_report.summary.here_it_is": "Jen via resumo de {year}:", - "annual_report.summary.highlighted_post.by_favourites": "plej ŝatata afiŝo", - "annual_report.summary.highlighted_post.by_reblogs": "plej diskonigita afiŝo", - "annual_report.summary.highlighted_post.by_replies": "afiŝo kun la plej multaj respondoj", - "annual_report.summary.highlighted_post.possessive": "de {name}", + "annual_report.announcement.action_dismiss": "Ne, dankon", + "annual_report.nav_item.badge": "Nova", + "annual_report.shared_page.donate": "Donaci", + "annual_report.summary.copy_link": "Kopii ligilon", + "annual_report.summary.highlighted_post.title": "Plej populara afiŝo", "annual_report.summary.most_used_app.most_used_app": "plej uzita aplikaĵo", "annual_report.summary.most_used_hashtag.most_used_hashtag": "plej uzata kradvorto", - "annual_report.summary.most_used_hashtag.none": "Nenio", "annual_report.summary.new_posts.new_posts": "novaj afiŝoj", "annual_report.summary.percentile.text": "Tion metas vin en la plejde {domain} uzantoj.", "annual_report.summary.percentile.we_wont_tell_bernie": "Ni ne diros al Zamenhof.", - "annual_report.summary.thanks": "Dankon pro esti parto de Mastodon!", "attachments_list.unprocessed": "(neprilaborita)", "audio.hide": "Kaŝi aŭdion", "block_modal.remote_users_caveat": "Ni petos al la servilo {domain} respekti vian elekton. Tamen, plenumo ne estas garantiita ĉar iuj serviloj eble manipulas blokojn malsame. Publikaj afiŝoj eble ankoraŭ estas videbla por ne-ensalutintaj uzantoj.", diff --git a/app/javascript/mastodon/locales/es-AR.json b/app/javascript/mastodon/locales/es-AR.json index b34e4cb3a87270..51fe6e89956f9c 100644 --- a/app/javascript/mastodon/locales/es-AR.json +++ b/app/javascript/mastodon/locales/es-AR.json @@ -114,29 +114,50 @@ "alt_text_modal.done": "Listo", "announcement.announcement": "Anuncio", "annual_report.announcement.action_build": "Construir mi MastodonAnual", + "annual_report.announcement.action_dismiss": "No, gracias", "annual_report.announcement.action_view": "Ver mi MastodonAnual", "annual_report.announcement.description": "Descubrí más sobre tu participación en Mastodon durante el último año.", "annual_report.announcement.title": "Llegó MastodonAnual {year}", - "annual_report.summary.archetype.booster": "Corrió la voz", - "annual_report.summary.archetype.lurker": "El acechador", - "annual_report.summary.archetype.oracle": "El oráculo", - "annual_report.summary.archetype.pollster": "Estuvo consultando", - "annual_report.summary.archetype.replier": "Respondió un montón", - "annual_report.summary.followers.followers": "seguidores", - "annual_report.summary.followers.total": "{count} en total", - "annual_report.summary.here_it_is": "Acá está tu resumen de {year}:", - "annual_report.summary.highlighted_post.by_favourites": "el mensaje más veces marcado como favorito", - "annual_report.summary.highlighted_post.by_reblogs": "el mensaje que más adhesiones recibió", - "annual_report.summary.highlighted_post.by_replies": "el mensaje que más respuestas recibió", - "annual_report.summary.highlighted_post.possessive": "{name}", + "annual_report.nav_item.badge": "Nueva", + "annual_report.shared_page.donate": "Donar", + "annual_report.shared_page.footer": "Generado con {heart} por el equipo de Mastodon", + "annual_report.summary.archetype.booster.desc_public": "{name} permaneció al acecho en busca de mensajes para adherir, apuntando a otros creadores con perfecta puntería.", + "annual_report.summary.archetype.booster.desc_self": "Permaneciste al acecho en busca de mensajes para adherir, apuntando a otros creadores con perfecta puntería.", + "annual_report.summary.archetype.booster.name": "El arquero", + "annual_report.summary.archetype.die_drei_fragezeichen": "¿¿¿???", + "annual_report.summary.archetype.lurker.desc_public": "Sabemos que {name} estuvo afuera, en algún lado, disfrutando de Mastodon a su propio modo silencioso.", + "annual_report.summary.archetype.lurker.desc_self": "Sabemos que estuviste afuera, en algún lado, disfrutando de Mastodon a tu propio modo silencioso.", + "annual_report.summary.archetype.lurker.name": "El estoico", + "annual_report.summary.archetype.oracle.desc_public": "{name} creó más mensajes nuevos que respuestas, manteniendo a Mastodon fresco y de cara al futuro.", + "annual_report.summary.archetype.oracle.desc_self": "Creaste más mensajes nuevos que respuestas, manteniendo a Mastodon fresco y de cara al futuro.", + "annual_report.summary.archetype.oracle.name": "El oráculo", + "annual_report.summary.archetype.pollster.desc_public": "{name} creó más encuestas que mensajes de otro tipo, cultivando curiosidad en Mastodon.", + "annual_report.summary.archetype.pollster.desc_self": "Creaste más encuestas que mensajes de otro tipo, cultivando curiosidad en Mastodon.", + "annual_report.summary.archetype.pollster.name": "El maravillado", + "annual_report.summary.archetype.replier.desc_public": "{name} respondió frecuentemente a los mensajes de otras cuentas, polinizando con nuevos debates.", + "annual_report.summary.archetype.replier.desc_self": "Respondiste frecuentemente a los mensajes de otras cuentas, polinizando con nuevos debates.", + "annual_report.summary.archetype.replier.name": "La mariposa", + "annual_report.summary.archetype.reveal": "Revelar mi arquetipo", + "annual_report.summary.archetype.reveal_description": "¡Gracias por ser parte de Mastodon! Es hora de descubrir qué arquetipo encarnaste en {year}.", + "annual_report.summary.archetype.title_public": "El arquetipo de {name}", + "annual_report.summary.archetype.title_self": "Tu arquetipo", + "annual_report.summary.close": "Cerrar", + "annual_report.summary.copy_link": "Copiar enlace", + "annual_report.summary.followers.new_followers": "{count, plural, one {nuevo seguidor} other {nuevos seguidores}}", + "annual_report.summary.highlighted_post.boost_count": "Este mensaje recibió adhesiones {count, plural, one {una vez} other {# veces}}.", + "annual_report.summary.highlighted_post.favourite_count": "Este mensaje fue marcado como favorito {count, plural, one {una vez} other {# veces}}.", + "annual_report.summary.highlighted_post.reply_count": "Este mensaje recibió {count, plural, one {una respuesta} other {# respuestas}}.", + "annual_report.summary.highlighted_post.title": "Mensaje más popular", "annual_report.summary.most_used_app.most_used_app": "la aplicación más usada", "annual_report.summary.most_used_hashtag.most_used_hashtag": "la etiqueta más usada", - "annual_report.summary.most_used_hashtag.none": "Ninguna", + "annual_report.summary.most_used_hashtag.used_count": "Incluiste esta etiqueta en {count, plural, one {un mensaje} other {# mensajes}}.", + "annual_report.summary.most_used_hashtag.used_count_public": "{name} incluyó esta etiqueta en {count, plural, one {un mensaje} other {# mensajes}}.", "annual_report.summary.new_posts.new_posts": "nuevos mensajes", "annual_report.summary.percentile.text": "Eso te coloca en la cima delde los usuarios de {domain}.", "annual_report.summary.percentile.we_wont_tell_bernie": "Queda entre nos.", + "annual_report.summary.share_elsewhere": "Compartir en otro lado", "annual_report.summary.share_message": "¡Conseguí el arquetipo {archetype}!", - "annual_report.summary.thanks": "¡Gracias por ser parte de Mastodon!", + "annual_report.summary.share_on_mastodon": "Compartir en Mastodon", "attachments_list.unprocessed": "[sin procesar]", "audio.hide": "Ocultar audio", "block_modal.remote_users_caveat": "Le pediremos al servidor {domain} que respete tu decisión. Sin embargo, el cumplimiento no está garantizado, ya que algunos servidores pueden manejar los bloqueos de forma diferente. Los mensajes públicos todavía podrían estar visibles para los usuarios no conectados.", diff --git a/app/javascript/mastodon/locales/es-MX.json b/app/javascript/mastodon/locales/es-MX.json index aecb13d8c476c1..3ec8beb6bfa861 100644 --- a/app/javascript/mastodon/locales/es-MX.json +++ b/app/javascript/mastodon/locales/es-MX.json @@ -114,29 +114,51 @@ "alt_text_modal.done": "Hecho", "announcement.announcement": "Anuncio", "annual_report.announcement.action_build": "Preparar mi Wrapstodon", + "annual_report.announcement.action_dismiss": "No, gracias", "annual_report.announcement.action_view": "Ver mi Wrapstodon", "annual_report.announcement.description": "Descubre más sobre tu participación en Mastodon durante el último año.", "annual_report.announcement.title": "Wrapstodon {year} ha llegado", - "annual_report.summary.archetype.booster": "El cazador de tendencias", - "annual_report.summary.archetype.lurker": "El merodeador", - "annual_report.summary.archetype.oracle": "El oráculo", - "annual_report.summary.archetype.pollster": "El encuestador", - "annual_report.summary.archetype.replier": "El más sociable", - "annual_report.summary.followers.followers": "seguidores", - "annual_report.summary.followers.total": "{count} en total", - "annual_report.summary.here_it_is": "Este es el resumen de tu {year}:", - "annual_report.summary.highlighted_post.by_favourites": "publicación con más favoritos", - "annual_report.summary.highlighted_post.by_reblogs": "publicación más impulsada", - "annual_report.summary.highlighted_post.by_replies": "publicación con más respuestas", - "annual_report.summary.highlighted_post.possessive": "de {name}", + "annual_report.nav_item.badge": "Nueva", + "annual_report.shared_page.donate": "Donar", + "annual_report.shared_page.footer": "Generado con {heart} por el equipo de Mastodon", + "annual_report.shared_page.footer_server_info": "{username} usa {domain}, una de las muchas comunidades que funcionan con Mastodon.", + "annual_report.summary.archetype.booster.desc_public": "{name} se mantuvo a la caza de publicaciones para impulsar, dando visibilidad a otros creadores con una puntería perfecta.", + "annual_report.summary.archetype.booster.desc_self": "Te mantuviste a la caza de publicaciones para impulsar, amplificando a otros creadores con una puntería perfecta.", + "annual_report.summary.archetype.booster.name": "El arquero", + "annual_report.summary.archetype.die_drei_fragezeichen": "???", + "annual_report.summary.archetype.lurker.desc_public": "Sabemos que {name} estaba ahí fuera, en algún lugar, disfrutando de Mastodon a su manera tranquila.", + "annual_report.summary.archetype.lurker.desc_self": "Sabemos que estabas ahí fuera, en algún lugar, disfrutando de Mastodon a tu manera, en silencio.", + "annual_report.summary.archetype.lurker.name": "El estoico", + "annual_report.summary.archetype.oracle.desc_public": "{name} creó más publicaciones nuevas que respuestas, lo que mantuvo a Mastodon fresco y con visión de futuro.", + "annual_report.summary.archetype.oracle.desc_self": "Creaste más publicaciones nuevas que respuestas, lo que mantuvo a Mastodon fresco y con visión de futuro.", + "annual_report.summary.archetype.oracle.name": "El oráculo", + "annual_report.summary.archetype.pollster.desc_public": "{name} creó más encuestas que otros tipos de publicaciones, lo que despertó la curiosidad en Mastodon.", + "annual_report.summary.archetype.pollster.desc_self": "Creaste más encuestas que otros tipos de publicaciones, lo que despertó la curiosidad en Mastodon.", + "annual_report.summary.archetype.pollster.name": "El soñador", + "annual_report.summary.archetype.replier.desc_public": "{name} respondía con frecuencia a las publicaciones de otras personas, lo que generaba nuevos debates en Mastodon.", + "annual_report.summary.archetype.replier.desc_self": "Respondías con frecuencia a las publicaciones de otras personas, lo que generaba nuevos debates en Mastodon.", + "annual_report.summary.archetype.replier.name": "La mariposa", + "annual_report.summary.archetype.reveal": "Revelar mi arquetipo", + "annual_report.summary.archetype.reveal_description": "¡Gracias por formar parte de Mastodon! Es hora de descubrir qué arquetipo encarnaste en {year}.", + "annual_report.summary.archetype.title_public": "El arquetipo de {name}", + "annual_report.summary.archetype.title_self": "Tu arquetipo", + "annual_report.summary.close": "Cerrar", + "annual_report.summary.copy_link": "Copiar enlace", + "annual_report.summary.followers.new_followers": "{count, plural,one {nuevo seguidor} other {nuevos seguidores}}", + "annual_report.summary.highlighted_post.boost_count": "Esta publicación fue impulsada {count, plural,one {una vez} other {# veces}}.", + "annual_report.summary.highlighted_post.favourite_count": "Esta publicación fue marcada como favorita {count, plural,one {una vez} other {# veces}}.", + "annual_report.summary.highlighted_post.reply_count": "Esta publicación consiguió {count, plural,one {una respuesta} other {# respuestas}}.", + "annual_report.summary.highlighted_post.title": "Publicación más popular", "annual_report.summary.most_used_app.most_used_app": "aplicación más utilizada", "annual_report.summary.most_used_hashtag.most_used_hashtag": "etiqueta más utilizada", - "annual_report.summary.most_used_hashtag.none": "Ninguna", + "annual_report.summary.most_used_hashtag.used_count": "Incluiste esta etiqueta en {count, plural,one {una publicación} other {# publicaciones}}.", + "annual_report.summary.most_used_hashtag.used_count_public": "{name} incluyó esta etiqueta en {count, plural,one {una publicación} other {# publicaciones}}.", "annual_report.summary.new_posts.new_posts": "nuevas publicaciones", "annual_report.summary.percentile.text": "Eso te sitúa en el topde usuarios de {domain}.", "annual_report.summary.percentile.we_wont_tell_bernie": "No se lo diremos a Bernie.", + "annual_report.summary.share_elsewhere": "Compartir en otro lado", "annual_report.summary.share_message": "¡Obtuve el arquetipo {archetype}!", - "annual_report.summary.thanks": "¡Gracias por ser parte de Mastodon!", + "annual_report.summary.share_on_mastodon": "Compartir en Mastodon", "attachments_list.unprocessed": "(sin procesar)", "audio.hide": "Ocultar audio", "block_modal.remote_users_caveat": "Le pediremos al servidor {domain} que respete tu decisión. Sin embargo, el cumplimiento no está garantizado, ya que algunos servidores pueden manejar bloques de forma diferente. Las publicaciones públicas pueden ser todavía visibles para los usuarios no conectados.", @@ -419,6 +441,8 @@ "follow_suggestions.who_to_follow": "Recomendamos seguir", "followed_tags": "Etiquetas seguidas", "footer.about": "Acerca de", + "footer.about_mastodon": "Acerca de Mastodon", + "footer.about_server": "Acerca de {domain}", "footer.about_this_server": "Sobre nosotros", "footer.directory": "Directorio de perfiles", "footer.get_app": "Obtener la aplicación", diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json index 29652f84f4e69c..a09919bdade282 100644 --- a/app/javascript/mastodon/locales/es.json +++ b/app/javascript/mastodon/locales/es.json @@ -114,29 +114,30 @@ "alt_text_modal.done": "Hecho", "announcement.announcement": "Comunicación", "annual_report.announcement.action_build": "Preparar mi Wrapstodon", + "annual_report.announcement.action_dismiss": "No, gracias", "annual_report.announcement.action_view": "Ver mi Wrapstodon", "annual_report.announcement.description": "Descubre más sobre tu participación en Mastodon durante el último año.", "annual_report.announcement.title": "Wrapstodon {year} ha llegado", - "annual_report.summary.archetype.booster": "El cazador de tendencias", - "annual_report.summary.archetype.lurker": "El acechador", - "annual_report.summary.archetype.oracle": "El oráculo", - "annual_report.summary.archetype.pollster": "El encuestador", - "annual_report.summary.archetype.replier": "El más sociable", - "annual_report.summary.followers.followers": "seguidores", - "annual_report.summary.followers.total": "{count} en total", - "annual_report.summary.here_it_is": "Aquí está tu resumen de {year}:", - "annual_report.summary.highlighted_post.by_favourites": "publicación con más favoritos", - "annual_report.summary.highlighted_post.by_reblogs": "publicación más impulsada", - "annual_report.summary.highlighted_post.by_replies": "publicación con más respuestas", - "annual_report.summary.highlighted_post.possessive": "de {name}", + "annual_report.nav_item.badge": "Nuevo", + "annual_report.shared_page.donate": "Donar", + "annual_report.shared_page.footer": "Generado con {heart} por el equipo de Mastodon", + "annual_report.summary.archetype.title_public": "El arquetipo de {name}", + "annual_report.summary.archetype.title_self": "Tu arquetipo", + "annual_report.summary.close": "Cerrar", + "annual_report.summary.copy_link": "Copiar enlace", + "annual_report.summary.highlighted_post.boost_count": "Esta publicación fue impulsada {count, plural,one {una vez} other {# veces}}.", + "annual_report.summary.highlighted_post.reply_count": "Esta publicación recibió {count, plural,one {una respuesta} other {# respuestas}}.", + "annual_report.summary.highlighted_post.title": "Publicación más popular", "annual_report.summary.most_used_app.most_used_app": "aplicación más usada", "annual_report.summary.most_used_hashtag.most_used_hashtag": "etiqueta más usada", - "annual_report.summary.most_used_hashtag.none": "Ninguna", + "annual_report.summary.most_used_hashtag.used_count": "Incluiste esta etiqueta en {count, plural,one {una publicación} other {# publicaciones}}.", + "annual_report.summary.most_used_hashtag.used_count_public": "{name} incluyó esta etiqueta en {count, plural, one {una publicación} other {# publicaciones}}.", "annual_report.summary.new_posts.new_posts": "nuevas publicaciones", "annual_report.summary.percentile.text": "Eso te coloca en el topde usuarios de {domain}.", "annual_report.summary.percentile.we_wont_tell_bernie": "No se lo diremos a Bernie.", + "annual_report.summary.share_elsewhere": "Compartir en otro lugar", "annual_report.summary.share_message": "¡Obtuve el arquetipo {archetype}!", - "annual_report.summary.thanks": "¡Gracias por ser parte de Mastodon!", + "annual_report.summary.share_on_mastodon": "Compartir en Mastodon", "attachments_list.unprocessed": "(sin procesar)", "audio.hide": "Ocultar audio", "block_modal.remote_users_caveat": "Le pediremos al servidor {domain} que respete tu decisión. Sin embargo, el cumplimiento no está garantizado, ya que algunos servidores pueden manejar bloqueos de forma distinta. Los mensajes públicos pueden ser todavía visibles para los usuarios que no hayan iniciado sesión.", diff --git a/app/javascript/mastodon/locales/et.json b/app/javascript/mastodon/locales/et.json index 7d361cb914abb7..3ba4bd96572945 100644 --- a/app/javascript/mastodon/locales/et.json +++ b/app/javascript/mastodon/locales/et.json @@ -14,7 +14,7 @@ "about.powered_by": "Hajutatud sotsiaalmeedia, mille taga on {mastodon}", "about.rules": "Serveri reeglid", "account.account_note_header": "Isiklik märge", - "account.add_or_remove_from_list": "Lisa või Eemalda loeteludest", + "account.add_or_remove_from_list": "Lisa või eemalda loenditest", "account.badges.bot": "Robot", "account.badges.group": "Grupp", "account.block": "Blokeeri @{name}", @@ -37,7 +37,7 @@ "account.featured": "Esiletõstetud", "account.featured.accounts": "Profiilid", "account.featured.hashtags": "Teemaviited", - "account.featured_tags.last_status_at": "Viimane postitus {date}", + "account.featured_tags.last_status_at": "Viimane postitus: {date}", "account.featured_tags.last_status_never": "Postitusi pole", "account.follow": "Jälgi", "account.follow_back": "Jälgi vastu", @@ -117,26 +117,14 @@ "annual_report.announcement.action_view": "Vaata kokkuvõtet minu tegevusest Mastodonis", "annual_report.announcement.description": "Vaata teavet oma suhestumise kohta Mastodonis eelmisel aastal.", "annual_report.announcement.title": "{year}. aasta Mastodoni kokkuvõte on valmis", - "annual_report.summary.archetype.booster": "Ägesisu küttija", - "annual_report.summary.archetype.lurker": "Hiilija", - "annual_report.summary.archetype.oracle": "Oraakel", - "annual_report.summary.archetype.pollster": "Küsitleja", - "annual_report.summary.archetype.replier": "Sotsiaalne liblikas", - "annual_report.summary.followers.followers": "jälgijad", - "annual_report.summary.followers.total": "{count} kokku", - "annual_report.summary.here_it_is": "Siin on sinu {year} ülevaatlikult:", - "annual_report.summary.highlighted_post.by_favourites": "enim lemmikuks märgitud postitus", - "annual_report.summary.highlighted_post.by_reblogs": "enim jagatud postitus", - "annual_report.summary.highlighted_post.by_replies": "kõige vastatum postitus", - "annual_report.summary.highlighted_post.possessive": "omanik {name}", + "annual_report.summary.highlighted_post.title": "Kõige populaarsemad postitused", "annual_report.summary.most_used_app.most_used_app": "enim kasutatud äpp", "annual_report.summary.most_used_hashtag.most_used_hashtag": "enim kasutatud teemaviide", - "annual_report.summary.most_used_hashtag.none": "Puudub", + "annual_report.summary.most_used_hashtag.used_count": "Sa lisasid selle teemaviite {count, plural, one {ühele postitusele} other {#-le postitusele}}.", "annual_report.summary.new_posts.new_posts": "uus postitus", "annual_report.summary.percentile.text": "See paneb su top {domain} kasutajate hulka.", "annual_report.summary.percentile.we_wont_tell_bernie": "Vägev.", "annual_report.summary.share_message": "Minu arhetüüp on {archetype}!", - "annual_report.summary.thanks": "Tänud olemast osa Mastodonist!", "attachments_list.unprocessed": "(töötlemata)", "audio.hide": "Peida audio", "block_modal.remote_users_caveat": "Serverile {domain} edastatakse palve otsust järgida. Ometi pole see tagatud, kuna mõned serverid võivad blokeeringuid käsitleda omal moel. Avalikud postitused võivad tuvastamata kasutajatele endiselt näha olla.", diff --git a/app/javascript/mastodon/locales/eu.json b/app/javascript/mastodon/locales/eu.json index 688ba0976769ca..be79158d982492 100644 --- a/app/javascript/mastodon/locales/eu.json +++ b/app/javascript/mastodon/locales/eu.json @@ -113,25 +113,51 @@ "alt_text_modal.describe_for_people_with_visual_impairments": "Deskribatu hau ikusmen arazoak dituzten pertsonentzat…", "alt_text_modal.done": "Egina", "announcement.announcement": "Iragarpena", - "annual_report.summary.archetype.booster": "Sustatzailea", - "annual_report.summary.archetype.lurker": "Begiluzea", - "annual_report.summary.archetype.oracle": "Orakulua", - "annual_report.summary.archetype.pollster": "Bozketazalea", - "annual_report.summary.archetype.replier": "Tolosa", - "annual_report.summary.followers.followers": "jarraitzaileak", - "annual_report.summary.followers.total": "{count} guztira", - "annual_report.summary.here_it_is": "Hona hemen zure {year}. urtearen bilduma:", - "annual_report.summary.highlighted_post.by_favourites": "egindako bidalketa gogokoena", - "annual_report.summary.highlighted_post.by_reblogs": "egindako bidalketa zabalduena", - "annual_report.summary.highlighted_post.by_replies": "erantzun gehien izan dituen bidalketa", - "annual_report.summary.highlighted_post.possessive": "{name}-(r)ena", + "annual_report.announcement.action_build": "Sortu nire Wrapstodon", + "annual_report.announcement.action_dismiss": "Ez, eskerrik asko", + "annual_report.announcement.action_view": "Ikusi nire Wrapstodon", + "annual_report.announcement.description": "Ezagutu azken urtean Mastodonen izan duzun parte-hartzeari buruzko informazio gehiago.", + "annual_report.announcement.title": "Hemen da {2025}(e)ko Wrapstodon", + "annual_report.nav_item.badge": "Berria", + "annual_report.shared_page.donate": "Egin dohaintza", + "annual_report.shared_page.footer": "Mastodonen taldeak {heart} sortua", + "annual_report.summary.archetype.booster.desc_public": "{name}(e)k promozionatzeko argitalpenen bila jarraitu zuen, beste sortzaile batzuk punteria perfektuarekin anplifikatuz.", + "annual_report.summary.archetype.booster.desc_self": "Bultzatu beharreko argitalpenen zelatan egon zinen, punteria perfektua zuten beste sortzaile batzuk anplifikatuz.", + "annual_report.summary.archetype.booster.name": "Arkularia", + "annual_report.summary.archetype.die_drei_fragezeichen": "???", + "annual_report.summary.archetype.lurker.desc_public": "Badakigu {name} hor zegoela kanpoan, nonbait, Mastodonez gozatzen bere modu lasaian.", + "annual_report.summary.archetype.lurker.desc_self": "Badakigu hor zinela kanpoan, nonbait, Mastodonez gozatzen zure erara, isilean.", + "annual_report.summary.archetype.lurker.name": "Estoikoa", + "annual_report.summary.archetype.oracle.desc_public": "{name}(e)k erantzun baino argitalpen berri gehiago sortu zituen, eta horrek Mastodon fresko eta etorkizuneko ikuspegiarekin mantendu zuen.", + "annual_report.summary.archetype.oracle.desc_self": "Erantzun baino argitalpen berri gehiago sortu zenituen, eta horrek Mastodon fresko eta etorkizuneko ikuspegiarekin mantendu zuen.", + "annual_report.summary.archetype.oracle.name": "Orakulua", + "annual_report.summary.archetype.pollster.desc_public": "{name}(e)k inkesta gehiago sortu zituen beste argitalpen mota batzuek baino, eta horrek jakin-mina piztu zuen Mastodonen.", + "annual_report.summary.archetype.pollster.desc_self": "Beste argitalpen batzuk baino inkesta gehiago sortu zenituen, eta horrek jakin-mina piztu zuen Mastodonen.", + "annual_report.summary.archetype.pollster.name": "Ameslaria", + "annual_report.summary.archetype.replier.desc_public": "{name}(e)k maiz erantzuten zien beste pertsona batzuen argitalpenei, Mastodon polinizatuz eztabaida berriekin.", + "annual_report.summary.archetype.replier.desc_self": "Maiz erantzuten zenien beste pertsona batzuen argitalpenei, Mastodon polinizatuz eztabaida berriekin.", + "annual_report.summary.archetype.replier.name": "Tximeleta", + "annual_report.summary.archetype.reveal": "Erakutsi nire arketipoa", + "annual_report.summary.archetype.reveal_description": "Eskerrik asko Mastodonen parte izateagatik! Bada garaia jakiteko zer arketipo haragitu duzun {year}(e)an.", + "annual_report.summary.archetype.title_public": "{name}-(r)en arketipoa", + "annual_report.summary.archetype.title_self": "Zure arketipoa", + "annual_report.summary.close": "Itxi", + "annual_report.summary.copy_link": "Kopiatu esteka", + "annual_report.summary.followers.new_followers": "{count, plural, one {jarraitzaile berri} other {jarraitzaile berri}}", + "annual_report.summary.highlighted_post.boost_count": "Bidalketa honek {count, plural, one {bultzada 1 dauka} other {# bultzada dauzka}}.", + "annual_report.summary.highlighted_post.favourite_count": "Bidalketa honek {count, plural, one {gogoko 1 dauka} other {# gogoko dauzka}}.", + "annual_report.summary.highlighted_post.reply_count": "Bidalketa honek {count, plural, one {erantzun 1 dauka} other {# erantzun dauzka}}.", + "annual_report.summary.highlighted_post.title": "Bidalketa ospetsuena", "annual_report.summary.most_used_app.most_used_app": "app erabiliena", "annual_report.summary.most_used_hashtag.most_used_hashtag": "traola erabiliena", - "annual_report.summary.most_used_hashtag.none": "Bat ere ez", + "annual_report.summary.most_used_hashtag.used_count": "Traola hau {count, plural, one {bidalketa baten sartu zenuen} other {# bidalketatan sartu zenuen}}.", + "annual_report.summary.most_used_hashtag.used_count_public": "{name}(e)k traola hau {count, plural, one {bidalketa baten sartu zuen} other {# bidalketatan sartu zituen}}.", "annual_report.summary.new_posts.new_posts": "bidalketa berriak", "annual_report.summary.percentile.text": "Horrek jartzen zaitu top (e)an {domain} erabiltzaileen artean ", "annual_report.summary.percentile.we_wont_tell_bernie": "Bernieri ez diogu ezer esango ;)..", - "annual_report.summary.thanks": "Eskerrik asko Mastodonen parte izateagatik!", + "annual_report.summary.share_elsewhere": "Partekatu beste edonon", + "annual_report.summary.share_message": "{arketipoa} arketipoa daukat!", + "annual_report.summary.share_on_mastodon": "Partekatu Mastodonen", "attachments_list.unprocessed": "(prozesatu gabe)", "audio.hide": "Ezkutatu audioa", "block_modal.remote_users_caveat": "{domain} zerbitzariari zure erabakia errespeta dezan eskatuko diogu. Halere, araua beteko den ezin da bermatu, zerbitzari batzuk modu desberdinean kudeatzen baitituzte blokeoak. Baliteke argitalpen publikoak saioa hasi ez duten erabiltzaileentzat ikusgai egotea.", @@ -249,7 +275,7 @@ "confirmations.missing_alt_text.secondary": "Bidali edonola ere", "confirmations.missing_alt_text.title": "Testu alternatiboa gehitu?", "confirmations.mute.confirm": "Mututu", - "confirmations.private_quote_notify.cancel": "Ediziora bueltatu", + "confirmations.private_quote_notify.cancel": "Bueltatu ediziora", "confirmations.private_quote_notify.confirm": "Argitaratu bidalketa", "confirmations.private_quote_notify.do_not_show_again": "Ez erakutsi mezu hau berriro", "confirmations.private_quote_notify.message": "Aipatzen ari zaren pertsonak eta aipatutako besteek jakinarazpena jasoko dute eta zure sarrera ikusi ahalko dute, zure jarraitzaileak ez badira ere.", @@ -357,6 +383,7 @@ "empty_column.notification_requests": "Garbi-garbi! Ezertxo ere ez hemen. Jakinarazpenak jasotzen dituzunean, hemen agertuko dira zure ezarpenen arabera.", "empty_column.notifications": "Ez duzu jakinarazpenik oraindik. Jarri besteekin harremanetan elkarrizketa abiatzeko.", "empty_column.public": "Ez dago ezer hemen! Idatzi zerbait publikoki edo jarraitu eskuz beste zerbitzari batzuetako erabiltzaileei hau betetzen joateko", + "error.no_hashtag_feed_access": "Egin bat edo hasi saioa etiketa hau ikusi eta jarraitzeko.", "error.unexpected_crash.explanation": "Gure kodean arazoren bat dela eta, edo nabigatzailearekin bateragarritasun arazoren bat dela eta, orri hau ezin izan da ongi bistaratu.", "error.unexpected_crash.explanation_addons": "Ezin izan da orria behar bezala bistaratu. Errore honen jatorria nabigatzailearen gehigarri batean edo itzulpen automatikoko tresnetan dago ziur aski.", "error.unexpected_crash.next_steps": "Saiatu orria berritzen. Horrek ez badu laguntzen, agian Mastodon erabiltzeko aukera duzu oraindik ere beste nabigatzaile bat edo aplikazio natibo bat erabilita.", @@ -515,6 +542,7 @@ "keyboard_shortcuts.toggle_hidden": "testua erakustea/ezkutatzea abisu baten atzean", "keyboard_shortcuts.toggle_sensitivity": "multimedia erakutsi/ezkutatzeko", "keyboard_shortcuts.toot": "Hasi bidalketa berri bat", + "keyboard_shortcuts.top": "Mugitu zerrendaren hasierara", "keyboard_shortcuts.translate": "bidalketa itzultzeko", "keyboard_shortcuts.unfocus": "testua konposatzeko area / bilaketatik fokua kentzea", "keyboard_shortcuts.up": "zerrendan gora mugitzea", @@ -903,6 +931,7 @@ "status.edited_x_times": "{count, plural, one {behin} other {{count} aldiz}} editatua", "status.embed": "Lortu txertatzeko kodea", "status.favourite": "Gogokoa", + "status.favourites_count": "{count, plural, one {{counter} gogoko} other {{counter} gogoko}}", "status.filter": "Iragazi bidalketa hau", "status.history.created": "{name} erabiltzaileak sortua {date}", "status.history.edited": "{name} erabiltzaileak editatua {date}", @@ -937,12 +966,14 @@ "status.quotes.empty": "Momentuz inork ez du bidalketa hau aipatu. Norbaitek eginez gero, hemen agertuko da.", "status.quotes.local_other_disclaimer": "Egileak errefusatutako aipuak ez dira erakutsiko.", "status.quotes.remote_other_disclaimer": "{domain} zerbitzariko aipuak baino ez daude bermatuta hemen. Egileak errefusatutako aipuak ez dira erakutsiko.", + "status.quotes_count": "{count, plural, one {{counter} aipu} other {{counter} aipu}}", "status.read_more": "Irakurri gehiago", "status.reblog": "Bultzada", "status.reblog_or_quote": "Bultzatu edo aipatu", "status.reblog_private": "Partekatu berriz zure jarraitzaileekin", "status.reblogged_by": "{name}(r)en bultzada", "status.reblogs.empty": "Inork ez dio bultzada eman bidalketa honi oraindik. Inork egiten badu, hemen agertuko da.", + "status.reblogs_count": "{count, plural, one {{counter} bultzaeda} other {{counter} bultzaeda}}", "status.redraft": "Ezabatu eta berridatzi", "status.remove_bookmark": "Kendu laster-marka", "status.remove_favourite": "Kendu gogokoetatik", diff --git a/app/javascript/mastodon/locales/fa.json b/app/javascript/mastodon/locales/fa.json index 7eda0c0a923ad5..7684a328fbb5ca 100644 --- a/app/javascript/mastodon/locales/fa.json +++ b/app/javascript/mastodon/locales/fa.json @@ -117,26 +117,12 @@ "annual_report.announcement.action_view": "دیدن خلاصهٔ ماستودونم", "annual_report.announcement.description": "کشف بیش‌تر دربارهٔ درگیریتان روی ماستودون در سال گذشته.", "annual_report.announcement.title": "خلاصهٔ ماستودون {year} این‌جاست", - "annual_report.summary.archetype.booster": "باحال‌یاب", - "annual_report.summary.archetype.lurker": "کم‌پیدا", - "annual_report.summary.archetype.oracle": "غیب‌گو", - "annual_report.summary.archetype.pollster": "نظرسنج", - "annual_report.summary.archetype.replier": "پاسخ‌گو", - "annual_report.summary.followers.followers": "دنبال کننده", - "annual_report.summary.followers.total": "در مجموع {count}", - "annual_report.summary.here_it_is": "بازبینی {year} تان:", - "annual_report.summary.highlighted_post.by_favourites": "پرپسندترین فرسته", - "annual_report.summary.highlighted_post.by_reblogs": "پرتقویت‌ترین فرسته", - "annual_report.summary.highlighted_post.by_replies": "پرپاسخ‌ترین فرسته", - "annual_report.summary.highlighted_post.possessive": "{name}", "annual_report.summary.most_used_app.most_used_app": "پراستفاده‌ترین کاره", "annual_report.summary.most_used_hashtag.most_used_hashtag": "پراستفاده‌ترین برچسب", - "annual_report.summary.most_used_hashtag.none": "هیچ‌کدام", "annual_report.summary.new_posts.new_posts": "فرستهٔ جدید", "annual_report.summary.percentile.text": "بین کاربران {domain} جزوبرتر هستید.", "annual_report.summary.percentile.we_wont_tell_bernie": "به برنی خبر نمی‌دهیم.", "annual_report.summary.share_message": "من کهن‌الگوی {archetype} را گرفتم!", - "annual_report.summary.thanks": "سپاس که بخشی از ماستودون هستید!", "attachments_list.unprocessed": "(پردازش نشده)", "audio.hide": "نهفتن صدا", "block_modal.remote_users_caveat": "از کارساز {domain} خواهیم خواست که به تصمیمتان احترام بگذارد. با این حال تضمینی برای رعایتش وجود ندارد؛ زیرا برخی کارسازها ممکن است مسدودی را متفاوت مدیریت کنند. ممکن است فرسته‌های عمومی همچنان برای کاربران وارد نشده نمایان باشند.", diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json index e811ba70d19e36..c0cd9a77cd5a9b 100644 --- a/app/javascript/mastodon/locales/fi.json +++ b/app/javascript/mastodon/locales/fi.json @@ -114,28 +114,51 @@ "alt_text_modal.done": "Valmis", "announcement.announcement": "Tiedote", "annual_report.announcement.action_build": "Koosta oma Wrapstodon", + "annual_report.announcement.action_dismiss": "Ei kiitos", "annual_report.announcement.action_view": "Näytä oma Wrapstodon", "annual_report.announcement.description": "Tutustu toimintaasi Mastodonissa kuluneen vuoden aikana.", "annual_report.announcement.title": "Wrapstodon {year} on täällä", - "annual_report.summary.archetype.booster": "Tehostaja", - "annual_report.summary.archetype.lurker": "Lymyilijä", - "annual_report.summary.archetype.oracle": "Oraakkeli", - "annual_report.summary.archetype.pollster": "Mielipidetutkija", - "annual_report.summary.archetype.replier": "Sosiaalinen perhonen", - "annual_report.summary.followers.followers": "seuraajaa", - "annual_report.summary.followers.total": "{count} yhteensä", - "annual_report.summary.here_it_is": "Tässä on katsaus vuoteesi {year}:", - "annual_report.summary.highlighted_post.by_favourites": "suosikkeihin lisätyin julkaisu", - "annual_report.summary.highlighted_post.by_reblogs": "tehostetuin julkaisu", - "annual_report.summary.highlighted_post.by_replies": "julkaisu, jolla on eniten vastauksia", - "annual_report.summary.highlighted_post.possessive": "Käyttäjän {name}", + "annual_report.nav_item.badge": "Uusi", + "annual_report.shared_page.donate": "Lahjoita", + "annual_report.shared_page.footer": "Luotu {heart}:lla Mastodon-tiimin toimesta", + "annual_report.shared_page.footer_server_info": "{username} käyttää palvelinta {domain}, yhtä monista Mastodonin tarjoamista yhteisöistä.", + "annual_report.summary.archetype.booster.desc_public": "{name} pysyi valppaana tehostettavien julkaisujen suhteen, vahvistaen muita luojia täydellisellä tähtäyksellä.", + "annual_report.summary.archetype.booster.desc_self": "Pysyit valppaana tehostettavien julkaisujen suhteen, vahvistaen muita luojia täydellisellä tähtäyksellä.", + "annual_report.summary.archetype.booster.name": "Jousimies", + "annual_report.summary.archetype.die_drei_fragezeichen": "???", + "annual_report.summary.archetype.lurker.desc_public": "Tiedämme, että {name} oli siellä jossakin, nauttien Mastodonista omalla hiljaisella tavallaan.", + "annual_report.summary.archetype.lurker.desc_self": "Tiedämme, että olit siellä jossakin, nauttien Mastodonista omalla hiljaisella tavallasi.", + "annual_report.summary.archetype.lurker.name": "Stoalainen", + "annual_report.summary.archetype.oracle.desc_public": "{name} loi enemmän julkaisuja kuin vastauksia, siten pitäen Mastodonin tuoreena ja valmiina tulevaisuuteen.", + "annual_report.summary.archetype.oracle.desc_self": "Loit enemmän julkaisuja kuin vastauksia, siten pitäen Mastodonin tuoreena ja valmiina tulevaisuuteen.", + "annual_report.summary.archetype.oracle.name": "Oraakkeli", + "annual_report.summary.archetype.pollster.desc_public": "{name} loi enemmän äänestyksiä kuin muita julkaisutyyppejä, siten herättäen uteliaisuutta Mastodonissa.", + "annual_report.summary.archetype.pollster.desc_self": "Loit enemmän äänestyksiä kuin muita julkaisutyyppejä, siten herättäen uteliaisuutta Mastodonissa.", + "annual_report.summary.archetype.pollster.name": "Ihmettelijä", + "annual_report.summary.archetype.replier.desc_public": "{name} vastasi säännöllisesti toisten julkaisuihin, siten pölyttäen Mastodonia uusilla keskusteluilla.", + "annual_report.summary.archetype.replier.desc_self": "Vastasit säännöllisesti toisten julkaisuihin, siten pölyttäen Mastodonia uusilla keskusteluilla.", + "annual_report.summary.archetype.replier.name": "Perhonen", + "annual_report.summary.archetype.reveal": "Paljasta arkkityyppini", + "annual_report.summary.archetype.reveal_description": "Kiitos, että olet osa Mastodonia! Aika selvittää, minkä arkkityypin ruumiillistuma olit vuonna {year}.", + "annual_report.summary.archetype.title_public": "Käyttäjän {name} arkkityyppi", + "annual_report.summary.archetype.title_self": "Arkkityyppisi", + "annual_report.summary.close": "Sulje", + "annual_report.summary.copy_link": "Kopioi linkki", + "annual_report.summary.followers.new_followers": "{count, plural, one {uusi seuraaja} other {uutta seuraajaa}}", + "annual_report.summary.highlighted_post.boost_count": "Tätä julkaisua tehostettiin {count, plural, one {kerran} other {# kertaa}}.", + "annual_report.summary.highlighted_post.favourite_count": "Tämä julkaisu lisättiin suosikkeihin {count, plural, one {kerran} other {# kertaa}}.", + "annual_report.summary.highlighted_post.reply_count": "Tämä julkaisu sai {count, plural, one {1 vastauksen} other {# vastausta}}.", + "annual_report.summary.highlighted_post.title": "Suosituin julkaisu", "annual_report.summary.most_used_app.most_used_app": "käytetyin sovellus", "annual_report.summary.most_used_hashtag.most_used_hashtag": "käytetyin aihetunniste", - "annual_report.summary.most_used_hashtag.none": "Ei mitään", + "annual_report.summary.most_used_hashtag.used_count": "Sisällytit tämän aihetunnisteen {count, plural, one {1 julkaisuun} other {# julkaisuun}}.", + "annual_report.summary.most_used_hashtag.used_count_public": "{name} sisällytti tämän aihetunnisteen {count, plural, one {1 julkaisuun} other {# julkaisuun}}.", "annual_report.summary.new_posts.new_posts": "uutta julkaisua", "annual_report.summary.percentile.text": "Olet osa huippujoukkoa, johon kuuluu{domain}-käyttäjistä.", "annual_report.summary.percentile.we_wont_tell_bernie": "Emme kerro Bernie Sandersille.", - "annual_report.summary.thanks": "Kiitos, että olet osa Mastodonia!", + "annual_report.summary.share_elsewhere": "Jaa muualla", + "annual_report.summary.share_message": "Arkkityyppini on {archetype}!", + "annual_report.summary.share_on_mastodon": "Jaa Mastodonissa", "attachments_list.unprocessed": "(käsittelemätön)", "audio.hide": "Piilota ääni", "block_modal.remote_users_caveat": "Pyydämme palvelinta {domain} kunnioittamaan päätöstäsi. Myötämielisyyttä ei kuitenkaan taata, koska jotkin palvelimet voivat käsitellä estoja eri tavalla. Julkiset julkaisut voivat silti näkyä kirjautumattomille käyttäjille.", @@ -418,6 +441,8 @@ "follow_suggestions.who_to_follow": "Ehdotuksia seurattavaksi", "followed_tags": "Seurattavat aihetunnisteet", "footer.about": "Tietoja", + "footer.about_mastodon": "Tietoja Mastodonista", + "footer.about_server": "Tietoja palvelimesta {domain}", "footer.about_this_server": "Tietoja", "footer.directory": "Profiilihakemisto", "footer.get_app": "Hanki sovellus", diff --git a/app/javascript/mastodon/locales/fo.json b/app/javascript/mastodon/locales/fo.json index 21f03cfb5a49e9..e87ba3cead3e55 100644 --- a/app/javascript/mastodon/locales/fo.json +++ b/app/javascript/mastodon/locales/fo.json @@ -114,29 +114,51 @@ "alt_text_modal.done": "Liðugt", "announcement.announcement": "Kunngerð", "annual_report.announcement.action_build": "Ger mítt Wrapstodon", + "annual_report.announcement.action_dismiss": "Nei takk", "annual_report.announcement.action_view": "Vís mítt Wrapstodon", "annual_report.announcement.description": "Fá meira at vita um títt virksemi á Mastodon seinasta árið.", "annual_report.announcement.title": "Wrapstodon {year} er komið", - "annual_report.summary.archetype.booster": "Kuli jagarin", - "annual_report.summary.archetype.lurker": "Lúrarin", - "annual_report.summary.archetype.oracle": "Oraklið", - "annual_report.summary.archetype.pollster": "Spyrjarin", - "annual_report.summary.archetype.replier": "Sosiali firvaldurin", - "annual_report.summary.followers.followers": "fylgjarar", - "annual_report.summary.followers.total": "{count} íalt", - "annual_report.summary.here_it_is": "Her er ein samandráttur av {year}:", - "annual_report.summary.highlighted_post.by_favourites": "mest dámdi postur", - "annual_report.summary.highlighted_post.by_reblogs": "oftast stimbraði postur", - "annual_report.summary.highlighted_post.by_replies": "postur við flestum svarum", - "annual_report.summary.highlighted_post.possessive": "hjá {name}", + "annual_report.nav_item.badge": "Nýtt", + "annual_report.shared_page.donate": "Stuðla", + "annual_report.shared_page.footer": "Gjørt við {heart} av Mastodon toyminum", + "annual_report.shared_page.footer_server_info": "{username} brúkar {domain}, ein av fleiri felagsskapum, sum er drivin av Mastodon.", + "annual_report.summary.archetype.booster.desc_public": "{name} helt fram at veiða postar at lyfta, og styrkti aðrar skaparar við perfektum sikti.", + "annual_report.summary.archetype.booster.desc_self": "Tú helt fram at veiða postar at lyfta, og styrkti aðrar skaparar við perfektum sikti.", + "annual_report.summary.archetype.booster.name": "Bogaskjúttin", + "annual_report.summary.archetype.die_drei_fragezeichen": "???", + "annual_report.summary.archetype.lurker.desc_public": "Vit vita, at {name} var úti har onkustaðni og neyt Mastodon uppá sín egna stilla máta.", + "annual_report.summary.archetype.lurker.desc_self": "Vit vita, at tú var úti har onkustaðni og neyt Mastodon uppá tín egna stilla máta.", + "annual_report.summary.archetype.lurker.name": "Stóikarin", + "annual_report.summary.archetype.oracle.desc_public": "{name} gjørdi fleiri nýggjar postar enn svar og helt Mastodon feskt og framtíðarrættað.", + "annual_report.summary.archetype.oracle.desc_self": "Tú gjørdi fleiri nýggjar postar enn svar og helt Mastodon feskt og framtíðarrættað.", + "annual_report.summary.archetype.oracle.name": "Oraklið", + "annual_report.summary.archetype.pollster.desc_public": "{name} stovnaði fleiri atkvøðugreiðslur enn onnur sløg av postum og dyrkaði forvitni á Mastodon.", + "annual_report.summary.archetype.pollster.desc_self": "Tú stovnaði fleiri atkvøðugreiðslur enn onnur sløg av postum og dyrkaði forvitni á Mastodon.", + "annual_report.summary.archetype.pollster.name": "Undrandi", + "annual_report.summary.archetype.replier.desc_public": "{name} svaraði ofta til postar hjá øðrum og ríkaði Mastodon við nýggjum kjaki.", + "annual_report.summary.archetype.replier.desc_self": "Tú svaraði ofta til postar hjá øðrum og ríkaði Mastodon við nýggjum kjaki.", + "annual_report.summary.archetype.replier.name": "Firvaldurin", + "annual_report.summary.archetype.reveal": "Avdúka mítt frumsnið", + "annual_report.summary.archetype.reveal_description": "Takk fyri at tú er partur av Mastodon! Nú er tíðin komin at finna útav hvat frumsnið tú fall inn í í {year}.", + "annual_report.summary.archetype.title_public": "Frumsniðið hjá {name}", + "annual_report.summary.archetype.title_self": "Títt frumsnið", + "annual_report.summary.close": "Lat aftur", + "annual_report.summary.copy_link": "Avrita leinki", + "annual_report.summary.followers.new_followers": "{count, plural, one {{counter} nýggjur fylgjari} other {{counter} nýggir fylgjarar}}", + "annual_report.summary.highlighted_post.boost_count": "Hesin posturin var lyftur {count, plural, one {eina ferð} other {# ferðir}}.", + "annual_report.summary.highlighted_post.favourite_count": "Hesin posturin var yndismerktur {count, plural, one {eina ferð} other {# ferðir}}.", + "annual_report.summary.highlighted_post.reply_count": "Hesin posturin fekk {count, plural, one {eitt svar} other {# svar}}.", + "annual_report.summary.highlighted_post.title": "Best umtókti postur", "annual_report.summary.most_used_app.most_used_app": "mest brúkta app", "annual_report.summary.most_used_hashtag.most_used_hashtag": "mest brúkta frámerki", - "annual_report.summary.most_used_hashtag.none": "Einki", + "annual_report.summary.most_used_hashtag.used_count": "Tú brúkti hetta frámerkið í {count, plural, one {einum posti} other {# postum}}.", + "annual_report.summary.most_used_hashtag.used_count_public": "{name} brúkti hetta frámerkið í {count, plural, one {einum posti} other {# postum}}.", "annual_report.summary.new_posts.new_posts": "nýggir postar", "annual_report.summary.percentile.text": "Tað fær teg í toppav {domain} brúkarum.", "annual_report.summary.percentile.we_wont_tell_bernie": "Vit fara ikki at fortelja Bernie tað.", + "annual_report.summary.share_elsewhere": "Deil aðrastaðni", "annual_report.summary.share_message": "Eg fekk {archetype} frumsniðið!", - "annual_report.summary.thanks": "Takk fyri at tú er partur av Mastodon!", + "annual_report.summary.share_on_mastodon": "Deil á Mastodon", "attachments_list.unprocessed": "(óviðgjørt)", "audio.hide": "Fjal ljóð", "block_modal.remote_users_caveat": "Vit biðja ambætaran {domain} virða tína avgerð. Kortini er eingin vissa um samsvar, av tí at fleiri ambætarar handfara blokkar ymiskt. Almennir postar kunnu framvegis vera sjónligir fyri brúkarar, sum ikki eru innritaðir.", @@ -419,6 +441,8 @@ "follow_suggestions.who_to_follow": "Hvørji tú átti at fylgt", "followed_tags": "Fylgd frámerki", "footer.about": "Um", + "footer.about_mastodon": "Um Mastodon", + "footer.about_server": "Um {domain}", "footer.about_this_server": "Um", "footer.directory": "Vangaskrá", "footer.get_app": "Heinta appina", diff --git a/app/javascript/mastodon/locales/fr-CA.json b/app/javascript/mastodon/locales/fr-CA.json index 1975ce0c89e49a..95b8efe078ba78 100644 --- a/app/javascript/mastodon/locales/fr-CA.json +++ b/app/javascript/mastodon/locales/fr-CA.json @@ -114,29 +114,51 @@ "alt_text_modal.done": "Terminé", "announcement.announcement": "Annonce", "annual_report.announcement.action_build": "Générer mon Wrapstodon", + "annual_report.announcement.action_dismiss": "Non merci", "annual_report.announcement.action_view": "Voir mon Wrapstodon", "annual_report.announcement.description": "En découvrir plus concernant votre activité sur Mastodon pour l'année écoulée.", "annual_report.announcement.title": "Le Wrapstodon {year} est arrivé", - "annual_report.summary.archetype.booster": "Le chasseur de sang-froid", - "annual_report.summary.archetype.lurker": "Le faucheur", - "annual_report.summary.archetype.oracle": "L’oracle", - "annual_report.summary.archetype.pollster": "Le sondeur", - "annual_report.summary.archetype.replier": "Le papillon social", - "annual_report.summary.followers.followers": "abonné·e·s", - "annual_report.summary.followers.total": "{count} au total", - "annual_report.summary.here_it_is": "Voici votre récap de {year} :", - "annual_report.summary.highlighted_post.by_favourites": "post le plus aimé", - "annual_report.summary.highlighted_post.by_reblogs": "post le plus boosté", - "annual_report.summary.highlighted_post.by_replies": "post avec le plus de réponses", - "annual_report.summary.highlighted_post.possessive": "{name}'s", + "annual_report.nav_item.badge": "Nouveau", + "annual_report.shared_page.donate": "Faire un don", + "annual_report.shared_page.footer": "Généré avec {heart} par l'équipe de Mastodon", + "annual_report.shared_page.footer_server_info": "{username} utilise {domain}, l'une des nombreuses communautés propulsées par Mastodon.", + "annual_report.summary.archetype.booster.desc_public": "{name} fut à l’affût des messages à partager, ciblant avec perfection les créatrices et créateurs à amplifier.", + "annual_report.summary.archetype.booster.desc_self": "Vous avez été à l'affût des messages à partager, ciblant avec perfection les créatrices et créateurs à amplifier.", + "annual_report.summary.archetype.booster.name": "Archer, archère", + "annual_report.summary.archetype.die_drei_fragezeichen": "???", + "annual_report.summary.archetype.lurker.desc_public": "Nous savons que {name} a été là, quelque part, profitant calmement de Mastodon à sa manière.", + "annual_report.summary.archetype.lurker.desc_self": "Nous savons que vous avez été là, quelque part, profitant calmement de Mastodon à votre manière.", + "annual_report.summary.archetype.lurker.name": "Stoïque", + "annual_report.summary.archetype.oracle.desc_public": "{name} publia plus de nouveaux messages que de réponses, contribuant à garder Mastodon frais et tourné vers l'avenir.", + "annual_report.summary.archetype.oracle.desc_self": "Vous avez publié plus de nouveaux messages que de réponses, contribuant à garder Mastodon frais et tourné vers l'avenir.", + "annual_report.summary.archetype.oracle.name": "Oracle", + "annual_report.summary.archetype.pollster.desc_public": "{name} publia plus de sondages que n'importe quel autre type de message, cultivant la curiosité sur Mastodon.", + "annual_report.summary.archetype.pollster.desc_self": "Vous avez publié plus de sondages que n'importe quel autre type de message, cultivant la curiosité sur Mastodon.", + "annual_report.summary.archetype.pollster.name": "Curieux, curieuse", + "annual_report.summary.archetype.replier.desc_public": "{name} répliqua fréquemment aux messages des autres, pollinisant Mastodon de nouvelles discussions.", + "annual_report.summary.archetype.replier.desc_self": "Vous avez fréquemment répliqué aux messages des autres, pollinisant Mastodon de nouvelles discussions.", + "annual_report.summary.archetype.replier.name": "Papillon", + "annual_report.summary.archetype.reveal": "Révéler mon archétype", + "annual_report.summary.archetype.reveal_description": "Merci de faire partie de Mastodon ! Il est temps de découvrir quel archétype vous avez incarné en {year}.", + "annual_report.summary.archetype.title_public": "L'archétype de {name}", + "annual_report.summary.archetype.title_self": "Votre archétype", + "annual_report.summary.close": "Fermer", + "annual_report.summary.copy_link": "Copier le lien", + "annual_report.summary.followers.new_followers": "{count, plural, one {nouvel·le abonné·e} other {nouveaux abonné·e·s}}", + "annual_report.summary.highlighted_post.boost_count": "Ce message a été partagé {count, plural, one {une fois} other {# fois}}.", + "annual_report.summary.highlighted_post.favourite_count": "Ce message a été mis en favoris {count, plural, one {une fois} other {# fois}}.", + "annual_report.summary.highlighted_post.reply_count": "Ce message a reçu {count, plural, one {une réponse} other {# réponses}}.", + "annual_report.summary.highlighted_post.title": "Message le plus populaire", "annual_report.summary.most_used_app.most_used_app": "appli la plus utilisée", "annual_report.summary.most_used_hashtag.most_used_hashtag": "hashtag le plus utilisé", - "annual_report.summary.most_used_hashtag.none": "Aucun", + "annual_report.summary.most_used_hashtag.used_count": "Vous avez utilisé ce hashtag dans {count, plural, one {un message} other {# messages}}.", + "annual_report.summary.most_used_hashtag.used_count_public": "{name} a inclus ce hashtag dans {count, plural, one {un message} other {# messages}}.", "annual_report.summary.new_posts.new_posts": "nouveaux messages", "annual_report.summary.percentile.text": "Cela vous place dans le topdes utilisateurs de {domain}.", "annual_report.summary.percentile.we_wont_tell_bernie": "Nous ne le dirons pas à Bernie.", + "annual_report.summary.share_elsewhere": "Partager ailleurs", "annual_report.summary.share_message": "J’ai obtenu l’archétype {archetype} !", - "annual_report.summary.thanks": "Merci de faire partie de Mastodon!", + "annual_report.summary.share_on_mastodon": "Partager sur Mastodon", "attachments_list.unprocessed": "(non traité)", "audio.hide": "Masquer l'audio", "block_modal.remote_users_caveat": "Nous allons demander au serveur {domain} de respecter votre décision. Cependant, ce respect n'est pas garanti, car certains serveurs peuvent gérer différemment les blocages. Les messages publics peuvent rester visibles par les utilisateur·rice·s non connecté·e·s.", @@ -419,6 +441,8 @@ "follow_suggestions.who_to_follow": "Qui suivre", "followed_tags": "Hashtags suivis", "footer.about": "À propos", + "footer.about_mastodon": "À propos de Mastodon", + "footer.about_server": "À propos de {domain}", "footer.about_this_server": "À propos", "footer.directory": "Annuaire des profils", "footer.get_app": "Télécharger l’application", diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json index 2ad548d9a4a035..2ef5c9acb40b17 100644 --- a/app/javascript/mastodon/locales/fr.json +++ b/app/javascript/mastodon/locales/fr.json @@ -114,29 +114,51 @@ "alt_text_modal.done": "Terminé", "announcement.announcement": "Annonce", "annual_report.announcement.action_build": "Générer mon Wrapstodon", + "annual_report.announcement.action_dismiss": "Non merci", "annual_report.announcement.action_view": "Voir mon Wrapstodon", "annual_report.announcement.description": "En découvrir plus concernant votre activité sur Mastodon pour l'année écoulée.", "annual_report.announcement.title": "Le Wrapstodon {year} est arrivé", - "annual_report.summary.archetype.booster": "Le chasseur de sang-froid", - "annual_report.summary.archetype.lurker": "Le faucheur", - "annual_report.summary.archetype.oracle": "L’oracle", - "annual_report.summary.archetype.pollster": "Le sondeur", - "annual_report.summary.archetype.replier": "Le papillon social", - "annual_report.summary.followers.followers": "abonné·e·s", - "annual_report.summary.followers.total": "{count} au total", - "annual_report.summary.here_it_is": "Voici votre récap de {year} :", - "annual_report.summary.highlighted_post.by_favourites": "post le plus aimé", - "annual_report.summary.highlighted_post.by_reblogs": "post le plus boosté", - "annual_report.summary.highlighted_post.by_replies": "post avec le plus de réponses", - "annual_report.summary.highlighted_post.possessive": "{name}'s", + "annual_report.nav_item.badge": "Nouveau", + "annual_report.shared_page.donate": "Faire un don", + "annual_report.shared_page.footer": "Généré avec {heart} par l'équipe de Mastodon", + "annual_report.shared_page.footer_server_info": "{username} utilise {domain}, l'une des nombreuses communautés propulsées par Mastodon.", + "annual_report.summary.archetype.booster.desc_public": "{name} fut à l’affût des messages à partager, ciblant avec perfection les créatrices et créateurs à amplifier.", + "annual_report.summary.archetype.booster.desc_self": "Vous avez été à l'affût des messages à partager, ciblant avec perfection les créatrices et créateurs à amplifier.", + "annual_report.summary.archetype.booster.name": "Archer, archère", + "annual_report.summary.archetype.die_drei_fragezeichen": "???", + "annual_report.summary.archetype.lurker.desc_public": "Nous savons que {name} a été là, quelque part, profitant calmement de Mastodon à sa manière.", + "annual_report.summary.archetype.lurker.desc_self": "Nous savons que vous avez été là, quelque part, profitant calmement de Mastodon à votre manière.", + "annual_report.summary.archetype.lurker.name": "Stoïque", + "annual_report.summary.archetype.oracle.desc_public": "{name} publia plus de nouveaux messages que de réponses, contribuant à garder Mastodon frais et tourné vers l'avenir.", + "annual_report.summary.archetype.oracle.desc_self": "Vous avez publié plus de nouveaux messages que de réponses, contribuant à garder Mastodon frais et tourné vers l'avenir.", + "annual_report.summary.archetype.oracle.name": "Oracle", + "annual_report.summary.archetype.pollster.desc_public": "{name} publia plus de sondages que n'importe quel autre type de message, cultivant la curiosité sur Mastodon.", + "annual_report.summary.archetype.pollster.desc_self": "Vous avez publié plus de sondages que n'importe quel autre type de message, cultivant la curiosité sur Mastodon.", + "annual_report.summary.archetype.pollster.name": "Curieux, curieuse", + "annual_report.summary.archetype.replier.desc_public": "{name} répliqua fréquemment aux messages des autres, pollinisant Mastodon de nouvelles discussions.", + "annual_report.summary.archetype.replier.desc_self": "Vous avez fréquemment répliqué aux messages des autres, pollinisant Mastodon de nouvelles discussions.", + "annual_report.summary.archetype.replier.name": "Papillon", + "annual_report.summary.archetype.reveal": "Révéler mon archétype", + "annual_report.summary.archetype.reveal_description": "Merci de faire partie de Mastodon ! Il est temps de découvrir quel archétype vous avez incarné en {year}.", + "annual_report.summary.archetype.title_public": "L'archétype de {name}", + "annual_report.summary.archetype.title_self": "Votre archétype", + "annual_report.summary.close": "Fermer", + "annual_report.summary.copy_link": "Copier le lien", + "annual_report.summary.followers.new_followers": "{count, plural, one {nouvel·le abonné·e} other {nouveaux abonné·e·s}}", + "annual_report.summary.highlighted_post.boost_count": "Ce message a été partagé {count, plural, one {une fois} other {# fois}}.", + "annual_report.summary.highlighted_post.favourite_count": "Ce message a été mis en favoris {count, plural, one {une fois} other {# fois}}.", + "annual_report.summary.highlighted_post.reply_count": "Ce message a reçu {count, plural, one {une réponse} other {# réponses}}.", + "annual_report.summary.highlighted_post.title": "Message le plus populaire", "annual_report.summary.most_used_app.most_used_app": "appli la plus utilisée", "annual_report.summary.most_used_hashtag.most_used_hashtag": "hashtag le plus utilisé", - "annual_report.summary.most_used_hashtag.none": "Aucun", + "annual_report.summary.most_used_hashtag.used_count": "Vous avez utilisé ce hashtag dans {count, plural, one {un message} other {# messages}}.", + "annual_report.summary.most_used_hashtag.used_count_public": "{name} a inclus ce hashtag dans {count, plural, one {un message} other {# messages}}.", "annual_report.summary.new_posts.new_posts": "nouveaux messages", "annual_report.summary.percentile.text": "Cela vous place dans le topdes utilisateurs de {domain}.", "annual_report.summary.percentile.we_wont_tell_bernie": "Nous ne le dirons pas à Bernie.", + "annual_report.summary.share_elsewhere": "Partager ailleurs", "annual_report.summary.share_message": "J’ai obtenu l’archétype {archetype} !", - "annual_report.summary.thanks": "Merci de faire partie de Mastodon!", + "annual_report.summary.share_on_mastodon": "Partager sur Mastodon", "attachments_list.unprocessed": "(non traité)", "audio.hide": "Masquer l'audio", "block_modal.remote_users_caveat": "Nous allons demander au serveur {domain} de respecter votre décision. Cependant, ce respect n'est pas garanti, car certains serveurs peuvent gérer différemment les blocages. Les messages publics peuvent rester visibles par les utilisateur·rice·s non connecté·e·s.", @@ -419,6 +441,8 @@ "follow_suggestions.who_to_follow": "Qui suivre", "followed_tags": "Hashtags suivis", "footer.about": "À propos", + "footer.about_mastodon": "À propos de Mastodon", + "footer.about_server": "À propos de {domain}", "footer.about_this_server": "À propos", "footer.directory": "Annuaire des profils", "footer.get_app": "Télécharger l’application", diff --git a/app/javascript/mastodon/locales/fy.json b/app/javascript/mastodon/locales/fy.json index e460b29de0349b..2a98f2978218b2 100644 --- a/app/javascript/mastodon/locales/fy.json +++ b/app/javascript/mastodon/locales/fy.json @@ -107,25 +107,11 @@ "alt_text_modal.describe_for_people_with_visual_impairments": "Beskriuw dit foar blinen en fisueel beheinde…", "alt_text_modal.done": "Klear", "announcement.announcement": "Oankundiging", - "annual_report.summary.archetype.booster": "De cool-hunter", - "annual_report.summary.archetype.lurker": "De lurker", - "annual_report.summary.archetype.oracle": "It orakel", - "annual_report.summary.archetype.pollster": "De opinypeiler", - "annual_report.summary.archetype.replier": "De sosjale flinter", - "annual_report.summary.followers.followers": "folgers", - "annual_report.summary.followers.total": "totaal {count}", - "annual_report.summary.here_it_is": "Jo jieroersjoch foar {year}:", - "annual_report.summary.highlighted_post.by_favourites": "berjocht mei de measte favoriten", - "annual_report.summary.highlighted_post.by_reblogs": "berjocht mei de measte boosts", - "annual_report.summary.highlighted_post.by_replies": "berjocht mei de measte reaksjes", - "annual_report.summary.highlighted_post.possessive": "{name}’s", "annual_report.summary.most_used_app.most_used_app": "meast brûkte app", "annual_report.summary.most_used_hashtag.most_used_hashtag": "meast brûkte hashtag", - "annual_report.summary.most_used_hashtag.none": "Gjin", "annual_report.summary.new_posts.new_posts": "nije berjochten", "annual_report.summary.percentile.text": "Hjirmei hearre jo ta de top fan {domain}.", "annual_report.summary.percentile.we_wont_tell_bernie": "Wy sille Bernie neat fertelle.", - "annual_report.summary.thanks": "Tank dat jo part binne fan Mastodon!", "attachments_list.unprocessed": "(net ferwurke)", "audio.hide": "Audio ferstopje", "block_modal.remote_users_caveat": "Wy freegje de server {domain} om jo beslút te respektearjen. It neilibben hjirfan is echter net garandearre, omdat guon servers blokkaden oars ynterpretearje kinne. Iepenbiere berjochten binne mooglik noch hieltyd sichtber foar net-oanmelde brûkers.", diff --git a/app/javascript/mastodon/locales/ga.json b/app/javascript/mastodon/locales/ga.json index 7172aaacf5794f..489616943be056 100644 --- a/app/javascript/mastodon/locales/ga.json +++ b/app/javascript/mastodon/locales/ga.json @@ -114,29 +114,50 @@ "alt_text_modal.done": "Déanta", "announcement.announcement": "Fógra", "annual_report.announcement.action_build": "Tóg mo Wrapstodon", + "annual_report.announcement.action_dismiss": "Ní raibh maith agat", "annual_report.announcement.action_view": "Féach ar mo Wrapstodon", "annual_report.announcement.description": "Faigh tuilleadh eolais faoi do rannpháirtíocht ar Mastodon le bliain anuas.", "annual_report.announcement.title": "Tá Wrapstodon {year} tagtha", - "annual_report.summary.archetype.booster": "An sealgair fionnuar", - "annual_report.summary.archetype.lurker": "An lurker", - "annual_report.summary.archetype.oracle": "An oracal", - "annual_report.summary.archetype.pollster": "An pollaire", - "annual_report.summary.archetype.replier": "An féileacán sóisialta", - "annual_report.summary.followers.followers": "leanúna", - "annual_report.summary.followers.total": "{count} san iomlán", - "annual_report.summary.here_it_is": "Seo do {year} faoi athbhreithniú:", - "annual_report.summary.highlighted_post.by_favourites": "post is fearr leat", - "annual_report.summary.highlighted_post.by_reblogs": "post is treisithe", - "annual_report.summary.highlighted_post.by_replies": "post leis an líon is mó freagraí", - "annual_report.summary.highlighted_post.possessive": "{name}'s", + "annual_report.nav_item.badge": "Nua", + "annual_report.shared_page.donate": "Tabhair Síntiús", + "annual_report.shared_page.footer": "Gineadh le {heart} ag foireann Mastodon", + "annual_report.summary.archetype.booster.desc_public": "D’fhan {name} ag cuardach postálacha le cur chun cinn, ag cur le cruthaitheoirí eile le cuspóir foirfe.", + "annual_report.summary.archetype.booster.desc_self": "D’fhan tú ag cuardach postálacha le borradh a chur fúthu, ag cur le cruthaitheoirí eile le cuspóir foirfe.", + "annual_report.summary.archetype.booster.name": "An Saighdeoir", + "annual_report.summary.archetype.die_drei_fragezeichen": "???", + "annual_report.summary.archetype.lurker.desc_public": "Tá a fhios againn go raibh {name} amuigh ansin, áit éigin, ag baint taitnimh as Mastodon ar a mbealach ciúin féin.", + "annual_report.summary.archetype.lurker.desc_self": "Tá a fhios againn go raibh tú amuigh ansin, áit éigin, ag baint taitnimh as Mastodon ar do bhealach ciúin féin.", + "annual_report.summary.archetype.lurker.name": "An Stoiceach", + "annual_report.summary.archetype.oracle.desc_public": "Chruthaigh {name} níos mó postálacha nua ná freagraí, rud a choinnigh Mastodon úr agus dírithe ar an todhchaí.", + "annual_report.summary.archetype.oracle.desc_self": "Chruthaigh tú níos mó postálacha nua ná freagraí, rud a choinnigh Mastodon úr agus dírithe ar an todhchaí.", + "annual_report.summary.archetype.oracle.name": "An tOracal", + "annual_report.summary.archetype.pollster.desc_public": "Chruthaigh {name} níos mó pobalbhreitheanna ná cineálacha poist eile, rud a chothaigh fiosracht faoi Mastodon.", + "annual_report.summary.archetype.pollster.desc_self": "Chruthaigh tú níos mó pobalbhreitheanna ná cineálacha poist eile, rud a chothaigh fiosracht ar Mastodon.", + "annual_report.summary.archetype.pollster.name": "An tIontasóir", + "annual_report.summary.archetype.replier.desc_public": "Is minic a d’fhreagair {name} poist daoine eile, rud a spreag plé nua i Mastodon.", + "annual_report.summary.archetype.replier.desc_self": "Is minic a d’fhreagair tú poist daoine eile, ag maolú Mastodon le plé nua.", + "annual_report.summary.archetype.replier.name": "An Féileacán", + "annual_report.summary.archetype.reveal": "Nocht mo sheandálaíocht", + "annual_report.summary.archetype.reveal_description": "Go raibh maith agat as bheith mar chuid de Mastodon! Tá sé in am a fháil amach cén t-archetíopa a léirigh tú i {year}.", + "annual_report.summary.archetype.title_public": "Seanchineál {name}", + "annual_report.summary.archetype.title_self": "Do sheandálaíocht", + "annual_report.summary.close": "Dún", + "annual_report.summary.copy_link": "Cóipeáil nasc", + "annual_report.summary.followers.new_followers": "{count, plural, one {leantóir nua} two {leantóirí nua} few {leantóirí nua} many {leantóirí nua} other {leantóirí nua}}", + "annual_report.summary.highlighted_post.boost_count": "Borradh a tugadh faoin bpost seo {count, plural, one {uair amháin} two {# uaire} few {# uaire} many {# uaire} other {# uaire}}.", + "annual_report.summary.highlighted_post.favourite_count": "Cuireadh an post seo leis na ceanáin {count, plural, one {uair amháin} two {# uaire} few {# uaire} many {# uaire} other {# uaire}}.", + "annual_report.summary.highlighted_post.reply_count": "Fuair ​​an post seo {count, plural, one {freagra amháin} two {# freagraí} few {# freagraí} many {# freagraí} other {# freagraí}}.", + "annual_report.summary.highlighted_post.title": "An post is mó tóir", "annual_report.summary.most_used_app.most_used_app": "aip is mó a úsáidtear", "annual_report.summary.most_used_hashtag.most_used_hashtag": "hashtag is mó a úsáidtear", - "annual_report.summary.most_used_hashtag.none": "Dada", + "annual_report.summary.most_used_hashtag.used_count": "Chuir tú an haischlib seo i {count, plural, one {post amháin} two {# poist} few {# poist} many {# poist} other {# poist}}.", + "annual_report.summary.most_used_hashtag.used_count_public": "Chuir {name} an haischlib seo i {count, plural, one {post amháin} two {# poist} few {# poist} many {# poist} other {# poist}}.", "annual_report.summary.new_posts.new_posts": "postanna nua", "annual_report.summary.percentile.text": "Cuireann sé sin i mbarr úsáideoirí {domain}. thú", "annual_report.summary.percentile.we_wont_tell_bernie": "Ní inseoidh muid do Bernie.", + "annual_report.summary.share_elsewhere": "Roinn in áit eile", "annual_report.summary.share_message": "Fuair ​​mé an t-archetíopa {archetype}!", - "annual_report.summary.thanks": "Go raibh maith agat as a bheith mar chuid de Mastodon!", + "annual_report.summary.share_on_mastodon": "Comhroinn ar Mastodon", "attachments_list.unprocessed": "(neamhphróiseáilte)", "audio.hide": "Cuir fuaim i bhfolach", "block_modal.remote_users_caveat": "Iarrfaimid ar an bhfreastalaí {domain} meas a bheith agat ar do chinneadh. Mar sin féin, ní ráthaítear comhlíonadh toisc go bhféadfadh roinnt freastalaithe bloic a láimhseáil ar bhealach difriúil. Seans go mbeidh postálacha poiblí fós le feiceáil ag úsáideoirí nach bhfuil logáilte isteach.", @@ -248,7 +269,7 @@ "confirmations.follow_to_list.title": "Lean an t-úsáideoir?", "confirmations.logout.confirm": "Logáil amach", "confirmations.logout.message": "An bhfuil tú cinnte gur mhaith leat logáil amach?", - "confirmations.logout.title": "Logáil Amach?", + "confirmations.logout.title": "Logáil amach?", "confirmations.missing_alt_text.confirm": "Cuir téacs alt leis", "confirmations.missing_alt_text.message": "Tá meáin gan alt téacs i do phostáil. Má chuirtear tuairiscí leis, cabhraíonn sé seo leat d’inneachar a rochtain do níos mó daoine.", "confirmations.missing_alt_text.secondary": "Post ar aon nós", @@ -456,7 +477,7 @@ "hints.profiles.see_more_followers": "Féach ar a thuilleadh leantóirí ar {domain}", "hints.profiles.see_more_follows": "Féach tuilleadh seo a leanas ar {domain}", "hints.profiles.see_more_posts": "Féach ar a thuilleadh postálacha ar {domain}", - "home.column_settings.show_quotes": "Taispeáin Sleachta", + "home.column_settings.show_quotes": "Taispeáin sleachta", "home.column_settings.show_reblogs": "Taispeáin moltaí", "home.column_settings.show_replies": "Taispeán freagraí", "home.hide_announcements": "Cuir fógraí i bhfolach", @@ -686,7 +707,7 @@ "notifications.column_settings.mention": "Tráchtanna:", "notifications.column_settings.poll": "Torthaí suirbhéanna:", "notifications.column_settings.push": "Brúfhógraí", - "notifications.column_settings.quote": "Luachain:", + "notifications.column_settings.quote": "Sleachta:", "notifications.column_settings.reblog": "Moltaí:", "notifications.column_settings.show": "Taispeáin i gcolún", "notifications.column_settings.sound": "Seinn an fhuaim", @@ -763,14 +784,14 @@ "privacy.public.long": "Duine ar bith ar agus amach Mastodon", "privacy.public.short": "Poiblí", "privacy.quote.anyone": "{visibility}, is féidir le duine ar bith lua", - "privacy.quote.disabled": "{visibility}, comharthaí athfhriotail díchumasaithe", - "privacy.quote.limited": "{visibility}, luachana teoranta", + "privacy.quote.disabled": "{visibility}, sleachta díchumasaithe", + "privacy.quote.limited": "{visibility}, sleachta teoranta", "privacy.unlisted.additional": "Iompraíonn sé seo díreach mar a bheadh ​​poiblí, ach amháin ní bheidh an postáil le feiceáil i bhfothaí beo nó i hashtags, in iniúchadh nó i gcuardach Mastodon, fiú má tá tú liostáilte ar fud an chuntais.", "privacy.unlisted.long": "I bhfolach ó thorthaí cuardaigh Mastodon, treochtaí, agus amlínte poiblí", "privacy.unlisted.short": "Poiblí ciúin", "privacy_policy.last_updated": "Nuashonraithe {date}", "privacy_policy.title": "Polasaí príobháideachais", - "quote_error.edit": "Ní féidir Sleachta a chur leis agus post á chur in eagar.", + "quote_error.edit": "Ní féidir sleachta a chur leis agus post á chur in eagar.", "quote_error.poll": "Ní cheadaítear lua le pobalbhreitheanna.", "quote_error.private_mentions": "Ní cheadaítear lua le tagairtí díreacha.", "quote_error.quote": "Ní cheadaítear ach luachan amháin ag an am.", @@ -885,7 +906,7 @@ "status.admin_account": "Oscail comhéadan modhnóireachta do @{name}", "status.admin_domain": "Oscail comhéadan modhnóireachta le haghaidh {domain}", "status.admin_status": "Oscail an postáil seo sa chomhéadan modhnóireachta", - "status.all_disabled": "Tá borradh agus luachana díchumasaithe", + "status.all_disabled": "Tá treisiúcháin agus sleachta díchumasaithe", "status.block": "Bac @{name}", "status.bookmark": "Leabharmharcanna", "status.cancel_reblog_private": "Dímhol", @@ -945,7 +966,7 @@ "status.quotes.empty": "Níl an post seo luaite ag aon duine go fóill. Nuair a dhéanann duine é, taispeánfar anseo é.", "status.quotes.local_other_disclaimer": "Ní thaispeánfar sleachta ar dhiúltaigh an t-údar dóibh.", "status.quotes.remote_other_disclaimer": "Níl ráthaíocht ann go dtaispeánfar anseo ach sleachta ó {domain}. Ní thaispeánfar sleachta ar dhiúltaigh an t-údar dóibh.", - "status.quotes_count": "{count, plural,\n one {{counter} athfhriotal}\n two {{counter} athfhriotail}\n few {{counter} athfhriotail}\n many {{counter} athfhriotal}\n other {{counter} athfhriotail}\n}", + "status.quotes_count": "{count, plural, one {{counter} sleacht} two {{counter} sleachta} few {{counter} sleachta} many {{counter} sleachta} other {{counter} sleachta}}", "status.read_more": "Léan a thuilleadh", "status.reblog": "Treisiú", "status.reblog_or_quote": "Borradh nó luachan", @@ -1001,7 +1022,7 @@ "upload_button.label": "Cuir íomhánna, físeán nó comhad fuaime leis", "upload_error.limit": "Sáraíodh an teorainn uaslódála comhaid.", "upload_error.poll": "Ní cheadaítear uaslódáil comhad le pobalbhreith.", - "upload_error.quote": "Ní cheadaítear uaslódáil comhaid le comharthaí athfhriotail.", + "upload_error.quote": "Ní cheadaítear uaslódáil comhaid le sleachta.", "upload_form.drag_and_drop.instructions": "Chun ceangaltán meán a phiocadh suas, brúigh spás nó cuir isteach. Agus tú ag tarraingt, bain úsáid as na heochracha saigheada chun an ceangaltán meán a bhogadh i dtreo ar bith. Brúigh spás nó cuir isteach arís chun an ceangaltán meán a scaoileadh ina phost nua, nó brúigh éalú chun cealú.", "upload_form.drag_and_drop.on_drag_cancel": "Cuireadh an tarraingt ar ceal. Scaoileadh ceangaltán meán {item}.", "upload_form.drag_and_drop.on_drag_end": "Scaoileadh ceangaltán meán {item}.", @@ -1027,11 +1048,11 @@ "video.volume_up": "Toirt suas", "visibility_modal.button_title": "Socraigh infheictheacht", "visibility_modal.direct_quote_warning.text": "Má shábhálann tú na socruithe reatha, déanfar an luachan leabaithe a thiontú ina nasc.", - "visibility_modal.direct_quote_warning.title": "Ní féidir luachana a leabú i luanna príobháideacha", + "visibility_modal.direct_quote_warning.title": "Ní féidir sleachta a leabú i dtráchtanna príobháideacha", "visibility_modal.header": "Infheictheacht agus idirghníomhaíocht", "visibility_modal.helper.direct_quoting": "Ní féidir le daoine eile tráchtanna príobháideacha a scríobhadh ar Mastodon a lua.", "visibility_modal.helper.privacy_editing": "Ní féidir infheictheacht a athrú tar éis post a fhoilsiú.", - "visibility_modal.helper.privacy_private_self_quote": "Ní féidir féin-luachanna ó phoist phríobháideacha a chur ar fáil don phobal.", + "visibility_modal.helper.privacy_private_self_quote": "Ní féidir féin-sleachta ó phoist phríobháideacha a chur ar fáil don phobal.", "visibility_modal.helper.private_quoting": "Ní féidir le daoine eile poist atá scríofa ar Mastodon agus atá dírithe ar leanúna amháin a lua.", "visibility_modal.helper.unlisted_quoting": "Nuair a luann daoine thú, beidh a bpost i bhfolach ó amlínte treochta freisin.", "visibility_modal.instructions": "Rialaigh cé a fhéadfaidh idirghníomhú leis an bpost seo. Is féidir leat socruithe a chur i bhfeidhm ar gach post amach anseo trí nascleanúint a dhéanamh chuig Sainroghanna > Réamhshocruithe Postála.", diff --git a/app/javascript/mastodon/locales/gd.json b/app/javascript/mastodon/locales/gd.json index e24a7d4608fdc4..16ce197f3f738c 100644 --- a/app/javascript/mastodon/locales/gd.json +++ b/app/javascript/mastodon/locales/gd.json @@ -113,25 +113,11 @@ "alt_text_modal.describe_for_people_with_visual_impairments": "Mìnich seo dhan fheadhainn air a bheil cion-lèirsinne…", "alt_text_modal.done": "Deiseil", "announcement.announcement": "Brath-fios", - "annual_report.summary.archetype.booster": "Brosnaiche", - "annual_report.summary.archetype.lurker": "Eala-bhalbh", - "annual_report.summary.archetype.oracle": "Coinneach Odhar", - "annual_report.summary.archetype.pollster": "Cunntair nam beachd", - "annual_report.summary.archetype.replier": "Ceatharnach nam freagairt", - "annual_report.summary.followers.followers": "luchd-leantainn", - "annual_report.summary.followers.total": "{count} gu h-iomlan", - "annual_report.summary.here_it_is": "Seo mar a chaidh {year} leat:", - "annual_report.summary.highlighted_post.by_favourites": "am post as annsa", - "annual_report.summary.highlighted_post.by_reblogs": "am post air a bhrosnachadh as trice", - "annual_report.summary.highlighted_post.by_replies": "am post dhan deach fhreagairt as trice", - "annual_report.summary.highlighted_post.possessive": "Aig {name},", "annual_report.summary.most_used_app.most_used_app": "an aplacaid a chaidh a cleachdadh as trice", "annual_report.summary.most_used_hashtag.most_used_hashtag": "an taga hais a chaidh a cleachdadh as trice", - "annual_report.summary.most_used_hashtag.none": "Chan eil gin", "annual_report.summary.new_posts.new_posts": "postaichean ùra", "annual_report.summary.percentile.text": "Tha thu am measgdhen luchd-cleachdaidh as cliùitiche air {domain}.", "annual_report.summary.percentile.we_wont_tell_bernie": "Ainmeil ’nad latha ’s ’nad linn.", - "annual_report.summary.thanks": "Mòran taing airson conaltradh air Mastodon!", "attachments_list.unprocessed": "(gun phròiseasadh)", "audio.hide": "Falaich an fhuaim", "block_modal.remote_users_caveat": "Iarraidh sinn air an fhrithealaiche {domain} gun gèill iad ri do cho-dhùnadh. Gidheadh, chan eil barantas gun gèill iad on a làimhsicheas cuid a fhrithealaichean bacaidhean air dòigh eadar-dhealaichte. Dh’fhaoidte gum faic daoine gun chlàradh a-steach na postaichean poblach agad fhathast.", diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json index dad94113a9323a..b68b33b4ec2fa6 100644 --- a/app/javascript/mastodon/locales/gl.json +++ b/app/javascript/mastodon/locales/gl.json @@ -114,29 +114,50 @@ "alt_text_modal.done": "Feito", "announcement.announcement": "Anuncio", "annual_report.announcement.action_build": "Crear o meu Wrapstodon", + "annual_report.announcement.action_dismiss": "Non, grazas", "annual_report.announcement.action_view": "Ver o meu Wrapstodon", "annual_report.announcement.description": "Olla o que andiveches facendo en Mastodon durante o último ano.", "annual_report.announcement.title": "Chegou o Wrapstodon de {year}", - "annual_report.summary.archetype.booster": "O Telexornal", - "annual_report.summary.archetype.lurker": "Volleur", - "annual_report.summary.archetype.oracle": "Sabichón", - "annual_report.summary.archetype.pollster": "I.G.E.", - "annual_report.summary.archetype.replier": "Lareteire", - "annual_report.summary.followers.followers": "seguidoras", - "annual_report.summary.followers.total": "{count} en total", - "annual_report.summary.here_it_is": "Este é o resumo do teu {year}:", - "annual_report.summary.highlighted_post.by_favourites": "a publicación mais favorecida", - "annual_report.summary.highlighted_post.by_reblogs": "a publicación con mais promocións", - "annual_report.summary.highlighted_post.by_replies": "a publicación con mais respostas", - "annual_report.summary.highlighted_post.possessive": "de {name}", + "annual_report.nav_item.badge": "Novidade", + "annual_report.shared_page.donate": "Doar", + "annual_report.shared_page.footer": "Creado con {heart} polo equipo de Mastodon", + "annual_report.summary.archetype.booster.desc_public": "{name} á caza de publicacións para promover, dando relevancia a outras creadoras.", + "annual_report.summary.archetype.booster.desc_self": "Á caza de publicacións para promover, dando relevancia a outras creadoras.", + "annual_report.summary.archetype.booster.name": "Arqueire", + "annual_report.summary.archetype.die_drei_fragezeichen": "???", + "annual_report.summary.archetype.lurker.desc_public": "Sabemos que {name} andivo por aí, nalgures, desfrutando de Mastodon paseniño e ao seu xeito.", + "annual_report.summary.archetype.lurker.desc_self": "Sabemos que andiveches por aí, nalgures, desfrutando de Mastodon tranquilamente e ao teu xeito.", + "annual_report.summary.archetype.lurker.name": "Xubilade", + "annual_report.summary.archetype.oracle.desc_public": "{name} creou máis publicacións que respostas, mantendo Mastodon ao día e ollando ao futuro.", + "annual_report.summary.archetype.oracle.desc_self": "Creaches máis publicacións que respostas, mantendo Mastodon ao día e ollando o futuro.", + "annual_report.summary.archetype.oracle.name": "O Oráculo", + "annual_report.summary.archetype.pollster.desc_public": "{name} creou máis enquisas que publicacións normais, cultivando a curiosidade en Mastodon.", + "annual_report.summary.archetype.pollster.desc_self": "Creaches máis enquisas que publicacións normais, cultivando a curiosidade en Mastodon.", + "annual_report.summary.archetype.pollster.name": "O mar de dúbidas", + "annual_report.summary.archetype.replier.desc_public": "{name} respondeu con frecuencia a outras persoas, polinizando Mastodon con novas conversas.", + "annual_report.summary.archetype.replier.desc_self": "Respondeches con frecuencia a outras persoas, polinizando Mastodon con novas conversas.", + "annual_report.summary.archetype.replier.name": "A Bolboreta", + "annual_report.summary.archetype.reveal": "Mostrar o meu arquetipo", + "annual_report.summary.archetype.reveal_description": "Grazas por ser parte de Mastodon! É hora de coñecer o teu arquetipo de usuaria no {year}.", + "annual_report.summary.archetype.title_public": "Arquetipo de {name}", + "annual_report.summary.archetype.title_self": "O teu arquetipo", + "annual_report.summary.close": "Fechar", + "annual_report.summary.copy_link": "Copiar ligazón", + "annual_report.summary.followers.new_followers": "{count, plural, one {nova seguidora} other {nevas seguidoras}}", + "annual_report.summary.highlighted_post.boost_count": "Esta publicación promoveuse {count, plural, one {unha vez} other {# veces}}.", + "annual_report.summary.highlighted_post.favourite_count": "Esta publicación favoreceuse {count, plural, one {unha vez} other {# veces}}.", + "annual_report.summary.highlighted_post.reply_count": "Esta publicación tivo {count, plural, one {unha resposta} other {# respostas}}.", + "annual_report.summary.highlighted_post.title": "Publicación máis popular", "annual_report.summary.most_used_app.most_used_app": "app que mais usaches", "annual_report.summary.most_used_hashtag.most_used_hashtag": "o cancelo mais utilizado", - "annual_report.summary.most_used_hashtag.none": "Nada", + "annual_report.summary.most_used_hashtag.used_count": "Incluíches este cancelo en {count, plural, one {1 publicación} other {# publicacións}}.", + "annual_report.summary.most_used_hashtag.used_count_public": "{name} incluíu este cancelo en {count, plural, one {1 publicación} other {# publicacións}}.", "annual_report.summary.new_posts.new_posts": "novas publicacións", "annual_report.summary.percentile.text": "Sitúante no top das usuarias de {domain}.", "annual_report.summary.percentile.we_wont_tell_bernie": "Moito tes que contarnos!", + "annual_report.summary.share_elsewhere": "Compárteo onde queiras", "annual_report.summary.share_message": "Resulta que son… {archetype}!", - "annual_report.summary.thanks": "Grazas por ser parte de Mastodon!", + "annual_report.summary.share_on_mastodon": "Compartir en Mastodon", "attachments_list.unprocessed": "(sen procesar)", "audio.hide": "Agochar audio", "block_modal.remote_users_caveat": "Ímoslle pedir ao servidor {domain} que respecte a túa decisión. Emporiso, non hai garantía de que atenda a petición xa que os servidores xestionan os bloqueos de formas diferentes. As publicacións públicas poderían aínda ser visibles para usuarias que non iniciaron sesión.", diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json index ea0bc4b44fa9cd..b2abc99d029bc3 100644 --- a/app/javascript/mastodon/locales/he.json +++ b/app/javascript/mastodon/locales/he.json @@ -114,29 +114,50 @@ "alt_text_modal.done": "סיום", "announcement.announcement": "הכרזה", "annual_report.announcement.action_build": "בנה לי את הסיכומודון שלי", + "annual_report.announcement.action_dismiss": "לא תודה", "annual_report.announcement.action_view": "לצפייה בסיכומודון שלי", "annual_report.announcement.description": "ללמוד עוד על דבפוסי השימוש שלך במסטודון לאורך השנה החולפת.", "annual_report.announcement.title": "סיכומודון {year} הגיע", - "annual_report.summary.archetype.booster": "ההד-וניסט(ית)", - "annual_report.summary.archetype.lurker": "השורץ.ת השקט.ה", - "annual_report.summary.archetype.oracle": "כבוד הרב.ה", - "annual_report.summary.archetype.pollster": "הסקרן.ית", - "annual_report.summary.archetype.replier": "הפרפר.ית החברתי.ת", - "annual_report.summary.followers.followers": "עוקבים", - "annual_report.summary.followers.total": "{count} בסך הכל", - "annual_report.summary.here_it_is": "והנה סיכום {year} שלך:", - "annual_report.summary.highlighted_post.by_favourites": "התות הכי מחובב", - "annual_report.summary.highlighted_post.by_reblogs": "התות הכי מהודהד", - "annual_report.summary.highlighted_post.by_replies": "התות עם מספר התשובות הגבוה ביותר", - "annual_report.summary.highlighted_post.possessive": "של {name}", + "annual_report.nav_item.badge": "חדש", + "annual_report.shared_page.donate": "לתרומה", + "annual_report.shared_page.footer": "נוצר עם כל ה-{heart} על ידי צוות מסטודון", + "annual_report.summary.archetype.booster.desc_public": "{name} צדו הודעות מעניינות להדהד, והגבירו קולותיהם של יוצרים אחרים בדיוק של חתול המזנק על הטרף.", + "annual_report.summary.archetype.booster.desc_self": "צדת הודעות מעניינות להדהד, והגברת קולותיהם של יוצרים אחרים בדיוק של חתול המזנק על הטרף.", + "annual_report.summary.archetype.booster.name": "החתול הצייד", + "annual_report.summary.archetype.die_drei_fragezeichen": "???", + "annual_report.summary.archetype.lurker.desc_public": "למיטב ידיעתנו {name} היו שם, איפשהוא, נהנים ממסטודון בדרכם השקטה.", + "annual_report.summary.archetype.lurker.desc_self": "למיטב ידיעתנו היית שם, איפשהוא, נהנית ממסטודון בדרכך השקטה.", + "annual_report.summary.archetype.lurker.name": "הסטואי.ת", + "annual_report.summary.archetype.oracle.desc_public": "{name} יצרו יותר הודעות מאשר תגובות, ושמרו על מסטודון רעננה ועם פנים לעתיד.", + "annual_report.summary.archetype.oracle.desc_self": "יצרת יותר הודעות מאשר תגובות, ושמרת על מסטודון רעננה ועם פנים לעתיד.", + "annual_report.summary.archetype.oracle.name": "כבוד הרב.ה", + "annual_report.summary.archetype.pollster.desc_public": "{name} יצרו יותר סקרים מאשר כל סוג הודעה אחר, וכך הרבו סקרנות במסטודון.", + "annual_report.summary.archetype.pollster.desc_self": "יצרת יותר סקרים מאשר כל סוג הודעה אחר, וכך הרבת סקרנות במסטודון.", + "annual_report.summary.archetype.pollster.name": "התוהה", + "annual_report.summary.archetype.replier.desc_public": "{name} ענו תכופות לאחרים, והפרו את מסטודון בדיונים חדשים.", + "annual_report.summary.archetype.replier.desc_self": "ענית תכופות לאחרים, והפרית את מסטודון בדיונים חדשים.", + "annual_report.summary.archetype.replier.name": "הפרפר", + "annual_report.summary.archetype.reveal": "גלו את הארכיטיפ שלכם", + "annual_report.summary.archetype.reveal_description": "תודה שאתם חלק ממסטודון! הגיע הזמן לגלות מה הארכיטיפ שגילמתן בשנת {year}.", + "annual_report.summary.archetype.title_public": "הארכיטיפ של {name}", + "annual_report.summary.archetype.title_self": "הארכיטיפ שלך", + "annual_report.summary.close": "סגירה", + "annual_report.summary.copy_link": "העתק קישור", + "annual_report.summary.followers.new_followers": "{count, plural,one {עוקב חדש} other {עוקבים חדשים}}", + "annual_report.summary.highlighted_post.boost_count": "הודעה זו הודהדה {count, plural,one {פעם אחת}other {# פעמים}}.", + "annual_report.summary.highlighted_post.favourite_count": "הודעה זו חובבה {count, plural,one {פעם אחת}other {# פעמים}}.", + "annual_report.summary.highlighted_post.reply_count": "הודעה זו נענתה על ידי {count, plural,one {תגובה אחת}other {# תגובות}}.", + "annual_report.summary.highlighted_post.title": "ההודעה הפופולרית ביותר", "annual_report.summary.most_used_app.most_used_app": "היישומון שהכי בשימוש", "annual_report.summary.most_used_hashtag.most_used_hashtag": "התג בשימוש הרב ביותר", - "annual_report.summary.most_used_hashtag.none": "אף אחד", + "annual_report.summary.most_used_hashtag.used_count": "כללת את התגית הזו {count, plural,one {בהודעה אחת}other {ב-# הודעות}}.", + "annual_report.summary.most_used_hashtag.used_count_public": "{name} כללו את התגית {count, plural,one {בהודעה אחת}other {ב־# הודעות}}.", "annual_report.summary.new_posts.new_posts": "הודעות חדשות", "annual_report.summary.percentile.text": "ממקם אותך באחוזון של משמשי {domain}.", "annual_report.summary.percentile.we_wont_tell_bernie": "לא נגלה לברני.", + "annual_report.summary.share_elsewhere": "שיתוף במקום אחר", "annual_report.summary.share_message": "זוהיתי כדוגמא לטיפוס {archetype}!", - "annual_report.summary.thanks": "תודה על היותך חלק ממסטודון!", + "annual_report.summary.share_on_mastodon": "לשתף במסטודון", "attachments_list.unprocessed": "(לא מעובד)", "audio.hide": "השתק", "block_modal.remote_users_caveat": "אנו נבקש מהשרת {domain} לכבד את החלטתך. עם זאת, ציות למוסכמות איננו מובטח כיוון ששרתים מסויימים עשויים לטפל בחסימות בצורה אחרת. הודעות פומביות עדיין יהיו גלויות לעיני משתמשים שאינם מחוברים.", diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json index c62a332a96d70b..755dbd1bede1b5 100644 --- a/app/javascript/mastodon/locales/hu.json +++ b/app/javascript/mastodon/locales/hu.json @@ -117,25 +117,43 @@ "annual_report.announcement.action_view": "Saját Wrapstodon megtekintése", "annual_report.announcement.description": "Fedezz fel többet a Mastodonon az elmúlt évben végzett tevékenységeidről.", "annual_report.announcement.title": "A Wrapstodon {year} megérkezett", - "annual_report.summary.archetype.booster": "A cool-vadász", - "annual_report.summary.archetype.lurker": "A settenkedő", - "annual_report.summary.archetype.oracle": "Az orákulum", - "annual_report.summary.archetype.pollster": "A közvélemény-kutató", - "annual_report.summary.archetype.replier": "A társasági pillangó", - "annual_report.summary.followers.followers": "követő", - "annual_report.summary.followers.total": "{count} összesen", - "annual_report.summary.here_it_is": "Itt a {year}. év értékelése:", - "annual_report.summary.highlighted_post.by_favourites": "legkedvencebb bejegyzés", - "annual_report.summary.highlighted_post.by_reblogs": "legtöbbet megtolt bejegyzés", - "annual_report.summary.highlighted_post.by_replies": "bejegyzés a legtöbb válasszal", - "annual_report.summary.highlighted_post.possessive": "{name} fióktól", + "annual_report.shared_page.donate": "Adományozás", + "annual_report.shared_page.footer": "A Mastodon által {heart}-tel előállítva", + "annual_report.summary.archetype.booster.desc_public": "{name} megtolandó bejegyzésekre vadászott, tökéletes célzással felerősítve mások üzeneteit.", + "annual_report.summary.archetype.booster.desc_self": "Megtolandó bejegyzésekre vadásztál, tökéletes célzással felerősítve mások üzeneteit.", + "annual_report.summary.archetype.booster.name": "Az íjász", + "annual_report.summary.archetype.die_drei_fragezeichen": "???", + "annual_report.summary.archetype.lurker.desc_public": "Tudjuk, hogy {name} ott volt, valahol, a saját csendes módján élvezve a Mastodont.", + "annual_report.summary.archetype.lurker.desc_self": "Tudjuk, hogy ott voltál, valahol, a saját csendes módodon élvezve a Mastodont.", + "annual_report.summary.archetype.lurker.name": "A sztoikus", + "annual_report.summary.archetype.oracle.desc_public": "{name} több bejegyzést hozott létre, mint választ, így a Mastodon friss és jövőbe tekintő marad.", + "annual_report.summary.archetype.oracle.desc_self": "Több bejegyzést hoztál létre, mint választ, így a Mastodon friss és jövőbe tekintő marad.", + "annual_report.summary.archetype.oracle.name": "Az orákulum", + "annual_report.summary.archetype.pollster.desc_public": "{name} több szavazást hozott létre, mint bármilyen más bejegyzést, ezzel támogatva a kíváncsiságot a Mastodonon.", + "annual_report.summary.archetype.pollster.desc_self": "Több szavazást hoztál létre, mint bármilyen más bejegyzést, ezzel támogatva a kíváncsiságot a Mastodonon.", + "annual_report.summary.archetype.pollster.name": "A csodálkozó", + "annual_report.summary.archetype.replier.desc_public": "{name} gyakran válaszolt más emberek bejegyzéseire, új témákat porozva be a Mastodonon.", + "annual_report.summary.archetype.replier.desc_self": "Gyakran válaszoltál más emberek bejegyzéseire, új témákat porozva be a Mastodonon.", + "annual_report.summary.archetype.replier.name": "A pillangó", + "annual_report.summary.archetype.reveal": "Saját archetípus felfedése", + "annual_report.summary.archetype.reveal_description": "Köszönjük, hogy a Mastodon része vagy! Tudj meg többet az archetípusodról {year} évében.", + "annual_report.summary.archetype.title_public": "{name} archetípusa", + "annual_report.summary.archetype.title_self": "Saját archetípus", + "annual_report.summary.close": "Bezárás", + "annual_report.summary.followers.new_followers": "{count, plural, one {új követő} other {új követők}}", + "annual_report.summary.highlighted_post.boost_count": "Ez a bejegyzés {count, plural, one {egyszer} other {# alkalommal}} volt megtolva.", + "annual_report.summary.highlighted_post.favourite_count": "Ez a bejegyzés {count, plural, one {egyszer} other {# alkalommal}} volt kedvencnek jelölve.", + "annual_report.summary.highlighted_post.reply_count": "Ez a bejegyzés {count, plural, one {egy választ} other {# választ}} kapott.", + "annual_report.summary.highlighted_post.title": "Legnépszerűbb bejegyzés", "annual_report.summary.most_used_app.most_used_app": "legtöbbet használt app", "annual_report.summary.most_used_hashtag.most_used_hashtag": "legtöbbet használt hashtag", - "annual_report.summary.most_used_hashtag.none": "Nincs", + "annual_report.summary.most_used_hashtag.used_count": "Ez a hashtag {count, plural, one {egy bejegyzésedben} other {# bejegyzésedben}} szerepel.", + "annual_report.summary.most_used_hashtag.used_count_public": "{name} {count, plural, one {egy bejegyzésében} other {# bejegyzésében}} használta ezt a hashtaget.", "annual_report.summary.new_posts.new_posts": "új bejegyzés", "annual_report.summary.percentile.text": "Ezzel a csúcs{domain} felhasználó között vagy.", "annual_report.summary.percentile.we_wont_tell_bernie": "Nem mondjuk el Bernie-nek.", - "annual_report.summary.thanks": "Kösz, hogy a Mastodon része vagy!", + "annual_report.summary.share_message": "{archetype} lett az archetípusom!", + "annual_report.summary.share_on_mastodon": "Megosztás a Mastodonon", "attachments_list.unprocessed": "(feldolgozatlan)", "audio.hide": "Hang elrejtése", "block_modal.remote_users_caveat": "Arra kérjük a {domain} kiszolgálót, hogy tartsa tiszteletben a döntésedet. Ugyanakkor az együttműködés nem garantált, mivel néhány kiszolgáló másképp kezelheti a letiltásokat. A nyilvános bejegyzések a be nem jelentkezett felhasználók számára továbbra is látszódhatnak.", diff --git a/app/javascript/mastodon/locales/ia.json b/app/javascript/mastodon/locales/ia.json index 4202a855c81b8b..a32a39617bd6f5 100644 --- a/app/javascript/mastodon/locales/ia.json +++ b/app/javascript/mastodon/locales/ia.json @@ -113,25 +113,11 @@ "alt_text_modal.describe_for_people_with_visual_impairments": "Describe isto pro personas con impedimentos visual…", "alt_text_modal.done": "Preste", "announcement.announcement": "Annuncio", - "annual_report.summary.archetype.booster": "Le impulsator", - "annual_report.summary.archetype.lurker": "Le lector", - "annual_report.summary.archetype.oracle": "Le oraculo", - "annual_report.summary.archetype.pollster": "Le sondagista", - "annual_report.summary.archetype.replier": "Le responditor", - "annual_report.summary.followers.followers": "sequitores", - "annual_report.summary.followers.total": "{count} in total", - "annual_report.summary.here_it_is": "Ecce tu summario de {year}:", - "annual_report.summary.highlighted_post.by_favourites": "message le plus favorite", - "annual_report.summary.highlighted_post.by_reblogs": "message le plus impulsate", - "annual_report.summary.highlighted_post.by_replies": "message le plus respondite", - "annual_report.summary.highlighted_post.possessive": "{name}, ecce tu…", "annual_report.summary.most_used_app.most_used_app": "application le plus usate", "annual_report.summary.most_used_hashtag.most_used_hashtag": "hashtag le plus usate", - "annual_report.summary.most_used_hashtag.none": "Necun", "annual_report.summary.new_posts.new_posts": "nove messages", "annual_report.summary.percentile.text": "Isto te pone in le primeusatores de {domain}.", "annual_report.summary.percentile.we_wont_tell_bernie": "Tu es un primo inter pares.", - "annual_report.summary.thanks": "Gratias pro facer parte de Mastodon!", "attachments_list.unprocessed": "(non processate)", "audio.hide": "Celar audio", "block_modal.remote_users_caveat": "Nos demandera al servitor {domain} de respectar tu decision. Nonobstante, le conformitate non es garantite perque alcun servitores pote tractar le blocadas de maniera differente. Le messages public pote esser totevia visibile pro le usatores non authenticate.", diff --git a/app/javascript/mastodon/locales/io.json b/app/javascript/mastodon/locales/io.json index 8ee26722501799..adf604a5d5d124 100644 --- a/app/javascript/mastodon/locales/io.json +++ b/app/javascript/mastodon/locales/io.json @@ -90,25 +90,11 @@ "alt_text_modal.describe_for_people_with_visual_impairments": "Priskribar co por personi kun viddeskapableso…", "alt_text_modal.done": "Finis", "announcement.announcement": "Anunco", - "annual_report.summary.archetype.booster": "La plurrepetanto", - "annual_report.summary.archetype.lurker": "La plurcelanto", - "annual_report.summary.archetype.oracle": "La pluraktivo", - "annual_report.summary.archetype.pollster": "La votinquestoiganto", - "annual_report.summary.archetype.replier": "La plurrespondanto", - "annual_report.summary.followers.followers": "sequanti", - "annual_report.summary.followers.total": "{count} sumo", - "annual_report.summary.here_it_is": "Caibe es vua rivido ye {year}:", - "annual_report.summary.highlighted_post.by_favourites": "maxim prizita mesajo", - "annual_report.summary.highlighted_post.by_reblogs": "maxim repetita mesajo", - "annual_report.summary.highlighted_post.by_replies": "mesajo kun la maxim multa respondi", - "annual_report.summary.highlighted_post.possessive": "di {name}", "annual_report.summary.most_used_app.most_used_app": "maxim uzita aplikajo", "annual_report.summary.most_used_hashtag.most_used_hashtag": "maxim uzita gretvorto", - "annual_report.summary.most_used_hashtag.none": "Nulo", "annual_report.summary.new_posts.new_posts": "nova afishi", "annual_report.summary.percentile.text": "To pozas vu sur la supro di uzanti di {domain}.", "annual_report.summary.percentile.we_wont_tell_bernie": "Ni ne dicas ad Bernio.", - "annual_report.summary.thanks": "Danki por partoprenar sur Mastodon!", "attachments_list.unprocessed": "(neprocedita)", "audio.hide": "Celez audio", "block_modal.remote_users_caveat": "Ni questionos {domain} di la servilo por respektar vua decido. Publika posti forsan ankore estas videbla a neenirinta uzanti.", diff --git a/app/javascript/mastodon/locales/is.json b/app/javascript/mastodon/locales/is.json index 5462f0c0ba91b5..d83074a08a9276 100644 --- a/app/javascript/mastodon/locales/is.json +++ b/app/javascript/mastodon/locales/is.json @@ -114,29 +114,51 @@ "alt_text_modal.done": "Lokið", "announcement.announcement": "Auglýsing", "annual_report.announcement.action_build": "Byggja Wrapstodon fyrir mig", + "annual_report.announcement.action_dismiss": "Nei takk", "annual_report.announcement.action_view": "Skoða minn Wrapstodon", "annual_report.announcement.description": "Skoðaðu meira um virkni þína á Mastodon á síðastliðnu ári.", "annual_report.announcement.title": "Wrapstodon {year} er komið", - "annual_report.summary.archetype.booster": "Svali gaurinn", - "annual_report.summary.archetype.lurker": "Lurkurinn", - "annual_report.summary.archetype.oracle": "Völvan", - "annual_report.summary.archetype.pollster": "Kannanafíkillinn", - "annual_report.summary.archetype.replier": "Félagsveran", - "annual_report.summary.followers.followers": "fylgjendur", - "annual_report.summary.followers.total": "{count} alls", - "annual_report.summary.here_it_is": "Hér er yfirlitið þitt fyrir {year}:", - "annual_report.summary.highlighted_post.by_favourites": "færsla sett oftast í eftirlæti", - "annual_report.summary.highlighted_post.by_reblogs": "færsla oftast endurbirt", - "annual_report.summary.highlighted_post.by_replies": "færsla með flestum svörum", - "annual_report.summary.highlighted_post.possessive": "{name}", + "annual_report.nav_item.badge": "Nýtt", + "annual_report.shared_page.donate": "Styrkja", + "annual_report.shared_page.footer": "{heart}-kveðjur frá Mastodon-teyminu", + "annual_report.shared_page.footer_server_info": "{username} notar {domain}, einu af samfélögunum sem Mastodon drífur.", + "annual_report.summary.archetype.booster.desc_public": "{name} var á höttunum eftir færslum til að endurbirta og hitti þannig í mark með að magna upp það sem aðrir voru að gera.", + "annual_report.summary.archetype.booster.desc_self": "Þú varst á höttunum eftir færslum til að endurbirta og hittir þannig í mark með að magna upp það sem aðrir voru að gera.", + "annual_report.summary.archetype.booster.name": "Veiðmaðurinn", + "annual_report.summary.archetype.die_drei_fragezeichen": "???", + "annual_report.summary.archetype.lurker.desc_public": "Við vitum að {name} var þarna úti, einhversstaðar, að njóta Mastodon á sínum eigin hljóðlátu forsendum.", + "annual_report.summary.archetype.lurker.desc_self": "Við vitum að þú varst þarna úti, einhversstaðar, að njóta Mastodon á þínum eigin hljóðlátu forsendum.", + "annual_report.summary.archetype.lurker.name": "Heimspekingurinn", + "annual_report.summary.archetype.oracle.desc_public": "{name} útbjó fleiri færslur en svör og hélt þannig Mastodon fersku og vísandi til framtíðar.", + "annual_report.summary.archetype.oracle.desc_self": "Þú útbjóst fleiri færslur en svör og hélst þannig Mastodon fersku og vísandi til framtíðar.", + "annual_report.summary.archetype.oracle.name": "Völvan", + "annual_report.summary.archetype.pollster.desc_public": "{name} útbjó fleiri kannanir en aðrar gerðir af færslum og ræktaði þannig forvitni á ökrum Mastodon.", + "annual_report.summary.archetype.pollster.desc_self": "Þú útbjóst fleiri kannanir en aðrar gerðir af færslum og ræktaðir þannig forvitni á ökrum Mastodon.", + "annual_report.summary.archetype.pollster.name": "Könnuðurinn", + "annual_report.summary.archetype.replier.desc_public": "{name} svaraði oft færslum annara og frjóvgaði Mastodon með nýjum samræðum.", + "annual_report.summary.archetype.replier.desc_self": "Þú svaraðir oft færslum annara og frjóvgaðir Mastodon með nýjum samræðum.", + "annual_report.summary.archetype.replier.name": "Fiðrildið", + "annual_report.summary.archetype.reveal": "Uppljóstra um erkitýpuna mína", + "annual_report.summary.archetype.reveal_description": "Takk fyrir að vera hluti af Mastodon! Nú er tíminn til að sjá hvaða erkitýpu þú líktist árið {year}.", + "annual_report.summary.archetype.title_public": "Erkitýpan fyrir {name}", + "annual_report.summary.archetype.title_self": "Erkitýpan þín", + "annual_report.summary.close": "Loka", + "annual_report.summary.copy_link": "Afrita tengil", + "annual_report.summary.followers.new_followers": "{count, plural, one {nýr fylgjandi} other {nýir fylgjendur}}", + "annual_report.summary.highlighted_post.boost_count": "Þessi færsla var endurbirt {count, plural, one {einu sinni} other {# sinnum}}.", + "annual_report.summary.highlighted_post.favourite_count": "Þessi færsla var sett í eftirlæti {count, plural, one {einu sinni} other {# sinnum}}.", + "annual_report.summary.highlighted_post.reply_count": "Þessi færsla fékk {count, plural, one {eitt svar} other {# svör}}.", + "annual_report.summary.highlighted_post.title": "Vinsælasta færslan", "annual_report.summary.most_used_app.most_used_app": "mest notaða forrit", "annual_report.summary.most_used_hashtag.most_used_hashtag": "mest notaða myllumerki", - "annual_report.summary.most_used_hashtag.none": "Ekkert", + "annual_report.summary.most_used_hashtag.used_count": "Þú hafðir þetta myllumerki með í {count, plural, one {einni færslu} other {# færslum}}.", + "annual_report.summary.most_used_hashtag.used_count_public": "{name} hafði þetta myllumerki með í {count, plural, one {einni færslu} other {# færslum}}.", "annual_report.summary.new_posts.new_posts": "nýjar færslur", "annual_report.summary.percentile.text": "Þetta setur þig á meðalof {domain} virkustu notendanna.", "annual_report.summary.percentile.we_wont_tell_bernie": "Við förum ekkert að raupa um þetta.", + "annual_report.summary.share_elsewhere": "Deila annarsstaðar", "annual_report.summary.share_message": "Ég er víst {archetype}-týpan!", - "annual_report.summary.thanks": "Takk fyrir að vera hluti af Mastodon-samfélaginu!", + "annual_report.summary.share_on_mastodon": "Deila á Mastodon", "attachments_list.unprocessed": "(óunnið)", "audio.hide": "Fela hljóð", "block_modal.remote_users_caveat": "Við munum biðja {domain} netþjóninn um að virða ákvörðun þína. Hitt er svo annað mál hvort hann fari eftir þessu, ekki er hægt að tryggja eftirfylgni því sumir netþjónar meðhöndla útilokanir á sinn hátt. Opinberar færslur gætu verið sýnilegar notendum sem ekki eru skráðir inn.", @@ -419,6 +441,8 @@ "follow_suggestions.who_to_follow": "Hverjum á að fylgjast með", "followed_tags": "Vöktuð myllumerki", "footer.about": "Nánari upplýsingar", + "footer.about_mastodon": "Um Mastodon", + "footer.about_server": "Um {domain}", "footer.about_this_server": "Nánari upplýsingar", "footer.directory": "Notandasniðamappa", "footer.get_app": "Ná í forritið", diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json index d6a3d994ead6d2..3f509078594ffd 100644 --- a/app/javascript/mastodon/locales/it.json +++ b/app/javascript/mastodon/locales/it.json @@ -31,7 +31,7 @@ "account.edit_profile_short": "Modifica", "account.enable_notifications": "Avvisami quando @{name} pubblica un post", "account.endorse": "In evidenza sul profilo", - "account.familiar_followers_many": "Seguito da {name1}, {name2}, e {othersCount, plural, one {un altro che conosci} other {# altri che conosci}}", + "account.familiar_followers_many": "Seguito da {name1}, {name2}, e {othersCount, plural, one {un altro che conosci} other {altri # che conosci}}", "account.familiar_followers_one": "Seguito da {name1}", "account.familiar_followers_two": "Seguito da {name1} e {name2}", "account.featured": "In primo piano", @@ -114,29 +114,51 @@ "alt_text_modal.done": "Fatto", "announcement.announcement": "Annuncio", "annual_report.announcement.action_build": "Costruisci il mio Wrapstodon", + "annual_report.announcement.action_dismiss": "No, grazie", "annual_report.announcement.action_view": "Visualizza il mio Wrapstodon", "annual_report.announcement.description": "Scopri di più sul tuo coinvolgimento su Mastodon nell'ultimo anno.", "annual_report.announcement.title": "Wrapstodon {year} è arrivato", - "annual_report.summary.archetype.booster": "Cacciatore/trice di tendenze", - "annual_report.summary.archetype.lurker": "L'osservatore/trice", - "annual_report.summary.archetype.oracle": "L'oracolo", - "annual_report.summary.archetype.pollster": "Sondaggista", - "annual_report.summary.archetype.replier": "Utente socievole", - "annual_report.summary.followers.followers": "seguaci", - "annual_report.summary.followers.total": "{count} in totale", - "annual_report.summary.here_it_is": "Ecco il tuo {year} in sintesi:", - "annual_report.summary.highlighted_post.by_favourites": "il post più apprezzato", - "annual_report.summary.highlighted_post.by_reblogs": "il post più condiviso", - "annual_report.summary.highlighted_post.by_replies": "il post con più risposte", - "annual_report.summary.highlighted_post.possessive": "di {name}", + "annual_report.nav_item.badge": "Nuovo", + "annual_report.shared_page.donate": "Dona", + "annual_report.shared_page.footer": "Generato con {heart} dal team di Mastodon", + "annual_report.shared_page.footer_server_info": "{username} usa {domain}, una delle tante comunità basate su Mastodon.", + "annual_report.summary.archetype.booster.desc_public": "{name} è rimasto/a alla ricerca di post da condividere, amplificando il lavoro di altri creatori con precisione mirata.", + "annual_report.summary.archetype.booster.desc_self": "Sei rimasto/a alla ricerca di post da condividere, amplificando il lavoro di altri creatori con precisione mirata.", + "annual_report.summary.archetype.booster.name": "L'Arciere", + "annual_report.summary.archetype.die_drei_fragezeichen": "???", + "annual_report.summary.archetype.lurker.desc_public": "Sappiamo che {name} era là fuori, da qualche parte, a godersi Mastodon in tutta tranquillità.", + "annual_report.summary.archetype.lurker.desc_self": "Sappiamo che eri là fuori, da qualche parte, a goderti Mastodon in tutta tranquillità.", + "annual_report.summary.archetype.lurker.name": "Lo Stoico", + "annual_report.summary.archetype.oracle.desc_public": "{name} ha creato più nuovi post che risposte, mantenendo Mastodon fresco e orientato al futuro.", + "annual_report.summary.archetype.oracle.desc_self": "Hai creato più nuovi post che risposte, mantenendo Mastodon fresco e orientato al futuro.", + "annual_report.summary.archetype.oracle.name": "L'Oracolo", + "annual_report.summary.archetype.pollster.desc_public": "{name} ha creato più sondaggi rispetto ad altri tipi di post, alimentando la curiosità su Mastodon.", + "annual_report.summary.archetype.pollster.desc_self": "Hai creato più sondaggi rispetto ad altri tipi di post, alimentando la curiosità su Mastodon.", + "annual_report.summary.archetype.pollster.name": "L'Esploratore", + "annual_report.summary.archetype.replier.desc_public": "{name} ha frequentemente risposto ai post di altre persone, alimentando Mastodon con nuove discussioni.", + "annual_report.summary.archetype.replier.desc_self": "Hai frequentemente risposto ai post di altre persone, alimentando Mastodon con nuove discussioni.", + "annual_report.summary.archetype.replier.name": "La Farfalla", + "annual_report.summary.archetype.reveal": "Rivela il mio archetipo", + "annual_report.summary.archetype.reveal_description": "Grazie per far parte di Mastodon! È il momento di scoprire quale archetipo hai incarnato nel {year}.", + "annual_report.summary.archetype.title_public": "Archetipo di {name}", + "annual_report.summary.archetype.title_self": "Il tuo archetipo", + "annual_report.summary.close": "Chiudi", + "annual_report.summary.copy_link": "Copia il сollegamento", + "annual_report.summary.followers.new_followers": "{count, plural, one {nuovo seguace} other {nuovi seguaci}}", + "annual_report.summary.highlighted_post.boost_count": "Questo post è stato condiviso {count, plural, one {1 volta} other {# volte}}.", + "annual_report.summary.highlighted_post.favourite_count": "Questo post è stato aggiunto ai preferiti {count, plural, one {1 volta} other {# volte}}.", + "annual_report.summary.highlighted_post.reply_count": "Questo post ha ricevuto {count, plural, one {1 risposta} other {# risposte}}.", + "annual_report.summary.highlighted_post.title": "Il post più popolare", "annual_report.summary.most_used_app.most_used_app": "l'app più utilizzata", "annual_report.summary.most_used_hashtag.most_used_hashtag": "l'hashtag più usato", - "annual_report.summary.most_used_hashtag.none": "Nessuno", + "annual_report.summary.most_used_hashtag.used_count": "Hai incluso questo hashtag in {count, plural, one {1 post} other {# post}}.", + "annual_report.summary.most_used_hashtag.used_count_public": "{name} ha incluso questo hashtag in {count, plural, one {1 post} other {# post}}.", "annual_report.summary.new_posts.new_posts": "nuovi post", "annual_report.summary.percentile.text": "Ciò ti colloca in cimaagli utenti di {domain}.", "annual_report.summary.percentile.we_wont_tell_bernie": "Non lo diremo a Bernie.", + "annual_report.summary.share_elsewhere": "Condividi altrove", "annual_report.summary.share_message": "Ho ottenuto l'archetipo: {archetype}!", - "annual_report.summary.thanks": "Grazie per far parte di Mastodon!", + "annual_report.summary.share_on_mastodon": "Condividi su Mastodon", "attachments_list.unprocessed": "(non elaborato)", "audio.hide": "Nascondi audio", "block_modal.remote_users_caveat": "Chiederemo al server {domain} di rispettare la tua decisione. Tuttavia, la conformità non è garantita poiché alcuni server potrebbero gestire i blocchi in modo diverso. I post pubblici potrebbero essere ancora visibili agli utenti che non hanno effettuato l'accesso.", @@ -419,6 +441,8 @@ "follow_suggestions.who_to_follow": "Chi seguire", "followed_tags": "Hashtag seguiti", "footer.about": "Info", + "footer.about_mastodon": "Riguardo Mastodon", + "footer.about_server": "Riguardo {domain}", "footer.about_this_server": "Info", "footer.directory": "Cartella dei profili", "footer.get_app": "Scarica l'app", diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json index e693387b126005..428009b29825cb 100644 --- a/app/javascript/mastodon/locales/ja.json +++ b/app/javascript/mastodon/locales/ja.json @@ -113,25 +113,11 @@ "alt_text_modal.describe_for_people_with_visual_impairments": "目が不自由な方のために説明してください…", "alt_text_modal.done": "完了", "announcement.announcement": "お知らせ", - "annual_report.summary.archetype.booster": "トレンドハンター", - "annual_report.summary.archetype.lurker": "ROM専", - "annual_report.summary.archetype.oracle": "予言者", - "annual_report.summary.archetype.pollster": "調査員", - "annual_report.summary.archetype.replier": "社交家", - "annual_report.summary.followers.followers": "フォロワー", - "annual_report.summary.followers.total": "合計{count}", - "annual_report.summary.here_it_is": "こちらがあなたの{year}年の振り返りです", - "annual_report.summary.highlighted_post.by_favourites": "最もお気に入りされた投稿", - "annual_report.summary.highlighted_post.by_reblogs": "最もブーストされた投稿", - "annual_report.summary.highlighted_post.by_replies": "最も返信が多かった投稿", - "annual_report.summary.highlighted_post.possessive": "{name}の", "annual_report.summary.most_used_app.most_used_app": "最も使用されているアプリ", "annual_report.summary.most_used_hashtag.most_used_hashtag": "最も使用されたハッシュタグ", - "annual_report.summary.most_used_hashtag.none": "なし", "annual_report.summary.new_posts.new_posts": "新しい投稿", "annual_report.summary.percentile.text": "{domain}で 上位に入ります!", "annual_report.summary.percentile.we_wont_tell_bernie": "バー二ーには秘密にしておくよ。", - "annual_report.summary.thanks": "Mastodonの一員になってくれてありがとう!", "attachments_list.unprocessed": "(未処理)", "audio.hide": "音声を閉じる", "block_modal.remote_users_caveat": "このサーバーはあなたのブロックの意思を尊重するように {domain} へ通知します。しかし、サーバーによってはブロック機能の扱いが異なる場合もありえるため、相手のサーバー側で求める通りの処理が行われる確証はありません。また、公開投稿はユーザーがログアウト状態であれば閲覧できる可能性があります。", diff --git a/app/javascript/mastodon/locales/kab.json b/app/javascript/mastodon/locales/kab.json index 36ecff0b43cfc6..05ea5f312ef27e 100644 --- a/app/javascript/mastodon/locales/kab.json +++ b/app/javascript/mastodon/locales/kab.json @@ -92,13 +92,9 @@ "alt_text_modal.cancel": "Semmet", "alt_text_modal.done": "Immed", "announcement.announcement": "Ulɣu", - "annual_report.summary.followers.followers": "imeḍfaṛen", - "annual_report.summary.followers.total": "{count} deg aɣrud", "annual_report.summary.most_used_app.most_used_app": "asnas yettwasqedcen s waṭas", - "annual_report.summary.most_used_hashtag.none": "Ula yiwen", "annual_report.summary.new_posts.new_posts": "tisuffaɣ timaynutin", "annual_report.summary.percentile.we_wont_tell_bernie": "Ur as-neqqar i yiwen.", - "annual_report.summary.thanks": "Tanemmirt imi i tettekkiḍ deg Mastodon!", "audio.hide": "Ffer amesli", "block_modal.show_less": "Ssken-d drus", "block_modal.show_more": "Ssken-d ugar", diff --git a/app/javascript/mastodon/locales/kk.json b/app/javascript/mastodon/locales/kk.json index 8e29c3fbeed207..7784f3d9e6871e 100644 --- a/app/javascript/mastodon/locales/kk.json +++ b/app/javascript/mastodon/locales/kk.json @@ -9,6 +9,7 @@ "about.domain_blocks.silenced.title": "Шектеулі", "about.domain_blocks.suspended.explanation": "Бұл сервердің деректері өңделмейді, сақталмайды және айырбасталмайды, сондықтан бұл сервердің қолданушыларымен кез келген әрекеттесу немесе байланыс мүмкін емес.", "about.domain_blocks.suspended.title": "Тоқтатылған", + "about.language_label": "Тіл", "about.not_available": "Бұл ақпарат бұл серверде қолжетімді емес.", "about.powered_by": "{mastodon} негізіндегі орталықсыз әлеуметтік желі", "about.rules": "Сервер ережелері", @@ -19,11 +20,13 @@ "account.block_domain": "{domain} доменін бұғаттау", "account.block_short": "Бұғаттау", "account.blocked": "Бұғатталған", + "account.blocking": "Бұғаттау", "account.cancel_follow_request": "Withdraw follow request", "account.direct": "@{name} жеке айту", "account.disable_notifications": "@{name} постары туралы ескертпеу", "account.domain_blocking": "Доменді бұғаттау", "account.edit_profile": "Профильді өңдеу", + "account.edit_profile_short": "Түзеу", "account.enable_notifications": "@{name} постары туралы ескерту", "account.endorse": "Профильде ұсыну", "account.familiar_followers_many": "{name1}, {name2} және {othersCount, plural, one {сіз білетін тағы бір адам} other {сіз білетін тағы # адам}} жазылған", @@ -91,7 +94,11 @@ "alert.rate_limited.title": "Бағалау шектеулі", "alert.unexpected.message": "Бір нәрсе дұрыс болмады.", "alert.unexpected.title": "Өй!", + "alt_text_badge.title": "Балама мазмұны", + "alt_text_modal.add_alt_text": "Балама мазмұнды қосу", + "alt_text_modal.done": "Дайын", "announcement.announcement": "Хабарландыру", + "annual_report.summary.close": "Жабу", "boost_modal.combo": "Келесіде өткізіп жіберу үшін басыңыз {combo}", "bundle_column_error.retry": "Қайтадан көріңіз", "bundle_modal_error.close": "Жабу", diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json index e3552abd2d3c62..6dfb4948863d6a 100644 --- a/app/javascript/mastodon/locales/ko.json +++ b/app/javascript/mastodon/locales/ko.json @@ -113,25 +113,38 @@ "alt_text_modal.describe_for_people_with_visual_impairments": "시각 장애가 있는 사람들을 위한 설명을 작성하세요…", "alt_text_modal.done": "완료", "announcement.announcement": "공지사항", - "annual_report.summary.archetype.booster": "연쇄부스트마", - "annual_report.summary.archetype.lurker": "은둔자", - "annual_report.summary.archetype.oracle": "예언자", - "annual_report.summary.archetype.pollster": "여론조사원", - "annual_report.summary.archetype.replier": "답글나비", - "annual_report.summary.followers.followers": "팔로워", - "annual_report.summary.followers.total": "총 {count}", - "annual_report.summary.here_it_is": "{year}년 결산입니다:", - "annual_report.summary.highlighted_post.by_favourites": "가장 많은 좋아요를 받은 게시물", - "annual_report.summary.highlighted_post.by_reblogs": "가장 많이 부스트된 게시물", - "annual_report.summary.highlighted_post.by_replies": "가장 많은 답글을 받은 게시물", - "annual_report.summary.highlighted_post.possessive": "{name} 님의", + "annual_report.announcement.action_build": "랩스토돈 만들기", + "annual_report.announcement.action_view": "랩스토돈 보기", + "annual_report.announcement.title": "{year} 랩스토돈이 도착했습니다", + "annual_report.summary.archetype.booster.desc_public": "{name} 님은 부스트할 게시물을 기다리고 정확한 조준으로 다른 제작자들을 밀어주었습니다.", + "annual_report.summary.archetype.booster.desc_self": "당신은 부스트할 게시물을 기다리고 정확한 조준으로 다른 제작자들을 밀어주었습니다.", + "annual_report.summary.archetype.booster.name": "궁수", + "annual_report.summary.archetype.die_drei_fragezeichen": "???", + "annual_report.summary.archetype.lurker.name": "금욕주의자", + "annual_report.summary.archetype.oracle.desc_public": "{name} 님은 답글보다 새로운 글을 많이 작성해 마스토돈을 신선하고 미래지향적으로 만들었습니다.", + "annual_report.summary.archetype.oracle.desc_self": "당신은 답글보다 새로운 글을 많이 작성해 마스토돈을 신선하고 미래지향적으로 만들었습니다.", + "annual_report.summary.archetype.oracle.name": "예언자", + "annual_report.summary.archetype.pollster.desc_public": "{name} 님은 다른 게시물보다 투표를 많이 만들었고 마스토돈에서 호기심을 일궈냈습니다.", + "annual_report.summary.archetype.pollster.desc_self": "당신은 다른 게시물보다 투표를 많이 만들었고 마스토돈에서 호기심을 일궈냈습니다.", + "annual_report.summary.archetype.pollster.name": "호기심쟁이", + "annual_report.summary.archetype.replier.desc_public": "{name} 님은 다른 사람의 게시물에 자주 답글을 남겨 마스토돈에 새로운 논의거리를 만들어냈습니다.", + "annual_report.summary.archetype.replier.desc_self": "당신은 다른 사람의 게시물에 자주 답글을 남겨 마스토돈에 새로운 논의거리를 만들어냈습니다.", + "annual_report.summary.archetype.replier.name": "나비", + "annual_report.summary.archetype.reveal": "내 특성을 확인합니다", + "annual_report.summary.archetype.reveal_description": "마스토돈의 일원이 되어주셔서 감사합니다! {year} 년엔 어떤 특성을 부여받는지 알아봅시다.", + "annual_report.summary.archetype.title_public": "{name} 님의 특성", + "annual_report.summary.archetype.title_self": "당신의 특성", + "annual_report.summary.close": "닫기", + "annual_report.summary.highlighted_post.boost_count": "이 게시물은 {count, plural,other {# 번}} 부스트되었습니다.", + "annual_report.summary.highlighted_post.favourite_count": "이 게시물은 {count, plural,other {# 번}} 마음에 들었습니다.", + "annual_report.summary.highlighted_post.reply_count": "이 게시물은 {count, plural, other {# 개}}의 답글을 받았습니다.", + "annual_report.summary.highlighted_post.title": "가장 인기있는 게시물", "annual_report.summary.most_used_app.most_used_app": "가장 많이 사용한 앱", "annual_report.summary.most_used_hashtag.most_used_hashtag": "가장 많이 사용한 해시태그", - "annual_report.summary.most_used_hashtag.none": "없음", "annual_report.summary.new_posts.new_posts": "새 게시물", "annual_report.summary.percentile.text": "{domain} 사용자의 상위입니다.", "annual_report.summary.percentile.we_wont_tell_bernie": "종부세는 안 걷을게요", - "annual_report.summary.thanks": "마스토돈과 함께 해주셔서 감사합니다!", + "annual_report.summary.share_message": "나는 {archetype} 특성을 부여받았습니다!", "attachments_list.unprocessed": "(처리 안 됨)", "audio.hide": "소리 숨기기", "block_modal.remote_users_caveat": "우리는 {domain} 서버가 당신의 결정을 존중해 주길 부탁할 것입니다. 하지만 몇몇 서버는 차단을 다르게 취급할 수 있기 때문에 규정이 준수되는 것을 보장할 수는 없습니다. 공개 게시물은 로그인 하지 않은 사용자들에게 여전히 보여질 수 있습니다.", @@ -513,6 +526,7 @@ "keyboard_shortcuts.toggle_hidden": "CW로 가려진 텍스트를 표시/비표시", "keyboard_shortcuts.toggle_sensitivity": "미디어 보이기/숨기기", "keyboard_shortcuts.toot": "새 게시물 작성", + "keyboard_shortcuts.top": "목록의 최상단으로 이동", "keyboard_shortcuts.translate": "게시물 번역", "keyboard_shortcuts.unfocus": "작성창에서 포커스 해제", "keyboard_shortcuts.up": "리스트에서 위로 이동", diff --git a/app/javascript/mastodon/locales/ku.json b/app/javascript/mastodon/locales/ku.json index f2efc7f3c68889..778ff2684a5635 100644 --- a/app/javascript/mastodon/locales/ku.json +++ b/app/javascript/mastodon/locales/ku.json @@ -95,9 +95,6 @@ "alt_text_modal.change_thumbnail": "Wêneyê biçûk biguherîne", "alt_text_modal.done": "Qediya", "announcement.announcement": "Daxuyanî", - "annual_report.summary.followers.followers": "şopîner", - "annual_report.summary.followers.total": "{count} tevahî", - "annual_report.summary.most_used_hashtag.none": "Ne yek", "annual_report.summary.new_posts.new_posts": "şandiyên nû", "attachments_list.unprocessed": "(bêpêvajo)", "audio.hide": "Dengê veşêre", diff --git a/app/javascript/mastodon/locales/lad.json b/app/javascript/mastodon/locales/lad.json index 9e6f503983289e..4ba1450029c0df 100644 --- a/app/javascript/mastodon/locales/lad.json +++ b/app/javascript/mastodon/locales/lad.json @@ -109,18 +109,9 @@ "alt_text_modal.change_thumbnail": "Troka minyatura", "alt_text_modal.done": "Fecho", "announcement.announcement": "Pregon", - "annual_report.summary.archetype.pollster": "El anketero", - "annual_report.summary.followers.followers": "suivantes", - "annual_report.summary.followers.total": "{count} en total", - "annual_report.summary.highlighted_post.by_favourites": "la puvlikasyon mas favoritada", - "annual_report.summary.highlighted_post.by_reblogs": "la puvlikasyon mas repartajada", - "annual_report.summary.highlighted_post.by_replies": "la puvlikasyon kon mas repuestas", - "annual_report.summary.highlighted_post.possessive": "de {name}", "annual_report.summary.most_used_app.most_used_app": "la aplikasyon mas uzada", "annual_report.summary.most_used_hashtag.most_used_hashtag": "la etiketa mas uzada", - "annual_report.summary.most_used_hashtag.none": "Dinguno", "annual_report.summary.new_posts.new_posts": "puvlikasyones muevas", - "annual_report.summary.thanks": "Mersi por ser parte de Mastodon!", "attachments_list.unprocessed": "(no prosesado)", "audio.hide": "Eskonde audio", "block_modal.show_less": "Amostra manko", diff --git a/app/javascript/mastodon/locales/lt.json b/app/javascript/mastodon/locales/lt.json index f9edb7bfb55dd9..f6da5eb6326b16 100644 --- a/app/javascript/mastodon/locales/lt.json +++ b/app/javascript/mastodon/locales/lt.json @@ -117,26 +117,12 @@ "annual_report.announcement.action_view": "Peržiūrėti mano Wrapstodon", "annual_report.announcement.description": "Sužinokite daugiau apie savo aktyvumą Mastodon\"e per pastaruosius metus.", "annual_report.announcement.title": "Wrapstodon {year} jau čia", - "annual_report.summary.archetype.booster": "Šaunus medžiotojas", - "annual_report.summary.archetype.lurker": "Stebėtojas", - "annual_report.summary.archetype.oracle": "Vydūnas", - "annual_report.summary.archetype.pollster": "Apklausos rengėjas", - "annual_report.summary.archetype.replier": "Socialinis drugelis", - "annual_report.summary.followers.followers": "sekėjai (-ų)", - "annual_report.summary.followers.total": "iš viso {count}", - "annual_report.summary.here_it_is": "Štai jūsų {year} apžvalga:", - "annual_report.summary.highlighted_post.by_favourites": "labiausiai pamėgtas įrašas", - "annual_report.summary.highlighted_post.by_reblogs": "labiausiai pasidalintas įrašas", - "annual_report.summary.highlighted_post.by_replies": "įrašas su daugiausiai atsakymų", - "annual_report.summary.highlighted_post.possessive": "{name}", "annual_report.summary.most_used_app.most_used_app": "labiausiai naudota programa", "annual_report.summary.most_used_hashtag.most_used_hashtag": "labiausiai naudota grotažymė", - "annual_report.summary.most_used_hashtag.none": "Nieko", "annual_report.summary.new_posts.new_posts": "nauji įrašai", "annual_report.summary.percentile.text": "Tai reiškia, kad esate tarppopuliariausių {domain} naudotojų.", "annual_report.summary.percentile.we_wont_tell_bernie": "Mes nesakysime Bernie.", "annual_report.summary.share_message": "Aš gavau „{archetype}“!", - "annual_report.summary.thanks": "Dėkojame, kad esate „Mastodon“ dalis!", "attachments_list.unprocessed": "(neapdorotas)", "audio.hide": "Slėpti garsą", "block_modal.remote_users_caveat": "Paprašysime serverio {domain} gerbti tavo sprendimą. Tačiau atitiktis negarantuojama, nes kai kurie serveriai gali skirtingai tvarkyti blokavimus. Vieši įrašai vis tiek gali būti matomi neprisijungusiems naudotojams.", diff --git a/app/javascript/mastodon/locales/lv.json b/app/javascript/mastodon/locales/lv.json index eeda75d85d190c..260b4486b85cab 100644 --- a/app/javascript/mastodon/locales/lv.json +++ b/app/javascript/mastodon/locales/lv.json @@ -113,23 +113,11 @@ "alt_text_modal.describe_for_people_with_visual_impairments": "Aprakstīt šo cilvēkiem ar redzes traucējumiem…", "alt_text_modal.done": "Gatavs", "announcement.announcement": "Paziņojums", - "annual_report.summary.archetype.lurker": "Glūņa", - "annual_report.summary.archetype.oracle": "Orākuls", - "annual_report.summary.archetype.replier": "Sabiedriskais tauriņš", - "annual_report.summary.followers.followers": "sekotāji", - "annual_report.summary.followers.total": "pavisam {count}", - "annual_report.summary.here_it_is": "Šeit ir {year}. gada pārskats:", - "annual_report.summary.highlighted_post.by_favourites": "izlasēm visvairāk pievienotais ieraksts", - "annual_report.summary.highlighted_post.by_reblogs": "vispastiprinātākais ieraksts", - "annual_report.summary.highlighted_post.by_replies": "ieraksts ar vislielāko atbilžu skaitu", - "annual_report.summary.highlighted_post.possessive": "{name}", "annual_report.summary.most_used_app.most_used_app": "visizmantotākā lietotne", "annual_report.summary.most_used_hashtag.most_used_hashtag": "visizmantotākais tēmturis", - "annual_report.summary.most_used_hashtag.none": "Nav", "annual_report.summary.new_posts.new_posts": "jauni ieraksti", "annual_report.summary.percentile.text": "Tas ievieto Tevi virsējosno {domain} lietotājiem.", "annual_report.summary.percentile.we_wont_tell_bernie": "Mēs neteiksim Bērnijam.", - "annual_report.summary.thanks": "Paldies, ka esi daļa no Mastodon!", "attachments_list.unprocessed": "(neapstrādāti)", "audio.hide": "Slēpt audio", "block_modal.remote_users_caveat": "Mēs lūgsim serverim {domain} ņemt vērā Tavu lēmumu. Tomēr sadarbība nav garantēta, jo atsevišķi serveri bloķēšanu var apstrādāt citādi. Publiski ieraksti, iespējams, joprojām būs redzami lietotājiem, kuri nav pieteikušies.", @@ -244,7 +232,9 @@ "confirmations.missing_alt_text.title": "Pievienot aprakstošo tekstu?", "confirmations.mute.confirm": "Apklusināt", "confirmations.private_quote_notify.cancel": "Atgriezties pie labošanas", + "confirmations.private_quote_notify.confirm": "Publicēt ierakstu", "confirmations.private_quote_notify.do_not_show_again": "Nerādīt vairāk šo paziņojumu", + "confirmations.private_quote_notify.title": "Dalīties ar sekotājiem un pieminētajiem lietotājiem?", "confirmations.quiet_post_quote_info.got_it": "Sapratu", "confirmations.redraft.confirm": "Dzēst un pārrakstīt", "confirmations.redraft.message": "Vai tiešām vēlies izdzēst šo ierakstu un veidot jaunu tā uzmetumu? Pievienošana izlasēs un pastiprinājumi tiks zaudēti, un sākotnējā ieraksta atbildes paliks bez saiknes ar to.", @@ -423,6 +413,9 @@ "home.pending_critical_update.title": "Ir pieejams būtisks drošības atjauninājums.", "home.show_announcements": "Rādīt paziņojumus", "ignore_notifications_modal.ignore": "Neņemt vērā paziņojumus", + "ignore_notifications_modal.limited_accounts_title": "Neņemt vērā paziņojumus no moderētiem kontiem?", + "ignore_notifications_modal.new_accounts_title": "Neņemt vērā paziņojumus no jauniem kontiem?", + "ignore_notifications_modal.not_followers_title": "Neņemt vērā paziņojumus no cilvēkiem, kas tev neseko?", "ignore_notifications_modal.not_following_title": "Neņemt vērā paziņojumus no cilvēkiem, kuriem neseko?", "info_button.label": "Palīdzība", "interaction_modal.go": "Aiziet", @@ -457,6 +450,7 @@ "keyboard_shortcuts.open_media": "Atvērt multividi", "keyboard_shortcuts.pinned": "Atvērt piesprausto ierakstu sarakstu", "keyboard_shortcuts.profile": "Atvērt autora profilu", + "keyboard_shortcuts.quote": "Citēt ierakstu", "keyboard_shortcuts.reply": "Atbildēt", "keyboard_shortcuts.requests": "Atvērt sekošanas pieprasījumu sarakstu", "keyboard_shortcuts.search": "Fokusēt meklēšanas joslu", diff --git a/app/javascript/mastodon/locales/ms.json b/app/javascript/mastodon/locales/ms.json index 46011b09a82087..71013cf3e6db15 100644 --- a/app/javascript/mastodon/locales/ms.json +++ b/app/javascript/mastodon/locales/ms.json @@ -94,25 +94,11 @@ "alt_text_modal.describe_for_people_with_visual_impairments": "Terangkan untuk OKU penglihatan…", "alt_text_modal.done": "Selesai", "announcement.announcement": "Pengumuman", - "annual_report.summary.archetype.booster": "Si pencapap", - "annual_report.summary.archetype.lurker": "Si penghendap", - "annual_report.summary.archetype.oracle": "Si penilik", - "annual_report.summary.archetype.pollster": "Si peninjau", - "annual_report.summary.archetype.replier": "Si peramah", - "annual_report.summary.followers.followers": "pengikut", - "annual_report.summary.followers.total": "sebanyak {count}", - "annual_report.summary.here_it_is": "Ini ulasan {year} anda:", - "annual_report.summary.highlighted_post.by_favourites": "hantaran paling disukai ramai", - "annual_report.summary.highlighted_post.by_reblogs": "hantaran paling digalak ramai", - "annual_report.summary.highlighted_post.by_replies": "hantaran paling dibalas ramai", - "annual_report.summary.highlighted_post.possessive": "oleh", "annual_report.summary.most_used_app.most_used_app": "aplikasi paling banyak digunakan", "annual_report.summary.most_used_hashtag.most_used_hashtag": "tanda pagar paling banyak digunakan", - "annual_report.summary.most_used_hashtag.none": "Tiada", "annual_report.summary.new_posts.new_posts": "hantaran baharu", "annual_report.summary.percentile.text": "Anda berkedudukan pengguna {domain}.", "annual_report.summary.percentile.we_wont_tell_bernie": "Rahsia anda selamat bersama kami. ;)", - "annual_report.summary.thanks": "Terima kasih kerana setia bersama Mastodon!", "attachments_list.unprocessed": "(belum diproses)", "audio.hide": "Sembunyikan audio", "block_modal.remote_users_caveat": "Kami akan meminta pelayan {domain} untuk menghormati keputusan anda. Bagaimanapun, pematuhan tidak dijamin kerana ada pelayan yang mungkin menangani sekatan dengan cara berbeza. Hantaran awam mungkin masih tampak kepada pengguna yang tidak log masuk.", diff --git a/app/javascript/mastodon/locales/nan.json b/app/javascript/mastodon/locales/nan.json index 9f5e53ef2449e3..366f568f0a44b3 100644 --- a/app/javascript/mastodon/locales/nan.json +++ b/app/javascript/mastodon/locales/nan.json @@ -114,29 +114,50 @@ "alt_text_modal.done": "做好ah", "announcement.announcement": "公告", "annual_report.announcement.action_build": "建立我ê Wrapstodon", + "annual_report.announcement.action_dismiss": "毋免,多謝。", "annual_report.announcement.action_view": "看我ê Wrapstodon", "annual_report.announcement.description": "發現其他關係lí佇最近tsi̍t年參與Mastodon ê狀況。", "annual_report.announcement.title": "Wrapstodon {year} 已經kàu ah", - "annual_report.summary.archetype.booster": "追求趣味ê", - "annual_report.summary.archetype.lurker": "有讀無PO ê", - "annual_report.summary.archetype.oracle": "先知", - "annual_report.summary.archetype.pollster": "愛發動投票ê", - "annual_report.summary.archetype.replier": "社交ê蝴蝶", - "annual_report.summary.followers.followers": "跟tuè lí ê", - "annual_report.summary.followers.total": "Lóng總有 {count} ê", - "annual_report.summary.here_it_is": "下kha是lí {year} 年ê回顧:", - "annual_report.summary.highlighted_post.by_favourites": "Hōo足tsē lâng收藏ê PO文", - "annual_report.summary.highlighted_post.by_reblogs": "Hōo足tsē lâng轉ê PO文", - "annual_report.summary.highlighted_post.by_replies": "有上tsē回應ê PO文", - "annual_report.summary.highlighted_post.possessive": "{name} ê", + "annual_report.nav_item.badge": "新ê", + "annual_report.shared_page.donate": "寄付", + "annual_report.shared_page.footer": "由 Mastodon 團隊用 {heart} 產生", + "annual_report.summary.archetype.booster.desc_public": "{name} 不斷走tshuē通轉送 ê PO文,靠完美ê對千,放大其他ê創作者。", + "annual_report.summary.archetype.booster.desc_self": " Lí不斷走tshuē通轉送 ê PO文,靠完美ê對千,放大其他ê創作者。", + "annual_report.summary.archetype.booster.name": "射手", + "annual_report.summary.archetype.die_drei_fragezeichen": "???", + "annual_report.summary.archetype.lurker.desc_public": "Guán知 {name} 捌佇某物所在,用伊恬靜ê方法享受Mastodon。", + "annual_report.summary.archetype.lurker.desc_self": "Guán知lí捌佇某物所在,用li恬靜ê方法享受Mastodon。", + "annual_report.summary.archetype.lurker.name": "Stoic主義者", + "annual_report.summary.archetype.oracle.desc_public": "{name} 發表ê新ê PO文較tsē回應,保持 Mastodon tshinn-tshioh kap面對未來。", + "annual_report.summary.archetype.oracle.desc_self": "Lí發表ê新ê PO文較tsē回應,保持 Mastodon tshinn-tshioh kap面對未來。", + "annual_report.summary.archetype.oracle.name": "先知", + "annual_report.summary.archetype.pollster.desc_public": "{name} 建立投票較tsē其他PO文類型,佇Mastodon培養好奇。", + "annual_report.summary.archetype.pollster.desc_self": "Lí建立投票較tsē其他PO文類型,佇Mastodon培養好奇。", + "annual_report.summary.archetype.pollster.name": "思考者", + "annual_report.summary.archetype.replier.desc_public": "{name} 定定應別lâng ê PO文,用新ê討論kā Mastodon授粉。", + "annual_report.summary.archetype.replier.desc_self": "You 定定應別lâng ê PO文,用新ê討論kā Mastodon授粉。", + "annual_report.summary.archetype.replier.name": "Ia̍h仔", + "annual_report.summary.archetype.reveal": "顯露我ê原形", + "annual_report.summary.archetype.reveal_description": "感謝lí成做Mastodon ê一部份!Tsit-má tshuē出lí佇 {year} 年表現ê原形。", + "annual_report.summary.archetype.title_public": "{name} ê原形", + "annual_report.summary.archetype.title_self": "Lí ê原形", + "annual_report.summary.close": "關", + "annual_report.summary.copy_link": "Khóo-pih連結", + "annual_report.summary.followers.new_followers": "{count, plural, other {新ê跟tuè ê}}", + "annual_report.summary.highlighted_post.boost_count": "Tsit篇PO文予lâng轉送 {count, plural, other {# kái}}。", + "annual_report.summary.highlighted_post.favourite_count": "Tsit篇PO文予lâng收藏 {count, plural, other {# kái}}。", + "annual_report.summary.highlighted_post.reply_count": "Tsit篇PO文得著 {count, plural, other {# 篇回應}}。", + "annual_report.summary.highlighted_post.title": "上hang ê PO文", "annual_report.summary.most_used_app.most_used_app": "上tsē lâng用ê app", "annual_report.summary.most_used_hashtag.most_used_hashtag": "上tsia̍p用ê hashtag", - "annual_report.summary.most_used_hashtag.none": "無", + "annual_report.summary.most_used_hashtag.used_count": "Lí佇{count, plural, other { # 篇PO文}}內包含tsit ê hashtag。", + "annual_report.summary.most_used_hashtag.used_count_public": "{name} 佇{count, plural, other { # 篇PO文}}內包含tsit ê hashtag。", "annual_report.summary.new_posts.new_posts": "新ê PO文", "annual_report.summary.percentile.text": "Tse 予lí變做 {domain} ê用戶ê ", "annual_report.summary.percentile.we_wont_tell_bernie": "Gún bē kā Bernie講。", + "annual_report.summary.share_elsewhere": "分享kàu別位", "annual_report.summary.share_message": "我得著 {archetype} ê典型!", - "annual_report.summary.thanks": "多謝成做Mastodon ê成員!", + "annual_report.summary.share_on_mastodon": "佇Mastodon分享", "attachments_list.unprocessed": "(Iáu bē處理)", "audio.hide": "Tshàng聲音", "block_modal.remote_users_caveat": "Guán ē要求服侍器 {domain} 尊重lí ê決定。但是bô法度保證ta̍k ê服侍器lóng遵守,因為tsi̍t-kuá服侍器huân-sè用別款方法處理封鎖。公開ê PO文可能iáu是ē hōo bô登入ê用者看著。", diff --git a/app/javascript/mastodon/locales/ne.json b/app/javascript/mastodon/locales/ne.json index 5b6b0994864ab3..2d861e470be3a1 100644 --- a/app/javascript/mastodon/locales/ne.json +++ b/app/javascript/mastodon/locales/ne.json @@ -77,8 +77,6 @@ "alert.unexpected.message": "एउटा अनपेक्षित त्रुटि भयो।", "alt_text_modal.cancel": "रद्द गर्नुहोस्", "announcement.announcement": "घोषणा", - "annual_report.summary.followers.followers": "फलोअरहरु", - "annual_report.summary.highlighted_post.by_reblogs": "सबैभन्दा बढि बूस्ट गरिएको पोस्ट", "annual_report.summary.new_posts.new_posts": "नयाँ पोस्टहरू", "block_modal.remote_users_caveat": "हामी सर्भर {domain} लाई तपाईंको निर्णयको सम्मान गर्न सोध्नेछौं। तर, हामी अनुपालनको ग्यारेन्टी दिन सक्दैनौं किनभने केही सर्भरहरूले ब्लकहरू फरक रूपमा ह्यान्डल गर्न सक्छन्। सार्वजनिक पोस्टहरू लग इन नभएका प्रयोगकर्ताहरूले देख्न सक्छन्।", "block_modal.show_less": "कम देखाउनुहोस्", diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json index 28406163ba40e4..792f6afd1dd016 100644 --- a/app/javascript/mastodon/locales/nl.json +++ b/app/javascript/mastodon/locales/nl.json @@ -114,29 +114,51 @@ "alt_text_modal.done": "Klaar", "announcement.announcement": "Mededeling", "annual_report.announcement.action_build": "Bouw mijn Wrapstodon", + "annual_report.announcement.action_dismiss": "Nee, bedankt", "annual_report.announcement.action_view": "Bekijk mijn Wrapstodon", "annual_report.announcement.description": "Ontdek meer over jouw engagement op Mastodon over het afgelopen jaar.", "annual_report.announcement.title": "Wrapstodon {year} is gearriveerd", - "annual_report.summary.archetype.booster": "De cool-hunter", - "annual_report.summary.archetype.lurker": "De lurker", - "annual_report.summary.archetype.oracle": "Het orakel", - "annual_report.summary.archetype.pollster": "De opiniepeiler", - "annual_report.summary.archetype.replier": "De sociale vlinder", - "annual_report.summary.followers.followers": "volgers", - "annual_report.summary.followers.total": "totaal {count}", - "annual_report.summary.here_it_is": "Hier is jouw terugblik op {year}:", - "annual_report.summary.highlighted_post.by_favourites": "bericht met de meeste favorieten", - "annual_report.summary.highlighted_post.by_reblogs": "bericht met de meeste boosts", - "annual_report.summary.highlighted_post.by_replies": "bericht met de meeste reacties", - "annual_report.summary.highlighted_post.possessive": "{name}'s", + "annual_report.nav_item.badge": "Nieuw", + "annual_report.shared_page.donate": "Doneren", + "annual_report.shared_page.footer": "Met {heart} gegenereerd door het Mastodonteam", + "annual_report.shared_page.footer_server_info": "{username} gebruikt {domain}, een van de vele door Mastodon mogelijk gemaakte gemeenschappen.", + "annual_report.summary.archetype.booster.desc_public": "{name} bleef op jacht naar berichten om te kunnen boosten, waardoor het geluid van andere gebruikers werd versterkt.", + "annual_report.summary.archetype.booster.desc_self": "Jij bleef op jacht naar berichten om te kunnen boosten, waardoor je het geluid van andere gebruikers versterkte.", + "annual_report.summary.archetype.booster.name": "De Boogschutter", + "annual_report.summary.archetype.die_drei_fragezeichen": "???", + "annual_report.summary.archetype.lurker.desc_public": "We weten dat {name} ergens in stilte van Mastodon aan het genieten was.", + "annual_report.summary.archetype.lurker.desc_self": "We weten dat je ergens in stilte van Mastodon aan het genieten was.", + "annual_report.summary.archetype.lurker.name": "De Stoïcijn", + "annual_report.summary.archetype.oracle.desc_public": "{name} heeft meer nieuwe berichten dan reacties geplaatst, waardoor Mastodon fris en toekomstgericht blijft.", + "annual_report.summary.archetype.oracle.desc_self": "Je hebt meer nieuwe berichten dan reacties geplaatst, waardoor Mastodon fris en toekomstgericht blijft.", + "annual_report.summary.archetype.oracle.name": "Het Orakel", + "annual_report.summary.archetype.pollster.desc_public": "{name} heeft meer polls aangemaakt dan andere soorten berichten, en daarmee de nieuwsgierigheid op Mastodon gecultiveerd.", + "annual_report.summary.archetype.pollster.desc_self": "Je hebt meer polls aangemaakt dan andere soorten berichten, en daarmee de nieuwsgierigheid op Mastodon gecultiveerd.", + "annual_report.summary.archetype.pollster.name": "De Dromer", + "annual_report.summary.archetype.replier.desc_public": "{name} reageerde regelmatig op berichten van andere mensen, waardoor nieuwe discussies op Mastodon tot bloei kwamen.", + "annual_report.summary.archetype.replier.desc_self": "Je reageerde regelmatig op berichten van andere mensen, waardoor nieuwe discussies op Mastodon tot bloei kwamen.", + "annual_report.summary.archetype.replier.name": "De Vlinder", + "annual_report.summary.archetype.reveal": "Onthul mijn archetype", + "annual_report.summary.archetype.reveal_description": "Bedankt dat je deel uitmaakt van Mastodon! Tijd om te ontdekken welk archetype je in {year} belichaamde.", + "annual_report.summary.archetype.title_public": "Het archetype van {name}", + "annual_report.summary.archetype.title_self": "Jouw archetype", + "annual_report.summary.close": "Sluiten", + "annual_report.summary.copy_link": "Link kopiëren", + "annual_report.summary.followers.new_followers": "{count, plural, one {nieuwe volger} other {nieuwe volgers}}", + "annual_report.summary.highlighted_post.boost_count": "Dit bericht is {count, plural, one {één keer} other {# keer}} geboost.", + "annual_report.summary.highlighted_post.favourite_count": "Dit bericht is {count, plural, one {één keer} other {# keer}} als favoriet gemarkeerd.", + "annual_report.summary.highlighted_post.reply_count": "Dit bericht heeft {count, plural, one {één reactie} other {# reacties}}.", + "annual_report.summary.highlighted_post.title": "Meest populaire berichten", "annual_report.summary.most_used_app.most_used_app": "meest gebruikte app", "annual_report.summary.most_used_hashtag.most_used_hashtag": "meest gebruikte hashtag", - "annual_report.summary.most_used_hashtag.none": "Geen", + "annual_report.summary.most_used_hashtag.used_count": "Je hebt deze hashtag in {count, plural, one{één bericht} other {# berichten}} gebruikt.", + "annual_report.summary.most_used_hashtag.used_count_public": "{name} heeft deze hashtag in {count, plural, one {één bericht} other {# berichten}} gebruikt.", "annual_report.summary.new_posts.new_posts": "nieuwe berichten", "annual_report.summary.percentile.text": "Hiermee behoor je tot de top van {domain}.", "annual_report.summary.percentile.we_wont_tell_bernie": "We zullen Bernie niets vertellen.", + "annual_report.summary.share_elsewhere": "Ergens anders delen", "annual_report.summary.share_message": "Ik heb het archetype {archetype}!", - "annual_report.summary.thanks": "Bedankt dat je deel uitmaakt van Mastodon!", + "annual_report.summary.share_on_mastodon": "Op Mastodon delen", "attachments_list.unprocessed": "(niet verwerkt)", "audio.hide": "Audio verbergen", "block_modal.remote_users_caveat": "We vragen de server {domain} om je besluit te respecteren. Het naleven hiervan is echter niet gegarandeerd, omdat sommige servers blokkades anders kunnen interpreteren. Openbare berichten zijn mogelijk nog steeds zichtbaar voor niet-ingelogde gebruikers.", @@ -419,6 +441,8 @@ "follow_suggestions.who_to_follow": "Wie te volgen", "followed_tags": "Gevolgde hashtags", "footer.about": "Over", + "footer.about_mastodon": "Over Mastodon", + "footer.about_server": "Over {domain}", "footer.about_this_server": "Over", "footer.directory": "Gebruikersgids", "footer.get_app": "App downloaden", diff --git a/app/javascript/mastodon/locales/nn.json b/app/javascript/mastodon/locales/nn.json index 6180bd4c6558e1..7ab269682bf529 100644 --- a/app/javascript/mastodon/locales/nn.json +++ b/app/javascript/mastodon/locales/nn.json @@ -117,25 +117,11 @@ "annual_report.announcement.action_view": "Sjå min Årstodon", "annual_report.announcement.description": "Sjå meir om kva du har gjort på Mastodon siste året.", "annual_report.announcement.title": "Årstodon {year} er her", - "annual_report.summary.archetype.booster": "Den som jaktar på noko kult", - "annual_report.summary.archetype.lurker": "Den som heng på hjørnet", - "annual_report.summary.archetype.oracle": "Orakelet", - "annual_report.summary.archetype.pollster": "Meiningsmålaren", - "annual_report.summary.archetype.replier": "Den sosiale sumarfuglen", - "annual_report.summary.followers.followers": "fylgjarar", - "annual_report.summary.followers.total": "{count} i alt", - "annual_report.summary.here_it_is": "Her er eit gjensyn med {year}:", - "annual_report.summary.highlighted_post.by_favourites": "det mest omtykte innlegget", - "annual_report.summary.highlighted_post.by_reblogs": "det mest framheva innlegget", - "annual_report.summary.highlighted_post.by_replies": "innlegget med flest svar", - "annual_report.summary.highlighted_post.possessive": "som {name} laga", "annual_report.summary.most_used_app.most_used_app": "mest brukte app", "annual_report.summary.most_used_hashtag.most_used_hashtag": "mest brukte emneknagg", - "annual_report.summary.most_used_hashtag.none": "Ingen", "annual_report.summary.new_posts.new_posts": "nye innlegg", "annual_report.summary.percentile.text": "Du er av deiivrigaste brukarane på {domain}.", "annual_report.summary.percentile.we_wont_tell_bernie": "Ikkje eit ord til pressa.", - "annual_report.summary.thanks": "Takk for at du er med i Mastodon!", "attachments_list.unprocessed": "(ubehandla)", "audio.hide": "Gøym lyd", "block_modal.remote_users_caveat": "Me vil be tenaren {domain} om å respektera di avgjerd. Me kan ikkje garantera at det vert gjort, sidan nokre tenarar kan handtera blokkering ulikt. Offentlege innlegg kan framleis vera synlege for ikkje-innlogga brukarar.", diff --git a/app/javascript/mastodon/locales/no.json b/app/javascript/mastodon/locales/no.json index 8cb67c97b06612..8a2ce940eadaa4 100644 --- a/app/javascript/mastodon/locales/no.json +++ b/app/javascript/mastodon/locales/no.json @@ -107,25 +107,11 @@ "alt_text_modal.describe_for_people_with_visual_impairments": "Beskriv dette for folk med synsproblemer…", "alt_text_modal.done": "Ferdig", "announcement.announcement": "Kunngjøring", - "annual_report.summary.archetype.booster": "Den iskalde jeger", - "annual_report.summary.archetype.lurker": "Det snikende ullteppe", - "annual_report.summary.archetype.oracle": "Allviteren", - "annual_report.summary.archetype.pollster": "Meningsmåleren", - "annual_report.summary.archetype.replier": "Festens midtpunkt", - "annual_report.summary.followers.followers": "følgere", - "annual_report.summary.followers.total": "{count} tilsammen", - "annual_report.summary.here_it_is": "Her er ditt {year} ditt sett sammlet:", - "annual_report.summary.highlighted_post.by_favourites": "mest likte innlegg", - "annual_report.summary.highlighted_post.by_reblogs": "mest opphøyde innlegg", - "annual_report.summary.highlighted_post.by_replies": "innlegg med de fleste tilbakemeldinger", - "annual_report.summary.highlighted_post.possessive": "{name}", "annual_report.summary.most_used_app.most_used_app": "mest brukte applikasjoner", "annual_report.summary.most_used_hashtag.most_used_hashtag": "mest brukte evne knagg", - "annual_report.summary.most_used_hashtag.none": "Ingen", "annual_report.summary.new_posts.new_posts": "nye innlegg", "annual_report.summary.percentile.text": "Det gjør at du er i toppav brukere på {domain}.", "annual_report.summary.percentile.we_wont_tell_bernie": "Vi skal ikke si noe til Bernie.", - "annual_report.summary.thanks": "Takk for at du er med på Mastodon!", "attachments_list.unprocessed": "(ubehandlet)", "audio.hide": "Skjul lyd", "block_modal.remote_users_caveat": "Vi vil be serveren {domain} om å respektere din beslutning. Det er imidlertid ingen garanti at det blir overholdt, siden noen servere kan håndtere blokkeringer på forskjellig vis. Offentlige innlegg kan fortsatt være synlige for ikke-innloggede brukere.", diff --git a/app/javascript/mastodon/locales/oc.json b/app/javascript/mastodon/locales/oc.json index 549203306bc2e3..d1d8daa2115423 100644 --- a/app/javascript/mastodon/locales/oc.json +++ b/app/javascript/mastodon/locales/oc.json @@ -91,8 +91,6 @@ "alt_text_modal.change_thumbnail": "Cambiar de miniatura", "alt_text_modal.done": "Acabat", "announcement.announcement": "Anóncia", - "annual_report.summary.followers.followers": "seguidors", - "annual_report.summary.followers.total": "{count} en total", "attachments_list.unprocessed": "(pas tractat)", "audio.hide": "Amagar àudio", "block_modal.show_less": "Ne veire mens", diff --git a/app/javascript/mastodon/locales/pa.json b/app/javascript/mastodon/locales/pa.json index 5d49bfa40a1451..3f519d8c0959e2 100644 --- a/app/javascript/mastodon/locales/pa.json +++ b/app/javascript/mastodon/locales/pa.json @@ -85,16 +85,8 @@ "alt_text_modal.cancel": "ਰੱਦ ਕਰੋ", "alt_text_modal.done": "ਮੁਕੰਮਲ", "announcement.announcement": "ਹੋਕਾ", - "annual_report.summary.followers.followers": "ਫ਼ਾਲੋਅਰ", - "annual_report.summary.followers.total": "{count} ਕੁੱਲ", - "annual_report.summary.highlighted_post.by_favourites": "ਸਭ ਤੋਂ ਵੱਧ ਪਸੰਦ ਕੀਤੀ ਪੋਸਟ", - "annual_report.summary.highlighted_post.by_reblogs": "ਸਭ ਤੋਂ ਵੱਧ ਬੂਸਟ ਕੀਤੀ ਪੋਸਟ", - "annual_report.summary.highlighted_post.by_replies": "ਸਭ ਤੋਂ ਵੱਧ ਜਵਾਬ ਦਿੱਤੀ ਗਈ ਪੋਸਟ", - "annual_report.summary.highlighted_post.possessive": "{name}", "annual_report.summary.most_used_app.most_used_app": "ਸਭ ਤੋਂ ਵੱਧ ਵਰਤੀ ਐਪ", - "annual_report.summary.most_used_hashtag.none": "ਕੋਈ ਨਹੀਂ", "annual_report.summary.new_posts.new_posts": "ਨਵੀਆਂ ਪੋਸਟਾਂ", - "annual_report.summary.thanks": "Mastodon ਦਾ ਹਿੱਸਾ ਬਣਨ ਵਾਸਤੇ ਧੰਨਵਾਦ ਹੈ!", "audio.hide": "ਆਡੀਓ ਨੂੰ ਲੁਕਾਓ", "block_modal.show_less": "ਘੱਟ ਦਿਖਾਓ", "block_modal.show_more": "ਵੱਧ ਦਿਖਾਓ", diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json index 8f2d33c5fa6875..a6fd027f7ac3d9 100644 --- a/app/javascript/mastodon/locales/pl.json +++ b/app/javascript/mastodon/locales/pl.json @@ -113,25 +113,11 @@ "alt_text_modal.describe_for_people_with_visual_impairments": "Opisz to dla osób niedowidzących…", "alt_text_modal.done": "Gotowe", "announcement.announcement": "Ogłoszenie", - "annual_report.summary.archetype.booster": "Łowca treści", - "annual_report.summary.archetype.lurker": "Czyhający", - "annual_report.summary.archetype.oracle": "Wyrocznia", - "annual_report.summary.archetype.pollster": "Ankieter", - "annual_report.summary.archetype.replier": "Towarzyski motyl", - "annual_report.summary.followers.followers": "obserwujących", - "annual_report.summary.followers.total": "łącznie {count}", - "annual_report.summary.here_it_is": "Oto przegląd twojego {year} roku:", - "annual_report.summary.highlighted_post.by_favourites": "najbardziej lubiany wpis", - "annual_report.summary.highlighted_post.by_reblogs": "najczęściej podbijany wpis", - "annual_report.summary.highlighted_post.by_replies": "wpis z największą liczbą komentarzy", - "annual_report.summary.highlighted_post.possessive": "{name}", "annual_report.summary.most_used_app.most_used_app": "najczęściej używana aplikacja", "annual_report.summary.most_used_hashtag.most_used_hashtag": "najczęściej używany hashtag", - "annual_report.summary.most_used_hashtag.none": "Brak", "annual_report.summary.new_posts.new_posts": "nowe wpisy", "annual_report.summary.percentile.text": "To plasuje cię w czołówce użytkowników {domain}.", "annual_report.summary.percentile.we_wont_tell_bernie": "Nie powiemy Berniemu.", - "annual_report.summary.thanks": "Dziękujemy, że jesteś częścią Mastodona!", "attachments_list.unprocessed": "(nieprzetworzone)", "audio.hide": "Ukryj dźwięk", "block_modal.remote_users_caveat": "Poprosimy serwer {domain} o uszanowanie twojej decyzji. Nie jest to jednak gwarantowane, bo niektóre serwery mogą obsługiwać blokady w inny sposób. Publiczne wpisy mogą być nadal widoczne dla niezalogowanych użytkowników.", diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json index 158da029d71881..cb5c7028880c88 100644 --- a/app/javascript/mastodon/locales/pt-BR.json +++ b/app/javascript/mastodon/locales/pt-BR.json @@ -11,7 +11,7 @@ "about.domain_blocks.suspended.title": "Suspenso", "about.language_label": "Idioma", "about.not_available": "Esta informação não foi disponibilizada neste servidor.", - "about.powered_by": "Redes sociais descentralizadas alimentadas por {mastodon}", + "about.powered_by": "Rede social descentralizada baseada no {mastodon}", "about.rules": "Regras do servidor", "account.account_note_header": "Nota pessoal", "account.add_or_remove_from_list": "Adicionar ou remover de listas", @@ -55,8 +55,8 @@ "account.follows.empty": "Nada aqui.", "account.follows_you": "Segue você", "account.go_to_profile": "Ir ao perfil", - "account.hide_reblogs": "Ocultar impulsionamentos de @{name}", - "account.in_memoriam": "Em memória.", + "account.hide_reblogs": "Ocultar impulsos de @{name}", + "account.in_memoriam": "In Memoriam.", "account.joined_short": "Entrou", "account.languages": "Mudar idiomas inscritos", "account.link_verified_on": "A propriedade deste link foi verificada em {date}", @@ -79,7 +79,7 @@ "account.requested_follow": "{name} quer te seguir", "account.requests_to_follow_you": "Pediu para seguir você", "account.share": "Compartilhar perfil de @{name}", - "account.show_reblogs": "Mostrar impulsionamentos de @{name}", + "account.show_reblogs": "Mostrar impulsos de @{name}", "account.statuses_counter": "{count, plural, one {{counter} publicação} other {{counter} publicações}}", "account.unblock": "Desbloquear @{name}", "account.unblock_domain": "Desbloquear domínio {domain}", @@ -106,36 +106,58 @@ "alert.unexpected.title": "Eita!", "alt_text_badge.title": "Texto alternativo", "alt_text_modal.add_alt_text": "Adicione texto alternativo", - "alt_text_modal.add_text_from_image": "Adicione texto da imagem", + "alt_text_modal.add_text_from_image": "Adicione texto a partir da imagem", "alt_text_modal.cancel": "Cancelar", "alt_text_modal.change_thumbnail": "Alterar miniatura", - "alt_text_modal.describe_for_people_with_hearing_impairments": "Descreva isso para pessoas com deficiências auditivas…", + "alt_text_modal.describe_for_people_with_hearing_impairments": "Descreva isto para pessoas com deficiências auditivas…", "alt_text_modal.describe_for_people_with_visual_impairments": "Descreva isto para pessoas com deficiências visuais…", "alt_text_modal.done": "Feito", "announcement.announcement": "Comunicados", "annual_report.announcement.action_build": "Gerar meu Wrapstodon", + "annual_report.announcement.action_dismiss": "Não, obrigado/a", "annual_report.announcement.action_view": "Ver meu Wrapstodon", "annual_report.announcement.description": "Descubra mais sobre seu engajamento no Mastodon ao longo do último ano.", "annual_report.announcement.title": "Chegou o Wrapstodon de {year}", - "annual_report.summary.archetype.booster": "Caçador legal", - "annual_report.summary.archetype.lurker": "O espreitador", - "annual_report.summary.archetype.oracle": "O oráculo", - "annual_report.summary.archetype.pollster": "O pesquisador", - "annual_report.summary.archetype.replier": "A borboleta social", - "annual_report.summary.followers.followers": "seguidores", - "annual_report.summary.followers.total": "{count} total", - "annual_report.summary.here_it_is": "Aqui está seu {year} em retrospectiva:", - "annual_report.summary.highlighted_post.by_favourites": "publicação mais favoritada", - "annual_report.summary.highlighted_post.by_reblogs": "publicação mais impulsionada", - "annual_report.summary.highlighted_post.by_replies": "publicação com mais respostas", - "annual_report.summary.highlighted_post.possessive": "{name}", + "annual_report.nav_item.badge": "Novo", + "annual_report.shared_page.donate": "Doe", + "annual_report.shared_page.footer": "Criado com {heart} pela equipe do Mastodon", + "annual_report.summary.archetype.booster.desc_public": "{name} se manteve na caça por publicações para impulsionar, amplificando outros criadores com uma mira perfeita.", + "annual_report.summary.archetype.booster.desc_self": "Você se manteve na caça por publicações para impulsionar, amplificando outros criadores com uma mira perfeita.", + "annual_report.summary.archetype.booster.name": "O Arqueiro", + "annual_report.summary.archetype.die_drei_fragezeichen": "???", + "annual_report.summary.archetype.lurker.desc_public": "Sabemos que {name} esteve por aí, em algum lugar, aproveitando o Mastodon do seu próprio jeito silencioso.", + "annual_report.summary.archetype.lurker.desc_self": "Sabemos que você esteve por aí, em algum lugar, aproveitando o Mastodon do seu próprio jeito silencioso.", + "annual_report.summary.archetype.lurker.name": "O Estoico", + "annual_report.summary.archetype.oracle.desc_public": "{name} criou mais publicações novas que respostas, mantendo o Mastodon fresco e em direção ao futuro.", + "annual_report.summary.archetype.oracle.desc_self": "Você criou mais publicações novas que respostas, mantendo o Mastodon fresco e em direção ao futuro.", + "annual_report.summary.archetype.oracle.name": "O Oráculo", + "annual_report.summary.archetype.pollster.desc_public": "{name} criou mais enquetes que quaisquer outros tipos de publicações, cultivando curiosidade no Mastodon.", + "annual_report.summary.archetype.pollster.desc_self": "Você criou mais enquetes que quaisquer outros tipos de publicações, cultivando curiosidade no Mastodon.", + "annual_report.summary.archetype.pollster.name": "O Questionador", + "annual_report.summary.archetype.replier.desc_public": "{name} frequentemente respondeu às publicações de outras pessoas, polinizando o Mastodon com novas discussões.", + "annual_report.summary.archetype.replier.desc_self": "Você frequentemente respondeu às publicações de outras pessoas, polinizando o Mastodon com novas discussões.", + "annual_report.summary.archetype.replier.name": "A Borboleta", + "annual_report.summary.archetype.reveal": "Revele meu arquétipo", + "annual_report.summary.archetype.reveal_description": "Obrigado por ser parte do Mastodon! Está na hora de descobrir qual arquétipo você incorporou em {year}.", + "annual_report.summary.archetype.title_public": "Arquétipo de {name}", + "annual_report.summary.archetype.title_self": "Seu arquétipo", + "annual_report.summary.close": "Fechar", + "annual_report.summary.copy_link": "Copiar link", + "annual_report.summary.followers.new_followers": "{count, plural, one {novo(a) seguidor(a)} other {novos seguidores}}", + "annual_report.summary.highlighted_post.boost_count": "Esta publicação foi impulsionada {count, plural, one {uma vez} other {# vezes}}.", + "annual_report.summary.highlighted_post.favourite_count": "Esta publicação foi favoritada {count, plural, one {uma vez} other {# vezes}}.", + "annual_report.summary.highlighted_post.reply_count": "Esta postagem recebeu {count, plural, one {uma resposta} other {# respostas}}.", + "annual_report.summary.highlighted_post.title": "Publicação mais popular", "annual_report.summary.most_used_app.most_used_app": "aplicativo mais usado", "annual_report.summary.most_used_hashtag.most_used_hashtag": "hashtag mais usada", - "annual_report.summary.most_used_hashtag.none": "Nenhuma", + "annual_report.summary.most_used_hashtag.used_count": "Você incluiu esta hashtag em {count, plural, one {uma publicação} other {# publicações}}.", + "annual_report.summary.most_used_hashtag.used_count_public": "{name} incluiu esta hashtag em {count, plural, one {uma publicação} other {# publicações}}.", "annual_report.summary.new_posts.new_posts": "novas publicações", "annual_report.summary.percentile.text": "Isso lhe coloca no topode usuários de {domain}.", "annual_report.summary.percentile.we_wont_tell_bernie": "Não contaremos ao Bernie.", - "annual_report.summary.thanks": "Obrigada por fazer parte do Mastodon!", + "annual_report.summary.share_elsewhere": "Compartilhar em outro lugar", + "annual_report.summary.share_message": "Eu obtive o arquétipo {archetype}!", + "annual_report.summary.share_on_mastodon": "Compartilhar no Mastodon", "attachments_list.unprocessed": "(não processado)", "audio.hide": "Ocultar áudio", "block_modal.remote_users_caveat": "Pediremos ao servidor {domain} que respeite sua decisão. No entanto, a conformidade não é garantida, já que alguns servidores podem lidar com bloqueios de maneira diferente. As publicações públicas ainda podem estar visíveis para usuários não logados.", @@ -145,10 +167,10 @@ "block_modal.they_cant_see_posts": "Não poderá ver suas publicações e você não verá as dele/a.", "block_modal.they_will_know": "Poderá ver que você bloqueou.", "block_modal.title": "Bloquear usuário?", - "block_modal.you_wont_see_mentions": "Você não verá publicações que mencionem o usuário.", + "block_modal.you_wont_see_mentions": "Você não verá publicações que mencionem este usuário.", "boost_modal.combo": "Pressione {combo} para pular isto na próxima vez", "boost_modal.reblog": "Impulsionar a publicação?", - "boost_modal.undo_reblog": "Retirar o impulso do post?", + "boost_modal.undo_reblog": "Retirar o impulso da publicação?", "bundle_column_error.copy_stacktrace": "Copiar relatório do erro", "bundle_column_error.error.body": "A página solicitada não pôde ser renderizada. Pode ser devido a um erro no nosso código, ou um problema de compatibilidade do seu navegador.", "bundle_column_error.error.title": "Ah, não!", @@ -162,7 +184,7 @@ "bundle_modal_error.message": "Algo deu errado ao carregar esta tela.", "bundle_modal_error.retry": "Tente novamente", "carousel.current": "Slide {current, number} / {max, number}", - "carousel.slide": "Slide {current, number} of {max, number}", + "carousel.slide": "Slide {current, number} de {max, number}", "closed_registrations.other_server_instructions": "Como o Mastodon é descentralizado, você pode criar uma conta em outro servidor e ainda pode interagir com este.", "closed_registrations_modal.description": "Não é possível criar uma conta em {domain} no momento, mas atente que você não precisa de uma conta especificamente em {domain} para usar o Mastodon.", "closed_registrations_modal.find_another_server": "Encontrar outro servidor", @@ -179,8 +201,8 @@ "column.edit_list": "Editar lista", "column.favourites": "Favoritos", "column.firehose": "Feeds ao vivo", - "column.firehose_local": "Transmissão ao vivo deste servidor", - "column.firehose_singular": "Transmissão ao vivo", + "column.firehose_local": "Feed ao vivo deste servidor", + "column.firehose_singular": "Feed ao vivo", "column.follow_requests": "Seguidores pendentes", "column.home": "Página inicial", "column.list_members": "Gerenciar membros da lista", @@ -235,7 +257,7 @@ "confirmations.delete_list.title": "Excluir lista?", "confirmations.discard_draft.confirm": "Descartar e continuar", "confirmations.discard_draft.edit.cancel": "Continuar editando", - "confirmations.discard_draft.edit.message": "Continuar vai descartar quaisquer mudanças feitas à publicação sendo editada.", + "confirmations.discard_draft.edit.message": "Continuar descartará quaisquer mudanças feitas à publicação sendo editada.", "confirmations.discard_draft.edit.title": "Descartar mudanças na sua publicação?", "confirmations.discard_draft.post.cancel": "Continuar rascunho", "confirmations.discard_draft.post.message": "Continuar eliminará a publicação que está sendo elaborada no momento.", @@ -263,7 +285,7 @@ "confirmations.quiet_post_quote_info.message": "Ao citar uma publicação pública silenciosa, sua postagem será oculta das linhas de tempo em tendência.", "confirmations.quiet_post_quote_info.title": "Citando publicações públicas silenciadas", "confirmations.redraft.confirm": "Excluir e rascunhar", - "confirmations.redraft.message": "Você tem certeza de que quer apagar essa publicação e rascunhá-la? Favoritos e impulsos serão perdidos, e respostas à postagem original ficarão órfãs.", + "confirmations.redraft.message": "Você tem certeza de que quer apagar esta publicação e rascunhá-la? Favoritos e impulsos serão perdidos, e respostas à publicação original ficarão órfãs.", "confirmations.redraft.title": "Excluir e rascunhar publicação?", "confirmations.remove_from_followers.confirm": "Remover seguidor", "confirmations.remove_from_followers.message": "{name} vai parar de te seguir. Tem certeza de que deseja continuar?", @@ -304,8 +326,8 @@ "domain_block_modal.title": "Bloquear domínio?", "domain_block_modal.you_will_lose_num_followers": "Você perderá {followersCount, plural, one {{followersCountDisplay} seguidor} other {{followersCountDisplay} seguidores}} e {followingCount, plural, one {{followingCountDisplay} pessoa que você segue} other {{followingCountDisplay} pessoas que você segue}}.", "domain_block_modal.you_will_lose_relationships": "Você irá perder todos os seguidores e pessoas que você segue neste servidor.", - "domain_block_modal.you_wont_see_posts": "Você não verá postagens ou notificações de usuários neste servidor.", - "domain_pill.activitypub_lets_connect": "Ele permite que você se conecte e interaja com pessoas não apenas no Mastodon, mas também em diferentes aplicativos sociais.", + "domain_block_modal.you_wont_see_posts": "Você não verá publicações ou notificações de usuários neste servidor.", + "domain_pill.activitypub_lets_connect": "Permite que você se conecte e interaja com pessoas não apenas no Mastodon, mas também em diferentes aplicativos sociais.", "domain_pill.activitypub_like_language": "ActivityPub é como a linguagem que o Mastodon fala com outras redes sociais.", "domain_pill.server": "Servidor", "domain_pill.their_handle": "Identificador dele/a:", @@ -347,13 +369,13 @@ "empty_column.bookmarked_statuses": "Nada aqui. Quando você salvar um toot, ele aparecerá aqui.", "empty_column.community": "A linha local está vazia. Publique algo para começar!", "empty_column.direct": "Você ainda não tem mensagens privadas. Quando você enviar ou receber uma, será exibida aqui.", - "empty_column.disabled_feed": "Este feed foi desativado pelos administradores do servidor.", + "empty_column.disabled_feed": "Este feed foi desativado pelos administradores de seu servidor.", "empty_column.domain_blocks": "Nada aqui.", "empty_column.explore_statuses": "Nada está em alta no momento. Volte mais tarde!", "empty_column.favourited_statuses": "Você ainda não tem publicações favoritas. Quanto você marcar uma como favorita, ela aparecerá aqui.", "empty_column.favourites": "Ninguém marcou esta publicação como favorita até agora. Quando alguém o fizer, será listado aqui.", "empty_column.follow_requests": "Nada aqui. Quando você tiver seguidores pendentes, eles aparecerão aqui.", - "empty_column.followed_tags": "Você ainda não seguiu nenhuma hashtag. Quando seguir uma, elas serão exibidas aqui.", + "empty_column.followed_tags": "Você ainda não seguiu nenhuma hashtag. Quando seguir, elas serão exibidas aqui.", "empty_column.hashtag": "Nada aqui.", "empty_column.home": "Sua página inicial está vazia! Siga mais pessoas para começar: {suggestions}", "empty_column.list": "Nada aqui. Quando membros da lista tootarem, eles aparecerão aqui.", @@ -374,13 +396,13 @@ "explore.trending_statuses": "Publicações", "explore.trending_tags": "Hashtags", "featured_carousel.current": "Publicação {current, number} / {max, number}", - "featured_carousel.header": "{count, plural, one {Postagem fixada} other {Postagens fixadas}}", - "featured_carousel.slide": "Publicação {current, number} of {max, number}", + "featured_carousel.header": "{count, plural, one {Publicação fixada} other {Publicações fixadas}}", + "featured_carousel.slide": "Publicação {current, number} de {max, number}", "filter_modal.added.context_mismatch_explanation": "Esta categoria de filtro não se aplica ao contexto no qual você acessou esta publicação. Se quiser que a publicação seja filtrada nesse contexto também, você terá que editar o filtro.", "filter_modal.added.context_mismatch_title": "Incompatibilidade de contexto!", "filter_modal.added.expired_explanation": "Esta categoria de filtro expirou, você precisará alterar a data de expiração para aplicar.", "filter_modal.added.expired_title": "Filtro expirado!", - "filter_modal.added.review_and_configure": "Para revisar e configurar ainda mais esta categoria de filtro, vá até {settings_link}.", + "filter_modal.added.review_and_configure": "Para revisar e configurar ainda mais esta categoria de filtro, vá para {settings_link}.", "filter_modal.added.review_and_configure_title": "Configurações de filtro", "filter_modal.added.settings_link": "página de configurações", "filter_modal.added.short_explanation": "Esta publicação foi adicionada à seguinte categoria de filtro: {title}.", @@ -612,7 +634,7 @@ "notification.admin.report_statuses": "{name} Reportou {target} para {category}", "notification.admin.report_statuses_other": "{name} denunciou {target}", "notification.admin.sign_up": "{name} se inscreveu", - "notification.admin.sign_up.name_and_others": "{name} e {count, plural, one {# other} other {# outros}}", + "notification.admin.sign_up.name_and_others": "{name} e {count, plural, one {# outro} other {# outros}} se inscreveram", "notification.annual_report.message": "O seu #Wrapstodon de {year} está esperando! Desvende seus destaques do ano e momentos memoráveis no Mastodon!", "notification.annual_report.view": "Ver #Wrapstodon", "notification.favourite": "{name} favoritou sua publicação", @@ -622,7 +644,7 @@ "notification.follow": "{name} te seguiu", "notification.follow.name_and_others": "{name} e {count, plural, one {# outro} other {# outros}} seguiram você", "notification.follow_request": "{name} quer te seguir", - "notification.follow_request.name_and_others": "{name} e {count, plural, one {# other} other {# outros}} pediu para seguir você", + "notification.follow_request.name_and_others": "{name} e {count, plural, one {# outro} other {# outros}} pediram para seguir você", "notification.label.mention": "Menção", "notification.label.private_mention": "Menção privada", "notification.label.private_reply": "Resposta privada", diff --git a/app/javascript/mastodon/locales/pt-PT.json b/app/javascript/mastodon/locales/pt-PT.json index 671930e673564b..9676206e2ceafd 100644 --- a/app/javascript/mastodon/locales/pt-PT.json +++ b/app/javascript/mastodon/locales/pt-PT.json @@ -114,28 +114,51 @@ "alt_text_modal.done": "Concluído", "announcement.announcement": "Mensagem de manutenção", "annual_report.announcement.action_build": "Criar o meu Wrapstodon", + "annual_report.announcement.action_dismiss": "Não, obrigado", "annual_report.announcement.action_view": "Ver o meu Wrapstodon", "annual_report.announcement.description": "Descobre mais sobre o teu envolvimento com o Mastodon durante o último ano.", "annual_report.announcement.title": "Chegou o Wrapstodon {year}", - "annual_report.summary.archetype.booster": "O caçador de tendências", - "annual_report.summary.archetype.lurker": "O espreitador", - "annual_report.summary.archetype.oracle": "O oráculo", - "annual_report.summary.archetype.pollster": "O sondagens", - "annual_report.summary.archetype.replier": "A borboleta social", - "annual_report.summary.followers.followers": "seguidores", - "annual_report.summary.followers.total": "{count} no total", - "annual_report.summary.here_it_is": "Aqui está um resumo do ano {year}:", - "annual_report.summary.highlighted_post.by_favourites": "publicação mais favorita", - "annual_report.summary.highlighted_post.by_reblogs": "publicação mais partilhada", - "annual_report.summary.highlighted_post.by_replies": "publicação com o maior número de respostas", - "annual_report.summary.highlighted_post.possessive": "{name}", + "annual_report.nav_item.badge": "Novo", + "annual_report.shared_page.donate": "Doar", + "annual_report.shared_page.footer": "Gerado com {heart} pela equipa do Mastodon", + "annual_report.shared_page.footer_server_info": "{username} utiliza {domain}, uma das muitas comunidades baseadas no Mastodon.", + "annual_report.summary.archetype.booster.desc_public": "{name} permaneceu à procura de publicações para partilhar, promovendo outros criadores com uma precisão perfeita.", + "annual_report.summary.archetype.booster.desc_self": "Permaneceu à procura de publicações para partilhar, promovendo outros criadores com uma precisão perfeita.", + "annual_report.summary.archetype.booster.name": "O Arqueiro", + "annual_report.summary.archetype.die_drei_fragezeichen": "???", + "annual_report.summary.archetype.lurker.desc_public": "Sabemos que {name} esteve por aí, algures, a apreciar o Mastodon na sua maneira discreta.", + "annual_report.summary.archetype.lurker.desc_self": "Sabemos que esteve por aí, algures, a apreciar o Mastodon na sua maneira discreta.", + "annual_report.summary.archetype.lurker.name": "O Estoico", + "annual_report.summary.archetype.oracle.desc_public": "{name} criou mais publicações novas do que respostas, mantendo o Mastodon atualizado e voltado para o futuro.", + "annual_report.summary.archetype.oracle.desc_self": "Criou mais publicações novas do que respostas, mantendo o Mastodon atualizado e voltado para o futuro.", + "annual_report.summary.archetype.oracle.name": "O Oráculo", + "annual_report.summary.archetype.pollster.desc_public": "{name} criou mais sondagens do que outros tipos de publicações, cultivando a curiosidade no Mastodon.", + "annual_report.summary.archetype.pollster.desc_self": "Criou mais sondagens do que outros tipos de publicações, cultivando a curiosidade no Mastodon.", + "annual_report.summary.archetype.pollster.name": "O Questionador", + "annual_report.summary.archetype.replier.desc_public": "{name} respondeu frequentemente às publicações de outras pessoas, polinizando o Mastodon com novas discussões.", + "annual_report.summary.archetype.replier.desc_self": "Respondeu frequentemente às publicações de outras pessoas, polinizando o Mastodon com novas discussões.", + "annual_report.summary.archetype.replier.name": "A Borboleta", + "annual_report.summary.archetype.reveal": "Revelar o meu arquétipo", + "annual_report.summary.archetype.reveal_description": "Obrigado por fazer parte do Mastodon! É hora de descobrir qual arquétipo você encarnou em {year}.", + "annual_report.summary.archetype.title_public": "Arquétipo de {name}", + "annual_report.summary.archetype.title_self": "O seu arquétipo", + "annual_report.summary.close": "Fechar", + "annual_report.summary.copy_link": "Copiar hiperligação", + "annual_report.summary.followers.new_followers": "{count, plural, one {novo seguidor} other {novos seguidores}}", + "annual_report.summary.highlighted_post.boost_count": "Esta publicação foi partilhada {count, plural, one {uma vez} other {# vezes}}.", + "annual_report.summary.highlighted_post.favourite_count": "Esta publicação foi colocada nos favoritos {count, plural, one {uma vez} other {# vezes}}.", + "annual_report.summary.highlighted_post.reply_count": "Esta publicação teve {count, plural, one {uma resposta} other {# respostas}}.", + "annual_report.summary.highlighted_post.title": "Publicação mais popular", "annual_report.summary.most_used_app.most_used_app": "aplicação mais utilizada", "annual_report.summary.most_used_hashtag.most_used_hashtag": "etiqueta mais utilizada", - "annual_report.summary.most_used_hashtag.none": "Nenhuma", + "annual_report.summary.most_used_hashtag.used_count": "Incluiu esta etiqueta {count, plural, one {numa publicação} other {em # publicações}}.", + "annual_report.summary.most_used_hashtag.used_count_public": "{name} incluiu esta etiqueta {count, plural, one {numa publicação} other {em # publicações}}.", "annual_report.summary.new_posts.new_posts": "novas publicações", "annual_report.summary.percentile.text": "Isso coloca-te no topodos utilizadores de {domain}.", "annual_report.summary.percentile.we_wont_tell_bernie": "Este segredo fica entre nós.", - "annual_report.summary.thanks": "Obrigado por fazeres parte do Mastodon!", + "annual_report.summary.share_elsewhere": "Partilhar noutro local", + "annual_report.summary.share_message": "Eu obtive o arquétipo {archetype}!", + "annual_report.summary.share_on_mastodon": "Partilhar no Mastodon", "attachments_list.unprocessed": "(não processado)", "audio.hide": "Ocultar áudio", "block_modal.remote_users_caveat": "Vamos pedir ao servidor {domain} para respeitar a tua decisão. No entanto, não é garantido o seu cumprimento, uma vez que alguns servidores podem tratar os bloqueios de forma diferente. As publicações públicas podem continuar a ser visíveis para utilizadores não autenticados.", @@ -418,6 +441,8 @@ "follow_suggestions.who_to_follow": "Quem seguir", "followed_tags": "Etiquetas seguidas", "footer.about": "Sobre", + "footer.about_mastodon": "Sobre o Mastodon", + "footer.about_server": "Sobre {domain}", "footer.about_this_server": "Sobre", "footer.directory": "Diretório de perfis", "footer.get_app": "Obter a aplicação", @@ -1032,7 +1057,7 @@ "visibility_modal.helper.privacy_editing": "A visibilidade não pode ser alterada após a publicação ser publicada.", "visibility_modal.helper.privacy_private_self_quote": "As autocitações de publicações privadas não podem ser tornadas públicas.", "visibility_modal.helper.private_quoting": "As publicações apenas para seguidores criadas no Mastodon não podem ser citadas por outras pessoas.", - "visibility_modal.helper.unlisted_quoting": "Quando as pessoas o citarem, as publicações delas serão também ocultadas das tendências.", + "visibility_modal.helper.unlisted_quoting": "Quando as pessoas o citarem, as respetivas publicações também serão ocultadas dos destaques.", "visibility_modal.instructions": "Controle quem pode interagir com esta publicação. Também pode definir esta configuração para todas as publicações futuras, em Preferências > Padrões de publicação.", "visibility_modal.privacy_label": "Visibilidade", "visibility_modal.quote_followers": "Apenas seguidores", diff --git a/app/javascript/mastodon/locales/ro.json b/app/javascript/mastodon/locales/ro.json index 9bf8150ba04378..8f487696434cdf 100644 --- a/app/javascript/mastodon/locales/ro.json +++ b/app/javascript/mastodon/locales/ro.json @@ -82,19 +82,8 @@ "alert.unexpected.title": "Ups!", "alt_text_badge.title": "Text alternativ", "announcement.announcement": "Anunț", - "annual_report.summary.archetype.lurker": "Pânditorul", - "annual_report.summary.archetype.oracle": "Oracolul", - "annual_report.summary.archetype.pollster": "Sondatorul", - "annual_report.summary.archetype.replier": "Fluturele social", - "annual_report.summary.followers.followers": "urmăritori", - "annual_report.summary.followers.total": "{count} total", - "annual_report.summary.here_it_is": "Iată rezumatul dvs. al anului {year}:", - "annual_report.summary.highlighted_post.by_favourites": "cea mai favorizată postare", - "annual_report.summary.highlighted_post.by_reblogs": "cea mai boostată postare", - "annual_report.summary.highlighted_post.by_replies": "postarea cu cele mai multe răspunsuri", "annual_report.summary.most_used_app.most_used_app": "cea mai utilizată aplicație", "annual_report.summary.most_used_hashtag.most_used_hashtag": "cel mai utilizat hashtag", - "annual_report.summary.most_used_hashtag.none": "Niciunul", "annual_report.summary.new_posts.new_posts": "postări noi", "attachments_list.unprocessed": "(neprocesate)", "audio.hide": "Ascunde audio", diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json index 2461dcf7e4c21b..e6891eaced2a83 100644 --- a/app/javascript/mastodon/locales/ru.json +++ b/app/javascript/mastodon/locales/ru.json @@ -113,25 +113,25 @@ "alt_text_modal.describe_for_people_with_visual_impairments": "Добавьте описание для людей с нарушениями зрения…", "alt_text_modal.done": "Готово", "announcement.announcement": "Объявление", - "annual_report.summary.archetype.booster": "Репостер", - "annual_report.summary.archetype.lurker": "Молчун", - "annual_report.summary.archetype.oracle": "Гуру", - "annual_report.summary.archetype.pollster": "Опросчик", - "annual_report.summary.archetype.replier": "Душа компании", - "annual_report.summary.followers.followers": "подписчиков", - "annual_report.summary.followers.total": "{count} за всё время", - "annual_report.summary.here_it_is": "Вот ваши итоги {year} года:", - "annual_report.summary.highlighted_post.by_favourites": "пост с наибольшим количеством звёздочек", - "annual_report.summary.highlighted_post.by_reblogs": "самый популярный пост", - "annual_report.summary.highlighted_post.by_replies": "пост с наибольшим количеством ответов", - "annual_report.summary.highlighted_post.possessive": "{name}", + "annual_report.announcement.action_dismiss": "Нет, спасибо", + "annual_report.announcement.action_view": "Посмотреть мой Wrapstodon", + "annual_report.announcement.title": "Wrapstodon {year} уже здесь", + "annual_report.nav_item.badge": "Новый", + "annual_report.shared_page.donate": "Пожертвовать", + "annual_report.shared_page.footer": "Сгенерировано с {heart} командой Mastodon", + "annual_report.summary.archetype.die_drei_fragezeichen": "???", + "annual_report.summary.archetype.reveal": "Показать мой архетип", + "annual_report.summary.archetype.title_public": "Архетип {name}", + "annual_report.summary.archetype.title_self": "Ваш архетип", + "annual_report.summary.close": "Закрыть", + "annual_report.summary.copy_link": "Скопировать ссылку", "annual_report.summary.most_used_app.most_used_app": "наиболее часто используемое приложение", "annual_report.summary.most_used_hashtag.most_used_hashtag": "наиболее часто используемый хештег", - "annual_report.summary.most_used_hashtag.none": "Нет", "annual_report.summary.new_posts.new_posts": "новых постов", "annual_report.summary.percentile.text": "Всё это помещает вас в топпользователей {domain}.", "annual_report.summary.percentile.we_wont_tell_bernie": "Роскомнадзор об этом не узнает.", - "annual_report.summary.thanks": "Спасибо за то, что были вместе с Mastodon!", + "annual_report.summary.share_elsewhere": "Поделиться на других", + "annual_report.summary.share_on_mastodon": "Поделиться в Mastodon", "attachments_list.unprocessed": "(не обработан)", "audio.hide": "Скрыть аудио", "block_modal.remote_users_caveat": "Мы попросим сервер {domain} уважать ваше решение, однако нельзя гарантировать, что он будет соблюдать блокировку, поскольку некоторые серверы могут по-разному обрабатывать запросы. Публичные посты по-прежнему могут быть видны неавторизованным пользователям.", diff --git a/app/javascript/mastodon/locales/sc.json b/app/javascript/mastodon/locales/sc.json index 8b4f4cc3d5f27a..5ba3d1cd968268 100644 --- a/app/javascript/mastodon/locales/sc.json +++ b/app/javascript/mastodon/locales/sc.json @@ -104,16 +104,10 @@ "alt_text_modal.change_thumbnail": "Càmbia sa miniadura", "alt_text_modal.done": "Fatu", "announcement.announcement": "Annùntziu", - "annual_report.summary.archetype.booster": "Semper a s'ùrtima", - "annual_report.summary.followers.followers": "sighiduras", - "annual_report.summary.followers.total": "{count} totale", - "annual_report.summary.highlighted_post.possessive": "de {name}", "annual_report.summary.most_used_app.most_used_app": "aplicatzione prus impreada", "annual_report.summary.most_used_hashtag.most_used_hashtag": "eticheta prus impreada", - "annual_report.summary.most_used_hashtag.none": "Peruna", "annual_report.summary.new_posts.new_posts": "publicatziones noas", "annual_report.summary.percentile.we_wont_tell_bernie": "No dd'amus a nàrrere a Bernie.", - "annual_report.summary.thanks": "Gràtzias de èssere parte de Mastodon!", "attachments_list.unprocessed": "(non protzessadu)", "audio.hide": "Cua s'àudio", "block_modal.remote_users_caveat": "Amus a pedire a su serbidore {domain} de rispetare sa detzisione tua. Nointames custu, su rispetu no est garantidu ca unos cantos serbidores diant pòdere gestire is blocos de manera diferente. Is publicatzione pùblicas diant pòdere ancora èssere visìbiles a is utentes chi no ant fatu s'atzessu.", diff --git a/app/javascript/mastodon/locales/si.json b/app/javascript/mastodon/locales/si.json index 8b6ab5688326c0..7b7ec1f8a2bde5 100644 --- a/app/javascript/mastodon/locales/si.json +++ b/app/javascript/mastodon/locales/si.json @@ -105,25 +105,11 @@ "alt_text_modal.describe_for_people_with_visual_impairments": "දෘශ්‍යාබාධිත පුද්ගලයින් සඳහා මෙය විස්තර කරන්න…", "alt_text_modal.done": "කළා", "announcement.announcement": "නිවේදනය", - "annual_report.summary.archetype.booster": "සිසිල් දඩයක්කාරයා", - "annual_report.summary.archetype.lurker": "සැඟවී සිටින්නා", - "annual_report.summary.archetype.oracle": "ඔරකල්", - "annual_report.summary.archetype.pollster": "ඡන්ද විමසන්නා", - "annual_report.summary.archetype.replier": "සමාජ සමනලයා", - "annual_report.summary.followers.followers": "අනුගාමිකයින්", - "annual_report.summary.followers.total": "මුළු {count}", - "annual_report.summary.here_it_is": "මෙන්න ඔබේ {year} සමාලෝචනය:", - "annual_report.summary.highlighted_post.by_favourites": "වඩාත්ම කැමති පළ කිරීම", - "annual_report.summary.highlighted_post.by_reblogs": "වඩාත්ම ප්‍රවර්ධනය කරන ලද පළ කිරීම", - "annual_report.summary.highlighted_post.by_replies": "වැඩිම පිළිතුරු සහිත පළ කිරීම", - "annual_report.summary.highlighted_post.possessive": "{name}ගේ", "annual_report.summary.most_used_app.most_used_app": "වැඩිපුරම භාවිතා කරන යෙදුම", "annual_report.summary.most_used_hashtag.most_used_hashtag": "වැඩිපුරම භාවිතා කරන ලද හැෂ් ටැගය", - "annual_report.summary.most_used_hashtag.none": "කිසිවක් නැත", "annual_report.summary.new_posts.new_posts": "නව පළ කිරීම්", "annual_report.summary.percentile.text": "එය ඔබව {domain} පරිශීලකයින්ගෙන් ඉහළමඅතරට ගෙන එයි.", "annual_report.summary.percentile.we_wont_tell_bernie": "අපි බර්නිට කියන්නේ නැහැ.", - "annual_report.summary.thanks": "මැස්ටෝඩන් හි කොටසක් වීම ගැන ස්තූතියි!", "attachments_list.unprocessed": "(සකසා නැති)", "audio.hide": "හඬපටය සඟවන්න", "block_modal.remote_users_caveat": "ඔබගේ තීරණයට ගරු කරන ලෙස අපි සේවාදායකයාගෙන් {domain} ඉල්ලා සිටිමු. කෙසේ වෙතත්, සමහර සේවාදායකයන් අවහිර කිරීම් වෙනස් ලෙස හසුරුවන බැවින් අනුකූලතාව සහතික නොවේ. පොදු පළ කිරීම් තවමත් ලොග් වී නොමැති පරිශීලකයින්ට දෘශ්‍යමාන විය හැකිය.", diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json index c440c78623792f..87282c41df27b9 100644 --- a/app/javascript/mastodon/locales/sk.json +++ b/app/javascript/mastodon/locales/sk.json @@ -113,25 +113,11 @@ "alt_text_modal.describe_for_people_with_visual_impairments": "Opíšte obsah pre ľudí so zrakovým postihnutím…", "alt_text_modal.done": "Hotovo", "announcement.announcement": "Oznámenie", - "annual_report.summary.archetype.booster": "Zdieľač*ka", - "annual_report.summary.archetype.lurker": "Sliedič*ka", - "annual_report.summary.archetype.oracle": "Divoká karta", - "annual_report.summary.archetype.pollster": "Anketár*ka", - "annual_report.summary.archetype.replier": "Hlasná trúba", - "annual_report.summary.followers.followers": "sledovatelia", - "annual_report.summary.followers.total": "{count} celkovo", - "annual_report.summary.here_it_is": "Tu je tvoja {year} v zhrnutí:", - "annual_report.summary.highlighted_post.by_favourites": "najviac obľúbený príspevok", - "annual_report.summary.highlighted_post.by_reblogs": "najviac zdieľaný príspevok", - "annual_report.summary.highlighted_post.by_replies": "príspevok s najviac odpoveďami", - "annual_report.summary.highlighted_post.possessive": "{name}", "annual_report.summary.most_used_app.most_used_app": "najviac používaná aplikácia", "annual_report.summary.most_used_hashtag.most_used_hashtag": "najviac užívaný hashtag", - "annual_report.summary.most_used_hashtag.none": "Žiaden", "annual_report.summary.new_posts.new_posts": "nové príspevky", "annual_report.summary.percentile.text": "Takže patríte do topúčtov na {domain}", "annual_report.summary.percentile.we_wont_tell_bernie": "Nepovieme Berniemu.", - "annual_report.summary.thanks": "Vďaka, že si súčasťou Mastodonu!", "attachments_list.unprocessed": "(nespracované)", "audio.hide": "Skryť zvuk", "block_modal.remote_users_caveat": "Požiadame server {domain} o rešpektovanie vášho rozhodnutia. Nevieme to však zaručiť, keďže niektoré servery pristupujú k blokovaniu inak. Verejné príspevky sa stále môžu zobrazovať neprihláseným ľuďom.", diff --git a/app/javascript/mastodon/locales/sl.json b/app/javascript/mastodon/locales/sl.json index 7f7d8bd9910658..30c72c87f0b847 100644 --- a/app/javascript/mastodon/locales/sl.json +++ b/app/javascript/mastodon/locales/sl.json @@ -103,25 +103,11 @@ "alt_text_modal.describe_for_people_with_visual_impairments": "Podaj opis za slabovidne ...", "alt_text_modal.done": "Opravljeno", "announcement.announcement": "Oznanilo", - "annual_report.summary.archetype.booster": "Lovec na trende", - "annual_report.summary.archetype.lurker": "Tiholazec", - "annual_report.summary.archetype.oracle": "Orakelj", - "annual_report.summary.archetype.pollster": "Anketar", - "annual_report.summary.archetype.replier": "Priljudnež", - "annual_report.summary.followers.followers": "sledilcev", - "annual_report.summary.followers.total": "skupaj {count}", - "annual_report.summary.here_it_is": "Tule je povzetek vašega leta {year}:", - "annual_report.summary.highlighted_post.by_favourites": "- najpriljubljenejša objava", - "annual_report.summary.highlighted_post.by_reblogs": "- največkrat izpostavljena objava", - "annual_report.summary.highlighted_post.by_replies": "- objava z največ odgovori", - "annual_report.summary.highlighted_post.possessive": "{name}", "annual_report.summary.most_used_app.most_used_app": "najpogosteje uporabljena aplikacija", "annual_report.summary.most_used_hashtag.most_used_hashtag": "največkrat uporabljen ključnik", - "annual_report.summary.most_used_hashtag.none": "Brez", "annual_report.summary.new_posts.new_posts": "nove objave", "annual_report.summary.percentile.text": "S tem ste se uvrstili med zgornjih uporabnikov domene {domain}.", "annual_report.summary.percentile.we_wont_tell_bernie": "Živi duši ne bomo povedali.", - "annual_report.summary.thanks": "Hvala, ker ste del Mastodona!", "attachments_list.unprocessed": "(neobdelano)", "audio.hide": "Skrij zvok", "block_modal.remote_users_caveat": "Strežnik {domain} bomo pozvali, naj spoštuje vašo odločitev. Kljub temu pa ni gotovo, da bo strežnik prošnjo upošteval, saj nekateri strežniki blokiranja obravnavajo drugače. Javne objave bodo morda še vedno vidne neprijavljenim uporabnikom.", diff --git a/app/javascript/mastodon/locales/sq.json b/app/javascript/mastodon/locales/sq.json index af268b1e494de0..0c8e1fc071f17c 100644 --- a/app/javascript/mastodon/locales/sq.json +++ b/app/javascript/mastodon/locales/sq.json @@ -113,21 +113,44 @@ "alt_text_modal.describe_for_people_with_visual_impairments": "Përshkruajeni këtë për persona me mangësi shikimi…", "alt_text_modal.done": "U bë", "announcement.announcement": "Lajmërim", - "annual_report.summary.archetype.oracle": "Orakulli", - "annual_report.summary.followers.followers": "ndjekës", - "annual_report.summary.followers.total": "{count} gjithsej", - "annual_report.summary.here_it_is": "Ja {year} juaj e shqyrtuar:", - "annual_report.summary.highlighted_post.by_favourites": "potimi më i parapëlqyer", - "annual_report.summary.highlighted_post.by_reblogs": "postimi me më shumë përforcime", - "annual_report.summary.highlighted_post.by_replies": "postimi me më tepër përgjigje", - "annual_report.summary.highlighted_post.possessive": "nga {name}", + "annual_report.announcement.action_dismiss": "Jo, faleminderit", + "annual_report.nav_item.badge": "E re", + "annual_report.shared_page.donate": "Dhuroni", + "annual_report.shared_page.footer": "Hartuar me {heart} nga ekipi i Mastodon-it", + "annual_report.shared_page.footer_server_info": "{username} përdor {domain}, një nga bashkësitë e shumta të bazuara në Mastodon.", + "annual_report.summary.archetype.booster.name": "Harkëtari", + "annual_report.summary.archetype.die_drei_fragezeichen": "???", + "annual_report.summary.archetype.lurker.desc_public": "E dimë se {name} qe vërdallë, diku, duke shijuar Mastodon-in në mënyrën e vet të qetë.", + "annual_report.summary.archetype.lurker.desc_self": "E dimë se qetë vërdallë, diku, duke shijuar Mastodon-in në mënyrën tuaj të qetë.", + "annual_report.summary.archetype.lurker.name": "Stoiku", + "annual_report.summary.archetype.oracle.desc_public": "{name} krijoi postime të reja, më shumë se përgjigje, duke e mbajtur Mastodon-in të freskët dhe me sytë nga ardhmja.", + "annual_report.summary.archetype.oracle.desc_self": "Krijuat postime të reja, më shumë se përgjigje, duke e mbajtur Mastodon-in të freskët dhe me sytë nga e ardhmja.", + "annual_report.summary.archetype.oracle.name": "Orakulli", + "annual_report.summary.archetype.pollster.desc_public": "{name} krijoi më tepër pyetësorë se sa lloje të tjera postimesh, duke kultivuar kureshtjen në Mastodon.", + "annual_report.summary.archetype.pollster.desc_self": "Krijuat më tepër pyetësorë, se sa lloje të tjera postimesh, duke kultivuar kureshtjen në Mastodon.", + "annual_report.summary.archetype.replier.desc_public": "{name} u përgjigj shpesh te postime të njerëzve të tjerë, duke pjalmuar Mastodon-in me diskutime të reja.", + "annual_report.summary.archetype.replier.desc_self": "U përgjigjët shpesh te postime të njerëzve të tjerë, duke pjalmuar Mastodon-in me diskutime të reja.", + "annual_report.summary.archetype.replier.name": "Flutura", + "annual_report.summary.archetype.reveal": "Zbulo me se ngjaj", + "annual_report.summary.archetype.reveal_description": "Faleminderit për qenien pjesë e Mastodon-it! Koha për të mësuar cilin model trupëzuat gjatë {year}.", + "annual_report.summary.archetype.title_public": "Modeli për {name}", + "annual_report.summary.archetype.title_self": "Modeli juaj", + "annual_report.summary.close": "Mbylle", + "annual_report.summary.copy_link": "Kopjoji lidhjen", + "annual_report.summary.followers.new_followers": "{count, plural, one {ndjekës i ri} other {ndjekës të rinj}}", + "annual_report.summary.highlighted_post.boost_count": "Ky postim qe përforcuar {count, plural, one {një herë} other {# herë}}.", + "annual_report.summary.highlighted_post.favourite_count": "Ky postim u vu si i parapëlqyer {count, plural, one {një herë} other {# herë}}.", + "annual_report.summary.highlighted_post.reply_count": "Ky postim pati {count, plural, one {një përgjigje} other {# përgjigje}}.", + "annual_report.summary.highlighted_post.title": "Postimi më popullor", "annual_report.summary.most_used_app.most_used_app": "aplikacioni më i përdorur", "annual_report.summary.most_used_hashtag.most_used_hashtag": "hashtag-u më i përdorur", - "annual_report.summary.most_used_hashtag.none": "Asnjë", + "annual_report.summary.most_used_hashtag.used_count": "Këtë hashtag e përfshitë në {count, plural, one {një postim} other {# postime}}.", + "annual_report.summary.most_used_hashtag.used_count_public": "{name} përfshiu këtë hashtag në {count, plural, one {një postim} other {# postime}}.", "annual_report.summary.new_posts.new_posts": "postime të reja", "annual_report.summary.percentile.text": "Kjo ju vendos te kryesues të përdoruesve të {domain}.", "annual_report.summary.percentile.we_wont_tell_bernie": "Nuk do t’ia themi Bernit.", - "annual_report.summary.thanks": "Faleminderit që jeni pjesë e Mastodon-it!", + "annual_report.summary.share_elsewhere": "Ndajeni me të tjerë gjetkë", + "annual_report.summary.share_on_mastodon": "Ndajeni në Mastodon me të tjerë", "attachments_list.unprocessed": "(e papërpunuar)", "audio.hide": "Fshihe audion", "block_modal.remote_users_caveat": "Do t’i kërkojmë shërbyesit {domain} të respektojë vendimin tuaj. Por, pajtimi s’është i garantuar, ngaqë disa shërbyes mund t’i trajtojnë ndryshe bllokimet. Psotimet publike mundet të jenë ende të dukshme për përdorues pa bërë hyrje në llogari.", @@ -410,6 +433,8 @@ "follow_suggestions.who_to_follow": "Cilët të ndiqen", "followed_tags": "Hashtag-ë të ndjekur", "footer.about": "Mbi", + "footer.about_mastodon": "Mbi Mastodon-in", + "footer.about_server": "Mbi {domain}", "footer.about_this_server": "Mbi", "footer.directory": "Drejtori profilesh", "footer.get_app": "Merreni aplikacionin", diff --git a/app/javascript/mastodon/locales/sv.json b/app/javascript/mastodon/locales/sv.json index 368498b1ce8c79..bbd3b68a7c1a29 100644 --- a/app/javascript/mastodon/locales/sv.json +++ b/app/javascript/mastodon/locales/sv.json @@ -113,25 +113,17 @@ "alt_text_modal.describe_for_people_with_visual_impairments": "Beskriv detta för personer med synnedsättning…", "alt_text_modal.done": "Klar", "announcement.announcement": "Kungörelse", - "annual_report.summary.archetype.booster": "Häftighetsjägaren", - "annual_report.summary.archetype.lurker": "Smygaren", - "annual_report.summary.archetype.oracle": "Oraklet", - "annual_report.summary.archetype.pollster": "Frågaren", - "annual_report.summary.archetype.replier": "Den sociala fjärilen", - "annual_report.summary.followers.followers": "följare", - "annual_report.summary.followers.total": "{count} totalt", - "annual_report.summary.here_it_is": "Här är en tillbakablick på ditt {year}:", - "annual_report.summary.highlighted_post.by_favourites": "mest favoritmarkerat inlägg", - "annual_report.summary.highlighted_post.by_reblogs": "mest boostat inlägg", - "annual_report.summary.highlighted_post.by_replies": "inlägg med flest svar", - "annual_report.summary.highlighted_post.possessive": "{name}s", + "annual_report.announcement.action_dismiss": "Nej tack", + "annual_report.nav_item.badge": "Ny", + "annual_report.shared_page.donate": "Donera", + "annual_report.summary.copy_link": "Kopiera länk", "annual_report.summary.most_used_app.most_used_app": "mest använda app", "annual_report.summary.most_used_hashtag.most_used_hashtag": "mest använda hashtag", - "annual_report.summary.most_used_hashtag.none": "Inga", "annual_report.summary.new_posts.new_posts": "nya inlägg", "annual_report.summary.percentile.text": "Det placerar dig i toppbland {domain} användare.", "annual_report.summary.percentile.we_wont_tell_bernie": "Vi berättar inte för Bernie.", - "annual_report.summary.thanks": "Tack för att du är en del av Mastodon!", + "annual_report.summary.share_elsewhere": "Dela någon annanstans", + "annual_report.summary.share_on_mastodon": "Dela på Mastodon", "attachments_list.unprocessed": "(obehandlad)", "audio.hide": "Dölj audio", "block_modal.remote_users_caveat": "Vi kommer att be servern {domain} att respektera ditt beslut. Dock garanteras inte efterlevnad eftersom vissa servrar kan hantera blockeringar på olika sätt. Offentliga inlägg kan fortfarande vara synliga för icke-inloggade användare.", @@ -414,6 +406,8 @@ "follow_suggestions.who_to_follow": "Rekommenderade profiler", "followed_tags": "Följda hashtags", "footer.about": "Om", + "footer.about_mastodon": "Om Mastodon", + "footer.about_server": "Om {domain}", "footer.about_this_server": "Om", "footer.directory": "Profilkatalog", "footer.get_app": "Skaffa appen", diff --git a/app/javascript/mastodon/locales/th.json b/app/javascript/mastodon/locales/th.json index 1ba048635731bf..eb2a814d610e23 100644 --- a/app/javascript/mastodon/locales/th.json +++ b/app/javascript/mastodon/locales/th.json @@ -110,23 +110,10 @@ "alt_text_modal.describe_for_people_with_visual_impairments": "อธิบายสิ่งนี้สำหรับผู้คนที่มีความบกพร่องทางการมองเห็น…", "alt_text_modal.done": "เสร็จสิ้น", "announcement.announcement": "ประกาศ", - "annual_report.summary.archetype.booster": "ผู้ล่าความเจ๋ง", - "annual_report.summary.archetype.lurker": "ผู้ซุ่มอ่านข่าว", - "annual_report.summary.archetype.oracle": "ผู้ให้คำปรึกษา", - "annual_report.summary.archetype.pollster": "ผู้สำรวจความคิดเห็น", - "annual_report.summary.archetype.replier": "ผู้ชอบเข้าสังคม", - "annual_report.summary.followers.followers": "ผู้ติดตาม", - "annual_report.summary.followers.total": "รวม {count}", - "annual_report.summary.highlighted_post.by_favourites": "โพสต์ที่ได้รับการชื่นชอบมากที่สุด", - "annual_report.summary.highlighted_post.by_reblogs": "โพสต์ที่ได้รับการดันมากที่สุด", - "annual_report.summary.highlighted_post.by_replies": "โพสต์ที่มีการตอบกลับมากที่สุด", - "annual_report.summary.highlighted_post.possessive": "{name}", "annual_report.summary.most_used_app.most_used_app": "แอปที่ใช้มากที่สุด", "annual_report.summary.most_used_hashtag.most_used_hashtag": "แฮชแท็กที่ใช้มากที่สุด", - "annual_report.summary.most_used_hashtag.none": "ไม่มี", "annual_report.summary.new_posts.new_posts": "โพสต์ใหม่", "annual_report.summary.percentile.we_wont_tell_bernie": "เราจะไม่บอก Bernie", - "annual_report.summary.thanks": "ขอบคุณสำหรับการเป็นส่วนหนึ่งของ Mastodon!", "attachments_list.unprocessed": "(ยังไม่ได้ประมวลผล)", "audio.hide": "ซ่อนเสียง", "block_modal.remote_users_caveat": "เราจะขอให้เซิร์ฟเวอร์ {domain} เคารพการตัดสินใจของคุณ อย่างไรก็ตาม ไม่รับประกันการปฏิบัติตามข้อกำหนดเนื่องจากเซิร์ฟเวอร์บางแห่งอาจจัดการการปิดกั้นแตกต่างกัน โพสต์สาธารณะอาจยังคงปรากฏแก่ผู้ใช้ที่ไม่ได้เข้าสู่ระบบ", diff --git a/app/javascript/mastodon/locales/tok.json b/app/javascript/mastodon/locales/tok.json index 7ed0b16de13156..8faa4fa17f7dec 100644 --- a/app/javascript/mastodon/locales/tok.json +++ b/app/javascript/mastodon/locales/tok.json @@ -112,25 +112,11 @@ "alt_text_modal.describe_for_people_with_visual_impairments": "jan li ken ala lukin la o pana e toki pi sona lukin…", "alt_text_modal.done": "o pana", "announcement.announcement": "toki suli", - "annual_report.summary.archetype.booster": "jan ni li alasa e pona", - "annual_report.summary.archetype.lurker": "jan ni li lukin taso", - "annual_report.summary.archetype.oracle": "jan ni li sona suli", - "annual_report.summary.archetype.pollster": "jan ni li wile sona e pilin jan", - "annual_report.summary.archetype.replier": "jan ni li toki tawa jan mute", - "annual_report.summary.followers.followers": "jan kute sina", - "annual_report.summary.followers.total": "ale la {count}", - "annual_report.summary.here_it_is": "toki lili la tenpo sike nanpa {year} li sama ni tawa sina:", - "annual_report.summary.highlighted_post.by_favourites": "toki ni li pona suli tawa jan", - "annual_report.summary.highlighted_post.by_reblogs": "jan ante li pana suli e toki ni", - "annual_report.summary.highlighted_post.by_replies": "la jan ante li toki suli tan toki ni", - "annual_report.summary.highlighted_post.possessive": "{name}", "annual_report.summary.most_used_app.most_used_app": "ilo pi kepeken suli", "annual_report.summary.most_used_hashtag.most_used_hashtag": "kulupu toki pi kepeken suli", - "annual_report.summary.most_used_hashtag.none": "ala", "annual_report.summary.new_posts.new_posts": "toki suli sin", "annual_report.summary.percentile.text": "ni la sina nanpa sewipi jan ale lon {domain}.", "annual_report.summary.percentile.we_wont_tell_bernie": "sona ni li len tawa ale.", - "annual_report.summary.thanks": "sina lon kulupu Mastodon la sina pona a!", "attachments_list.unprocessed": "(nasin open)", "audio.hide": "o len e kalama", "block_modal.remote_users_caveat": "mi pana e wile sina tawa ma {domain}. taso ma li ken kepeken nasin ante la pakala li ken. jan li awen ken lukin e toki kepeken sijelo ala.", diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json index 54a993acf6234f..fed0220a7be8dd 100644 --- a/app/javascript/mastodon/locales/tr.json +++ b/app/javascript/mastodon/locales/tr.json @@ -114,29 +114,49 @@ "alt_text_modal.done": "Tamamlandı", "announcement.announcement": "Duyuru", "annual_report.announcement.action_build": "Wrapstodon'umu Oluştur", + "annual_report.announcement.action_dismiss": "Hayır teşekkürler", "annual_report.announcement.action_view": "Wrapstodon'umu Görüntüle", "annual_report.announcement.description": "Mastodon'daki geçen yıldaki etkileşimleriniz hakkında daha fazlasını öğrenin.", "annual_report.announcement.title": "{year} Wrapstodon'u yayında", - "annual_report.summary.archetype.booster": "Trend takipçisi", - "annual_report.summary.archetype.lurker": "Gizli meraklı", - "annual_report.summary.archetype.oracle": "Kahin", - "annual_report.summary.archetype.pollster": "Anketör", - "annual_report.summary.archetype.replier": "Sosyal kelebek", - "annual_report.summary.followers.followers": "takipçiler", - "annual_report.summary.followers.total": "{count} toplam", - "annual_report.summary.here_it_is": "İşte {year} yılı değerlendirmeniz:", - "annual_report.summary.highlighted_post.by_favourites": "en çok beğenilen gönderi", - "annual_report.summary.highlighted_post.by_reblogs": "en çok paylaşılan gönderi", - "annual_report.summary.highlighted_post.by_replies": "en çok yanıt alan gönderi", - "annual_report.summary.highlighted_post.possessive": "{name}", + "annual_report.shared_page.donate": "Bağış Yap", + "annual_report.shared_page.footer": "Mastodon ekibi tarafından {heart} ile oluşturulmuştur", + "annual_report.summary.archetype.booster.desc_public": "{name} mükemmel bir hedefle diğer içerik üreticilerini desteklemek için paylaşımları yeniden yayınlamaya devam etti.", + "annual_report.summary.archetype.booster.desc_self": "Mükemmel bir hedefle diğer içerik üreticilerini desteklemek için paylaşımları yeniden yayınlamaya devam ettin.", + "annual_report.summary.archetype.booster.name": "Okçu", + "annual_report.summary.archetype.die_drei_fragezeichen": "???", + "annual_report.summary.archetype.lurker.desc_public": "{name} orada, bir yerlerde, kendi sessiz tarzıyla Mastodon'un tadını çıkarıyor, biliyoruz.", + "annual_report.summary.archetype.lurker.desc_self": "Orada, bir yerlerde, kendi sessiz tarzınla Mastodon'un tadını çıkarıyorsun, biliyoruz.", + "annual_report.summary.archetype.lurker.name": "Stoacı", + "annual_report.summary.archetype.oracle.desc_public": "{name} yanıtlardan daha çok yeni gönderi oluşturarak Mastodon'u taze ve geleceğe dönük tuttu.", + "annual_report.summary.archetype.oracle.desc_self": "Yanıtlardan daha çok yeni gönderi oluşturarak Mastodon'u taze ve geleceğe dönük tuttun.", + "annual_report.summary.archetype.oracle.name": "Kahin", + "annual_report.summary.archetype.pollster.desc_public": "{name} diğer gönderi türlerinden çok anket oluşturarak Mastodon'da merak uyandırdı.", + "annual_report.summary.archetype.pollster.desc_self": "Diğer gönderi türlerinden çok anket oluşturarak Mastodon'da merak uyandırdın.", + "annual_report.summary.archetype.pollster.name": "Meraklı", + "annual_report.summary.archetype.replier.desc_public": "{name} sık sık diğer kullanıcıların gönderilerine yanıt vererek Mastodon'a yeni tartışmalar kazandırdı.", + "annual_report.summary.archetype.replier.desc_self": "Sık sık diğer kullanıcıların gönderilerine yanıt vererek Mastodon'a yeni tartışmalar kazandırdın.", + "annual_report.summary.archetype.replier.name": "Kelebek", + "annual_report.summary.archetype.reveal": "Arketipimi Göster", + "annual_report.summary.archetype.reveal_description": "Mastodon'un bir parçası olduğun için teşekkürler! {year} yılında hangi arketipi temsil ettiğini öğrenme zamanı geldi.", + "annual_report.summary.archetype.title_public": "{name} kullanıcısının arketipi", + "annual_report.summary.archetype.title_self": "Arketipin", + "annual_report.summary.close": "Kapat", + "annual_report.summary.copy_link": "Bağlantıyı kopyala", + "annual_report.summary.followers.new_followers": "{count, plural, one {1 yeni takipçi} other {# yeni takipçi}}", + "annual_report.summary.highlighted_post.boost_count": "Bu gönderi {count, plural, one {1 kez} other {# kez}} yeniden paylaşıldı.", + "annual_report.summary.highlighted_post.favourite_count": "Bu gönderi {count, plural, one {1 kez} other {# kez}} beğenildi.", + "annual_report.summary.highlighted_post.reply_count": "Bu gönderi {count, plural, one {1 yanıt} other {# yanıt}} aldı.", + "annual_report.summary.highlighted_post.title": "En popüler gönderi", "annual_report.summary.most_used_app.most_used_app": "en çok kullanılan uygulama", "annual_report.summary.most_used_hashtag.most_used_hashtag": "en çok kullanılan etiket", - "annual_report.summary.most_used_hashtag.none": "Yok", + "annual_report.summary.most_used_hashtag.used_count": "Bu etiketi {count, plural, one {1 gönderi} other {# gönderi}}de kullandınız.", + "annual_report.summary.most_used_hashtag.used_count_public": "{name} bu etiketi {count, plural, one {1 gönderi} other {# gönderi}}de kullandı.", "annual_report.summary.new_posts.new_posts": "yeni gönderiler", "annual_report.summary.percentile.text": "{domain} kullanıcılarınınüst dilimindesiniz", "annual_report.summary.percentile.we_wont_tell_bernie": "Bernie'ye söylemeyiz.", + "annual_report.summary.share_elsewhere": "Başka yerde paylaş", "annual_report.summary.share_message": "{archetype} arketipindeyim!", - "annual_report.summary.thanks": "Mastodon'un bir parçası olduğunuz için teşekkürler!", + "annual_report.summary.share_on_mastodon": "Mastodon'da Paylaş", "attachments_list.unprocessed": "(işlenmemiş)", "audio.hide": "Sesi gizle", "block_modal.remote_users_caveat": "{domain} sunucusundan kararınıza saygı duymasını isteyeceğiz. Ancak, Uymaları garanti değildir çünkü bazı sunucular engellemeyi farklı şekilde yapıyorlar. Herkese açık gönderiler giriş yapmamış kullanıcılara görüntülenmeye devam edebilir.", diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json index dc48e9dafd0b8b..38ec3d3e1c21f8 100644 --- a/app/javascript/mastodon/locales/uk.json +++ b/app/javascript/mastodon/locales/uk.json @@ -110,25 +110,11 @@ "alt_text_modal.describe_for_people_with_visual_impairments": "Опишіть цю ідею для людей із порушеннями зору…", "alt_text_modal.done": "Готово", "announcement.announcement": "Оголошення", - "annual_report.summary.archetype.booster": "Мисливець на дописи", - "annual_report.summary.archetype.lurker": "Причаєнець", - "annual_report.summary.archetype.oracle": "Оракул", - "annual_report.summary.archetype.pollster": "Опитувач", - "annual_report.summary.archetype.replier": "Душа компанії", - "annual_report.summary.followers.followers": "підписники", - "annual_report.summary.followers.total": "Загалом {count}", - "annual_report.summary.here_it_is": "Ось ваші підсумки {year} року:", - "annual_report.summary.highlighted_post.by_favourites": "найуподобаніші дописи", - "annual_report.summary.highlighted_post.by_reblogs": "найпоширюваніші дописи", - "annual_report.summary.highlighted_post.by_replies": "найкоментованіші дописи", - "annual_report.summary.highlighted_post.possessive": "{name}", "annual_report.summary.most_used_app.most_used_app": "найчастіше використовуваний застосунок", "annual_report.summary.most_used_hashtag.most_used_hashtag": "найчастіший хештег", - "annual_report.summary.most_used_hashtag.none": "Немає", "annual_report.summary.new_posts.new_posts": "нові дописи", "annual_report.summary.percentile.text": "Це виводить вас у топ користувачів Mastodon.", "annual_report.summary.percentile.we_wont_tell_bernie": "Ми не скажемо Bernie.", - "annual_report.summary.thanks": "Дякуємо, що ви є частиною Mastodon!", "attachments_list.unprocessed": "(не оброблено)", "audio.hide": "Сховати аудіо", "block_modal.remote_users_caveat": "Ми попросимо сервер {domain} поважати ваше рішення. Однак дотримання вимог не гарантується, оскільки деякі сервери можуть обробляти блоки по-різному. Загальнодоступні дописи все ще можуть бути видимими для користувачів, які не увійшли в систему.", diff --git a/app/javascript/mastodon/locales/vi.json b/app/javascript/mastodon/locales/vi.json index 79528fb9f61728..a5feaebc447724 100644 --- a/app/javascript/mastodon/locales/vi.json +++ b/app/javascript/mastodon/locales/vi.json @@ -114,29 +114,51 @@ "alt_text_modal.done": "Xong", "announcement.announcement": "Có gì mới?", "annual_report.announcement.action_build": "Tạo Wrapstodon của tôi", + "annual_report.announcement.action_dismiss": "Không, cảm ơn", "annual_report.announcement.action_view": "Xem Wrapstodon của tôi", "annual_report.announcement.description": "Tìm hiểu thêm về mức độ tương tác của bạn trên Mastodon trong năm qua.", "annual_report.announcement.title": "Wrapstodon {year} đã đến", - "annual_report.summary.archetype.booster": "Hiệp sĩ ngầu", - "annual_report.summary.archetype.lurker": "Kẻ rình mò", - "annual_report.summary.archetype.oracle": "Nhà tiên tri", - "annual_report.summary.archetype.pollster": "Chuyên gia khảo sát", - "annual_report.summary.archetype.replier": "Bướm xã hội", - "annual_report.summary.followers.followers": "người theo dõi", - "annual_report.summary.followers.total": "tổng {count}", - "annual_report.summary.here_it_is": "Nhìn lại năm {year} của bạn:", - "annual_report.summary.highlighted_post.by_favourites": "tút được thích nhiều nhất", - "annual_report.summary.highlighted_post.by_reblogs": "tút được đăng lại nhiều nhất", - "annual_report.summary.highlighted_post.by_replies": "tút được trả lời nhiều nhất", - "annual_report.summary.highlighted_post.possessive": "{name}", + "annual_report.nav_item.badge": "Mới", + "annual_report.shared_page.donate": "Quyên góp", + "annual_report.shared_page.footer": "Tạo bằng {heart} bởi đội ngũ Mastodon", + "annual_report.shared_page.footer_server_info": "{username} ở {domain}, một trong nhiều cộng đồng Mastodon.", + "annual_report.summary.archetype.booster.desc_public": "{name} thích tìm kiếm và đăng lại các tút, lan tỏa những người sáng tạo khác với mục tiêu hoàn hảo.", + "annual_report.summary.archetype.booster.desc_self": "Bạn thích tìm kiếm và đăng lại các tút, lan tỏa những người sáng tạo khác với mục tiêu hoàn hảo.", + "annual_report.summary.archetype.booster.name": "Cung Thủ", + "annual_report.summary.archetype.die_drei_fragezeichen": "???", + "annual_report.summary.archetype.lurker.desc_public": "Chúng tôi biết {name} đang ở đâu đó ngoài kia, tận hưởng Mastodon theo cách riêng của họ.", + "annual_report.summary.archetype.lurker.desc_self": "Chúng tôi biết bạn đang ở đâu đó ngoài kia, tận hưởng Mastodon theo cách riêng.", + "annual_report.summary.archetype.lurker.name": "Lãng Nhân", + "annual_report.summary.archetype.oracle.desc_public": "{name} tạo ra nhiều tút mới hơn là trả lời, giúp Mastodon luôn mới mẻ và hướng tới tương lai.", + "annual_report.summary.archetype.oracle.desc_self": "Bạn tạo ra nhiều tút mới hơn là trả lời, giúp Mastodon luôn mới mẻ và hướng tới tương lai.", + "annual_report.summary.archetype.oracle.name": "Tiên Tri", + "annual_report.summary.archetype.pollster.desc_public": "{name} tạo ra nhiều cuộc vốt hơn các loại tút khác, khơi dậy sự tò mò trên Mastodon.", + "annual_report.summary.archetype.pollster.desc_self": "Bạn tạo ra nhiều cuộc vốt hơn các loại tút khác, khơi dậy sự tò mò trên Mastodon.", + "annual_report.summary.archetype.pollster.name": "Mọt Sách", + "annual_report.summary.archetype.replier.desc_public": "{name} thường xuyên trả lời tút của người khác, mang đến cho Mastodon những cuộc thảo luận mới.", + "annual_report.summary.archetype.replier.desc_self": "Bạn thường xuyên trả lời tút của người khác, mang đến cho Mastodon những cuộc thảo luận mới.", + "annual_report.summary.archetype.replier.name": "Bướm Xinh", + "annual_report.summary.archetype.reveal": "Bật mí nguyên mẫu của tôi", + "annual_report.summary.archetype.reveal_description": "Cảm ơn bạn đã là một phần của Mastodon! Đã đến lúc tìm hiểu xem bạn thuộc nguyên mẫu nào vào năm {year}.", + "annual_report.summary.archetype.title_public": "Nguyên mẫu của {name}", + "annual_report.summary.archetype.title_self": "Nguyên mẫu của bạn", + "annual_report.summary.close": "Đóng", + "annual_report.summary.copy_link": "Sao chép liên kết", + "annual_report.summary.followers.new_followers": "{count, plural, other {người theo dõi mới}}", + "annual_report.summary.highlighted_post.boost_count": "Tút này được đăng lại {count, plural, other {# lần}}.", + "annual_report.summary.highlighted_post.favourite_count": "Tút này được thích {count, plural, other {# lần}}.", + "annual_report.summary.highlighted_post.reply_count": "Tút này có {count, plural, other {# lượt trả lời}}.", + "annual_report.summary.highlighted_post.title": "Tút nổi tiếng nhất", "annual_report.summary.most_used_app.most_used_app": "app dùng nhiều nhất", "annual_report.summary.most_used_hashtag.most_used_hashtag": "hashtag dùng nhiều nhất", - "annual_report.summary.most_used_hashtag.none": "Không có", + "annual_report.summary.most_used_hashtag.used_count": "Bạn đã dùng hashtag này trong {count, plural, other {# tút}}.", + "annual_report.summary.most_used_hashtag.used_count_public": "{name} đã dùng hashtag này trong {count, plural, other {# tút}}.", "annual_report.summary.new_posts.new_posts": "tút mới", "annual_report.summary.percentile.text": "Bạn thuộc topthành viên của {domain}.", "annual_report.summary.percentile.we_wont_tell_bernie": "Chúng tôi sẽ không kể cho Bernie.", + "annual_report.summary.share_elsewhere": "Chia sẻ nơi khác", "annual_report.summary.share_message": "Tôi là điển hình {archetype}!", - "annual_report.summary.thanks": "Cảm ơn đã trở thành một phần của Mastodon!", + "annual_report.summary.share_on_mastodon": "Chia sẻ lên Mastodon", "attachments_list.unprocessed": "(chưa xử lí)", "audio.hide": "Ẩn âm thanh", "block_modal.remote_users_caveat": "Chúng tôi sẽ yêu cầu {domain} tôn trọng quyết định của bạn. Tuy nhiên, việc tuân thủ không được đảm bảo vì một số máy chủ có thể xử lý việc chặn theo cách khác nhau. Các tút công khai vẫn có thể hiển thị đối với người dùng chưa đăng nhập.", @@ -419,6 +441,8 @@ "follow_suggestions.who_to_follow": "Gợi ý theo dõi", "followed_tags": "Hashtag theo dõi", "footer.about": "Giới thiệu", + "footer.about_mastodon": "Về Mastodon", + "footer.about_server": "Về {domain}", "footer.about_this_server": "Giới thiệu", "footer.directory": "Danh bạ", "footer.get_app": "Ứng dụng", diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json index 274d3bc598e03a..cb63df5e99c714 100644 --- a/app/javascript/mastodon/locales/zh-CN.json +++ b/app/javascript/mastodon/locales/zh-CN.json @@ -114,29 +114,50 @@ "alt_text_modal.done": "完成", "announcement.announcement": "公告", "annual_report.announcement.action_build": "构建我的 Wrapstodon 年度回顾", + "annual_report.announcement.action_dismiss": "不了,谢谢", "annual_report.announcement.action_view": "查看我的 Wrapstodon 年度回顾", "annual_report.announcement.description": "探索更多关于您过去一年在 Mastodon 上的互动情况。", "annual_report.announcement.title": "Wrapstodon {year} 年度回顾来啦", - "annual_report.summary.archetype.booster": "潮流捕手", - "annual_report.summary.archetype.lurker": "吃瓜群众", - "annual_report.summary.archetype.oracle": "未卜先知", - "annual_report.summary.archetype.pollster": "民调专家", - "annual_report.summary.archetype.replier": "社交蝴蝶", - "annual_report.summary.followers.followers": "关注者", - "annual_report.summary.followers.total": "共 {count} 人", - "annual_report.summary.here_it_is": "您的 {year} 年度回顾在此:", - "annual_report.summary.highlighted_post.by_favourites": "最受欢迎的嘟文", - "annual_report.summary.highlighted_post.by_reblogs": "传播最广的嘟文", - "annual_report.summary.highlighted_post.by_replies": "评论最多的嘟文", - "annual_report.summary.highlighted_post.possessive": "{name} 的", + "annual_report.nav_item.badge": "新", + "annual_report.shared_page.donate": "捐助", + "annual_report.shared_page.footer": "由 Mastodon 团队用 {heart} 生成", + "annual_report.summary.archetype.booster.desc_public": "{name}持续寻找值得转嘟的嘟文,以精准眼光放大其他创作者的影响力。", + "annual_report.summary.archetype.booster.desc_self": "你持续寻找值得转嘟的嘟文,以精准眼光放大其他创作者的影响力。", + "annual_report.summary.archetype.booster.name": "转发游侠", + "annual_report.summary.archetype.die_drei_fragezeichen": "???", + "annual_report.summary.archetype.lurker.desc_public": "我们知道{name}曾在联邦宇宙的某个角落驻足,以自己的方式静静享受着Mastodon。", + "annual_report.summary.archetype.lurker.desc_self": "我们知道你曾在联邦宇宙的某个角落驻足,以自己的方式静静享受着Mastodon。", + "annual_report.summary.archetype.lurker.name": "吃瓜群众", + "annual_report.summary.archetype.oracle.desc_public": "{name}发布的新嘟文远多于回复,为Mastodon注入无限活力与未来。", + "annual_report.summary.archetype.oracle.desc_self": "你发布的新嘟文远多于回复,为Mastodon注入无限活力与未来。", + "annual_report.summary.archetype.oracle.name": "创作先知", + "annual_report.summary.archetype.pollster.desc_public": "{name}发起投票的次数远多于其他嘟文类型,不断激发Mastodon上大家的好奇心。", + "annual_report.summary.archetype.pollster.desc_self": "你发起投票的次数远多于其他嘟文类型,不断激发Mastodon上大家的好奇心。", + "annual_report.summary.archetype.pollster.name": "探求先锋", + "annual_report.summary.archetype.replier.desc_public": "{name}经常回复其他人的嘟文,为Mastodon培育新讨论的萌芽。", + "annual_report.summary.archetype.replier.desc_self": "你经常回复其他人的嘟文,为Mastodon培育新讨论的萌芽。", + "annual_report.summary.archetype.replier.name": "社交蝴蝶", + "annual_report.summary.archetype.reveal": "揭示我的画像", + "annual_report.summary.archetype.reveal_description": "感谢你成为Mastodon的一份子!是时候揭晓你{year}年的用户画像啦。", + "annual_report.summary.archetype.title_public": "{name}的画像", + "annual_report.summary.archetype.title_self": "你的画像", + "annual_report.summary.close": "关闭", + "annual_report.summary.copy_link": "复制链接", + "annual_report.summary.followers.new_followers": "{count, plural, other {位新关注者}}", + "annual_report.summary.highlighted_post.boost_count": "此嘟文被转嘟了 {count, plural, other {# 次}}。", + "annual_report.summary.highlighted_post.favourite_count": "此嘟文收到了 {count, plural, other {# 次}}喜欢。", + "annual_report.summary.highlighted_post.reply_count": "此嘟文收到了 {count, plural, other {# 条回复}}。", + "annual_report.summary.highlighted_post.title": "最热门的嘟文", "annual_report.summary.most_used_app.most_used_app": "最常用的应用", "annual_report.summary.most_used_hashtag.most_used_hashtag": "最常用的话题", - "annual_report.summary.most_used_hashtag.none": "无", + "annual_report.summary.most_used_hashtag.used_count": "你在 {count, plural, other {# 条嘟文}}中使用了此话题标签。", + "annual_report.summary.most_used_hashtag.used_count_public": "{name} 在 {count, plural, other {# 条嘟文}}中使用了此话题标签。", "annual_report.summary.new_posts.new_posts": "新嘟文", "annual_report.summary.percentile.text": "这使你跻身 {domain} 用户的前", "annual_report.summary.percentile.we_wont_tell_bernie": " ", + "annual_report.summary.share_elsewhere": "分享到其他地方", "annual_report.summary.share_message": "我今年的画像是{archetype}!", - "annual_report.summary.thanks": "感谢您成为 Mastodon 的一员!", + "annual_report.summary.share_on_mastodon": "在Mastodon上分享", "attachments_list.unprocessed": "(未处理)", "audio.hide": "隐藏音频", "block_modal.remote_users_caveat": "我们将要求站点 {domain} 尊重你的决定。然而,我们无法保证对方一定遵从,因为某些站点可能会以不同的方案处理屏蔽操作。公开嘟文仍然可能对未登录用户可见。", diff --git a/app/javascript/mastodon/locales/zh-HK.json b/app/javascript/mastodon/locales/zh-HK.json index dbb7752e97b662..8d86bd981d2afc 100644 --- a/app/javascript/mastodon/locales/zh-HK.json +++ b/app/javascript/mastodon/locales/zh-HK.json @@ -105,7 +105,6 @@ "alt_text_modal.cancel": "取消", "alt_text_modal.done": "完成", "announcement.announcement": "公告", - "annual_report.summary.thanks": "感謝您成為 Mastodon 的一份子!", "attachments_list.unprocessed": "(未處理)", "audio.hide": "隱藏音訊", "block_modal.remote_users_caveat": "我們會要求 {domain} 伺服器尊重你的決定。然而,由於部份伺服器可能以不同方式處理封鎖,因此無法保證一定會成功。公開帖文仍然有機會被未登入的使用者看見。", diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json index 21e2bde3f9b9bd..78d191efa38123 100644 --- a/app/javascript/mastodon/locales/zh-TW.json +++ b/app/javascript/mastodon/locales/zh-TW.json @@ -114,29 +114,51 @@ "alt_text_modal.done": "完成", "announcement.announcement": "公告", "annual_report.announcement.action_build": "建立我的 Mastodon 年度回顧 (Wrapstodon)", + "annual_report.announcement.action_dismiss": "不需要,謝謝", "annual_report.announcement.action_view": "檢視我的 Mastodon 年度回顧 (Wrapstodon)", "annual_report.announcement.description": "探索更多關於您過去一年於 Mastodon 上的互動情況。", "annual_report.announcement.title": "您的 Mastodon 年度回顧 {year} 已抵達", - "annual_report.summary.archetype.booster": "酷炫獵人", - "annual_report.summary.archetype.lurker": "潛水高手", - "annual_report.summary.archetype.oracle": "先知", - "annual_report.summary.archetype.pollster": "民調專家", - "annual_report.summary.archetype.replier": "社交菁英", - "annual_report.summary.followers.followers": "跟隨者", - "annual_report.summary.followers.total": "總共 {count} 人", - "annual_report.summary.here_it_is": "以下是您的 {year} 年度回顧:", - "annual_report.summary.highlighted_post.by_favourites": "最多被加至最愛的嘟文", - "annual_report.summary.highlighted_post.by_reblogs": "最多轉嘟的嘟文", - "annual_report.summary.highlighted_post.by_replies": "最多回覆的嘟文", - "annual_report.summary.highlighted_post.possessive": "{name} 的", + "annual_report.nav_item.badge": "新報告", + "annual_report.shared_page.donate": "捐款", + "annual_report.shared_page.footer": "由 Mastodon 團隊 {heart} 產生", + "annual_report.shared_page.footer_server_info": "{username} 使用 {domain},運行 Mastodon 的眾多社群之一。", + "annual_report.summary.archetype.booster.desc_public": "{name} 持續追尋值得轉嘟的嘟文,以精準眼光放大其他創作者之影響力。", + "annual_report.summary.archetype.booster.desc_self": "您持續追尋值得轉嘟的嘟文,以精準眼光放大其他創作者之影響力。", + "annual_report.summary.archetype.booster.name": "弓箭手", + "annual_report.summary.archetype.die_drei_fragezeichen": "???", + "annual_report.summary.archetype.lurker.desc_public": "我們知道 {name} 曾於聯邦宇宙的某個角落駐足,以靜謐的方式獨享 Mastodon。", + "annual_report.summary.archetype.lurker.desc_self": "我們知道您曾於聯邦宇宙的某個角落駐足,以靜謐的方式獨享 Mastodon。", + "annual_report.summary.archetype.lurker.name": "斯多葛主義信徒", + "annual_report.summary.archetype.oracle.desc_public": "{name} 發表的新嘟文多於回嘟,使 Mastodon 注入活力並展望未來。", + "annual_report.summary.archetype.oracle.desc_self": "您發表的新嘟文多於回嘟,使 Mastodon 注入活力並展望未來。", + "annual_report.summary.archetype.oracle.name": "先知", + "annual_report.summary.archetype.pollster.desc_public": "{name} 發起投票多於其他嘟文類型,使 Mastodon 充滿探索與好奇。", + "annual_report.summary.archetype.pollster.desc_self": "您發起投票多於其他嘟文類型,使 Mastodon 充滿探索與好奇。", + "annual_report.summary.archetype.pollster.name": "探究者", + "annual_report.summary.archetype.replier.desc_public": "{name} 經常回覆他人嘟文,替 Mastodon 帶來源源不絕的新討論。", + "annual_report.summary.archetype.replier.desc_self": "您經常回覆他人嘟文,替 Mastodon 帶來源源不絕的新討論。", + "annual_report.summary.archetype.replier.name": "花蝴蝶", + "annual_report.summary.archetype.reveal": "揭露我的類型稱號", + "annual_report.summary.archetype.reveal_description": "感謝您成為 Mastodon 的一分子!是時候揭曉您於 {year} 年份的代表類型。", + "annual_report.summary.archetype.title_public": "{name} 的類型稱號", + "annual_report.summary.archetype.title_self": "您的類型稱號", + "annual_report.summary.close": "關閉", + "annual_report.summary.copy_link": "複製連結", + "annual_report.summary.followers.new_followers": "{count, plural, other {位新跟隨者}}", + "annual_report.summary.highlighted_post.boost_count": "此嘟文被轉嘟 {count, plural, other {# 次}}。", + "annual_report.summary.highlighted_post.favourite_count": "此嘟文被加入最愛 {count, plural, other {# 次}}。", + "annual_report.summary.highlighted_post.reply_count": "此嘟文獲得 {count, plural, other {# 則回覆}}。", + "annual_report.summary.highlighted_post.title": "最受歡迎的嘟文", "annual_report.summary.most_used_app.most_used_app": "最常使用的應用程式", "annual_report.summary.most_used_hashtag.most_used_hashtag": "最常使用的主題標籤", - "annual_report.summary.most_used_hashtag.none": "無最常用之主題標籤", + "annual_report.summary.most_used_hashtag.used_count": "您於 {count, plural, other {# 則嘟文}}中使用此主題標籤。", + "annual_report.summary.most_used_hashtag.used_count_public": "{name} 於 {count, plural, other {# 則嘟文}}中使用此主題標籤。", "annual_report.summary.new_posts.new_posts": "新嘟文", "annual_report.summary.percentile.text": "這讓您成為前{domain} 的使用者。", "annual_report.summary.percentile.we_wont_tell_bernie": "我們不會告訴 Bernie。", + "annual_report.summary.share_elsewhere": "分享至其他地方", "annual_report.summary.share_message": "我獲得 {archetype} 稱號!", - "annual_report.summary.thanks": "感謝您成為 Mastodon 的一份子!", + "annual_report.summary.share_on_mastodon": "於 Mastodon 上分享", "attachments_list.unprocessed": "(未處理)", "audio.hide": "隱藏音訊", "block_modal.remote_users_caveat": "我們會要求 {domain} 伺服器尊重您的決定。然而,我們無法保證所有伺服器皆會遵守,某些伺服器可能以不同方式處理封鎖。未登入之使用者仍可能看見您的公開嘟文。", @@ -358,16 +380,16 @@ "empty_column.hashtag": "這個主題標籤下什麼也沒有。", "empty_column.home": "您的首頁時間軸是空的!跟隨更多人將它填滿吧!", "empty_column.list": "這份列表下什麼也沒有。當此列表的成員嘟出新的嘟文時,它們將顯示於此。", - "empty_column.mutes": "您尚未靜音任何使用者。", + "empty_column.mutes": "您還沒有靜音任何使用者。", "empty_column.notification_requests": "清空啦!已經沒有任何推播通知。當您收到新推播通知時,它們將依照您的設定於此顯示。", "empty_column.notifications": "您還沒有收到任何推播通知,當您與別人開始互動時,它將於此顯示。", "empty_column.public": "這裡什麼都沒有!嘗試寫些公開的嘟文,或著自己跟隨其他伺服器的使用者後就會有嘟文出現了", "error.no_hashtag_feed_access": "加入或登入 Mastodon 以檢視與跟隨此主題標籤。", "error.unexpected_crash.explanation": "由於發生系統故障或瀏覽器相容性問題,無法正常顯示此頁面。", "error.unexpected_crash.explanation_addons": "此頁面無法被正常顯示,這可能是由瀏覽器附加元件或網頁自動翻譯工具造成的。", - "error.unexpected_crash.next_steps": "請嘗試重新整理頁面。如果狀況沒有改善,您可以使用不同的瀏覽器或應用程式以檢視來使用 Mastodon。", - "error.unexpected_crash.next_steps_addons": "請嘗試關閉它們然後重新整理頁面。如果狀況沒有改善,您可以使用不同的瀏覽器或應用程式來檢視來使用 Mastodon。", - "errors.unexpected_crash.copy_stacktrace": "複製 stacktrace 到剪貼簿", + "error.unexpected_crash.next_steps": "請嘗試重新整理頁面。如果狀況沒有改善,您可以透過不同的瀏覽器或應用程式以使用 Mastodon。", + "error.unexpected_crash.next_steps_addons": "請嘗試關閉它們然後重新整理頁面。如果狀況沒有改善,您可以透過不同的瀏覽器或應用程式以使用 Mastodon。", + "errors.unexpected_crash.copy_stacktrace": "複製 stacktrace 至剪貼簿", "errors.unexpected_crash.report_issue": "回報問題", "explore.suggested_follows": "使用者", "explore.title": "熱門", @@ -381,12 +403,12 @@ "filter_modal.added.context_mismatch_title": "不符合情境!", "filter_modal.added.expired_explanation": "此過濾器類別已失效,您需要更新過期日期以套用。", "filter_modal.added.expired_title": "過期的過濾器!", - "filter_modal.added.review_and_configure": "要檢視與進一步設定此過濾器類別,請至 {settings_link}。", + "filter_modal.added.review_and_configure": "如欲檢視與進一步設定此過濾器類別,請至 {settings_link}。", "filter_modal.added.review_and_configure_title": "過濾器設定", "filter_modal.added.settings_link": "設定頁面", "filter_modal.added.short_explanation": "此嘟文已被新增至以下過濾器類別:{title}。", "filter_modal.added.title": "已新增過濾器!", - "filter_modal.select_filter.context_mismatch": "不是用目前情境", + "filter_modal.select_filter.context_mismatch": "不適用目前情境", "filter_modal.select_filter.expired": "已過期", "filter_modal.select_filter.prompt_new": "新類別:{name}", "filter_modal.select_filter.search": "搜尋或新增", @@ -404,13 +426,13 @@ "follow_requests.unlocked_explanation": "即便您的帳號未被鎖定,{domain} 的管理員認為您可能想要自己審核這些帳號的跟隨請求。", "follow_suggestions.curated_suggestion": "精選內容", "follow_suggestions.dismiss": "不再顯示", - "follow_suggestions.featured_longer": "{domain} 團隊精選", + "follow_suggestions.featured_longer": "{domain} 團隊精心挑選", "follow_suggestions.friends_of_friends_longer": "受您跟隨之使用者愛戴的風雲人物", - "follow_suggestions.hints.featured": "這個個人檔案是 {domain} 管理團隊精心挑選的。", - "follow_suggestions.hints.friends_of_friends": "這個個人檔案於您跟隨的帳號中很受歡迎。", - "follow_suggestions.hints.most_followed": "這個個人檔案是 {domain} 中最受歡迎的帳號之一。", - "follow_suggestions.hints.most_interactions": "這個個人檔案最近於 {domain} 受到非常多關注。", - "follow_suggestions.hints.similar_to_recently_followed": "這個個人檔案與您最近跟隨之帳號類似。", + "follow_suggestions.hints.featured": "此個人檔案是 {domain} 管理團隊精心挑選。", + "follow_suggestions.hints.friends_of_friends": "此個人檔案於您跟隨的帳號中很受歡迎。", + "follow_suggestions.hints.most_followed": "此個人檔案是 {domain} 中最受歡迎的帳號之一。", + "follow_suggestions.hints.most_interactions": "此個人檔案最近於 {domain} 受到非常多關注。", + "follow_suggestions.hints.similar_to_recently_followed": "此個人檔案與您最近跟隨之帳號類似。", "follow_suggestions.personalized_suggestion": "個人化推薦", "follow_suggestions.popular_suggestion": "熱門推薦", "follow_suggestions.popular_suggestion_longer": "{domain} 上的人氣王", @@ -419,6 +441,8 @@ "follow_suggestions.who_to_follow": "推薦跟隨帳號", "followed_tags": "已跟隨主題標籤", "footer.about": "關於", + "footer.about_mastodon": "關於 Mastodon", + "footer.about_server": "關於 {domain}", "footer.about_this_server": "關於", "footer.directory": "個人檔案目錄", "footer.get_app": "取得應用程式", @@ -615,7 +639,7 @@ "notification.admin.sign_up": "{name} 已經註冊", "notification.admin.sign_up.name_and_others": "{name} 與{count, plural, other {其他 # 個人}}已註冊", "notification.annual_report.message": "您的 {year} #Wrapstodon 正等著您!揭開您 Mastodon 上的年度精彩時刻與值得回憶的難忘時光!", - "notification.annual_report.view": "檢視 #Wrapstodon", + "notification.annual_report.view": "檢視 #Wrapstodon 年度回顧", "notification.favourite": "{name} 已將您的嘟文加入最愛", "notification.favourite.name_and_others_with_link": "{name} 與{count, plural, other {其他 # 個人}}已將您的嘟文加入最愛", "notification.favourite_pm": "{name} 將您的私訊加入最愛", diff --git a/config/locales/activerecord.ca.yml b/config/locales/activerecord.ca.yml index f53f7f364a0f4e..f92aca17a2e9c5 100644 --- a/config/locales/activerecord.ca.yml +++ b/config/locales/activerecord.ca.yml @@ -32,6 +32,12 @@ ca: attributes: url: invalid: no és un enllaç vàlid + collection: + attributes: + collection_items: + too_many: n'hi ha massa. %{count} és el màxim permès + tag: + unusable: pot no ser emprat doorkeeper/application: attributes: website: diff --git a/config/locales/activerecord.en-GB.yml b/config/locales/activerecord.en-GB.yml index 2402b2f7f253b8..cd94e0942231e2 100644 --- a/config/locales/activerecord.en-GB.yml +++ b/config/locales/activerecord.en-GB.yml @@ -7,7 +7,7 @@ en-GB: options: Choices user: agreement: Service agreement - email: E-mail address + email: Email address locale: Locale password: Password user/account: @@ -26,7 +26,7 @@ en-GB: fields: fields_with_values_missing_labels: contains values with missing labels username: - invalid: must contain only letters, numbers and underscores + invalid: must contain only letters, numbers, and underscores reserved: is reserved admin/webhook: attributes: @@ -64,7 +64,7 @@ en-GB: date_of_birth: below_limit: is below the age limit email: - blocked: uses a disallowed e-mail provider + blocked: uses a disallowed email provider unreachable: does not seem to exist role_id: elevated: cannot be higher than your current role @@ -80,4 +80,4 @@ en-GB: webhook: attributes: events: - invalid_permissions: cannot include events you don't have the rights to + invalid_permissions: cannot include events to which you don't have the rights diff --git a/config/locales/activerecord.eu.yml b/config/locales/activerecord.eu.yml index c0ac1bb338b046..4324106061d9a7 100644 --- a/config/locales/activerecord.eu.yml +++ b/config/locales/activerecord.eu.yml @@ -32,6 +32,12 @@ eu: attributes: url: invalid: ez da baliozko URL bat + collection: + attributes: + collection_items: + too_many: gehiegi dira, eta ez dira onartzen %{count} baino gehiago + tag: + unusable: baliteke ez erabiltzea doorkeeper/application: attributes: website: diff --git a/config/locales/activerecord.ko.yml b/config/locales/activerecord.ko.yml index 3aa991734b832a..05be3155831d08 100644 --- a/config/locales/activerecord.ko.yml +++ b/config/locales/activerecord.ko.yml @@ -32,6 +32,10 @@ ko: attributes: url: invalid: 올바른 URL이 아닙니다 + collection: + attributes: + tag: + unusable: 사용할 수 없음 doorkeeper/application: attributes: website: diff --git a/config/locales/be.yml b/config/locales/be.yml index 3212b7cbb3c9cf..bbe64c59511728 100644 --- a/config/locales/be.yml +++ b/config/locales/be.yml @@ -7,6 +7,8 @@ be: hosted_on: Mastodon месціцца на %{domain} title: Пра нас accounts: + errors: + cannot_be_added_to_collections: Гэты ўліковы запіс нельга дадаць у калекцыі. followers: few: Падпісчыка many: Падпісчыкаў @@ -2274,4 +2276,5 @@ be: otp_required: Каб выкарыстоўваць ключы бяспекі, спачатку ўключыце двухфактарную аўтэнтыфікацыю. registered_on: Зарэгістраваны %{date} wrapstodon: + description: Паглядзіце, як %{name} карыстаў(-ла)ся Mastodon у гэтым годзе! title: Вынікадон %{year} для %{name} diff --git a/config/locales/ca.yml b/config/locales/ca.yml index bc7cd7673accf6..baf33daacf2eb0 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -7,6 +7,8 @@ ca: hosted_on: Mastodon allotjat a %{domain} title: Quant a accounts: + errors: + cannot_be_added_to_collections: Aquest compte no es pot afegir a coŀleccions. followers: one: Seguidor other: Seguidors @@ -2160,4 +2162,5 @@ ca: otp_required: Per a usar claus de seguretat, activeu primer l'autenticació de dos factors. registered_on: Registrat en %{date} wrapstodon: + description: Mira com %{name} ha fet servir Mastodon enguany. title: Wrapstodon %{year} per a %{name} diff --git a/config/locales/cs.yml b/config/locales/cs.yml index 25d61bbb0d9fd6..90f118e82456dc 100644 --- a/config/locales/cs.yml +++ b/config/locales/cs.yml @@ -7,6 +7,8 @@ cs: hosted_on: Mastodon na doméně %{domain} title: O službě accounts: + errors: + cannot_be_added_to_collections: Tento účet nelze přidat do kolekcí. followers: few: Sledující many: Sledujících @@ -2274,4 +2276,5 @@ cs: otp_required: Pro použití bezpečnostních klíčů prosím nejprve zapněte dvoufázové ověřování. registered_on: Přidán %{date} wrapstodon: + description: Podívejte se, jak %{name} používali Mastodon v tomto roce! title: Wrapstodon %{year} pro %{name} diff --git a/config/locales/cy.yml b/config/locales/cy.yml index ad153fdac31458..ab45735c671f01 100644 --- a/config/locales/cy.yml +++ b/config/locales/cy.yml @@ -7,6 +7,8 @@ cy: hosted_on: Mastodon wedi ei weinyddu ar %{domain} title: Ynghylch accounts: + errors: + cannot_be_added_to_collections: Does dim modd ychwanegu'r cyfrif hwn at gasgliadau. followers: few: Dilynwyr many: Dilynwyr @@ -1862,16 +1864,22 @@ cy: body: 'Caswoch eich crybwyll gan %{name} yn:' subject: Cawsoch eich crybwyll gan %{name} title: Crywbylliad newydd + moderation_warning: + subject: Rydych wedi derbyn rhybudd gan gymedrolwr poll: subject: Mae arolwg gan %{name} wedi dod i ben quote: body: 'Mae %{name} wedi dyfynnu eich postiad :' subject: Mae %{name} wedi dyfynnu eich postiad title: Dyfyniad newydd + quoted_update: + subject: Golygodd %{name} bostiad rydych chi wedi'i ddyfynnu reblog: body: 'Cafodd eich postiad ei hybu gan %{name}:' subject: Rhoddodd %{name} hwb i'ch postiad title: Hwb newydd + severed_relationships: + subject: Rydych chi wedi colli cysylltiadau oherwydd penderfyniad cymedroli status: subject: "%{name} newydd ei bostio" update: @@ -2355,3 +2363,6 @@ cy: not_supported: Nid yw'r porwr hwn yn cynnal allweddi diogelwch otp_required: I ddefnyddio allweddi diogelwch, galluogwch ddilysu dau ffactor yn gyntaf. registered_on: Cofrestrwyd ar %{date} + wrapstodon: + description: Gweler sut defnyddiodd %{name} Mastodon eleni! + title: Wrapstodon %{year} ar gyfer %{name} diff --git a/config/locales/da.yml b/config/locales/da.yml index 09bcb6fdf07fe9..e15eeb7dda6637 100644 --- a/config/locales/da.yml +++ b/config/locales/da.yml @@ -7,6 +7,8 @@ da: hosted_on: Mastodon hostet på %{domain} title: Om accounts: + errors: + cannot_be_added_to_collections: Denne konto kan ikke tilføjes til samlinger. followers: one: Følger other: Følgere @@ -2186,4 +2188,5 @@ da: otp_required: For at bruge sikkerhedsnøgler skal tofaktorgodkendelse først aktiveres. registered_on: Registreret d. %{date} wrapstodon: + description: Se hvordan %{name} brugte Mastodon i år! title: Wrapstodon %{year} for %{name} diff --git a/config/locales/de.yml b/config/locales/de.yml index 13fd701bca60a1..04dc47b0387943 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -7,6 +7,8 @@ de: hosted_on: Mastodon, gehostet auf %{domain} title: Über accounts: + errors: + cannot_be_added_to_collections: Dieses Konto darf keinen Sammlungen hinzugefügt werden. followers: one: Follower other: Follower @@ -54,15 +56,15 @@ de: title: Rolle für %{username} ändern confirm: Bestätigen confirmed: Bestätigt - confirming: Bestätigung + confirming: Bestätigung ausstehend custom: Angepasst delete: Daten löschen deleted: Gelöscht demote: Zurückstufen - destroyed_msg: Daten von %{username} wurden zum Löschen in die Warteschlange eingereiht + destroyed_msg: Die Daten von %{username} befinden sich nun in der Warteschlange und werden in Kürze gelöscht disable: Einfrieren disable_sign_in_token_auth: E-Mail-Token-Authentisierung deaktivieren - disable_two_factor_authentication: Zwei-Faktor-Authentisierung deaktivieren + disable_two_factor_authentication: Zwei-Faktor-Authentisierung (2FA) deaktivieren disabled: Eingefroren display_name: Anzeigename domain: Domain @@ -80,7 +82,7 @@ de: invite_request_text: Begründung für das Beitreten invited_by: Eingeladen von ip: IP-Adresse - joined: Mitglied seit + joined: Registriert am location: all: Alle local: Lokal @@ -103,12 +105,12 @@ de: most_recent_activity: Letzte Aktivität most_recent_ip: Letzte IP-Adresse no_account_selected: Keine Konten wurden geändert, da keine ausgewählt wurden - no_limits_imposed: Keine Beschränkungen + no_limits_imposed: Keine Einschränkungen no_role_assigned: Keine Rolle zugewiesen not_subscribed: Nicht abonniert pending: Überprüfung ausstehend perform_full_suspension: Sperren - previous_strikes: Vorherige Maßnahmen + previous_strikes: Frühere Maßnahmen previous_strikes_description_html: one: Gegen dieses Konto wurde eine Maßnahme verhängt. other: Gegen dieses Konto wurden %{count} Maßnahmen verhängt. @@ -129,14 +131,14 @@ de: resend_confirmation: already_confirmed: Dieses Profil wurde bereits bestätigt send: Bestätigungslink erneut zusenden - success: Bestätigungslink erfolgreich gesendet! + success: Bestätigungslink erfolgreich verschickt! reset: Zurücksetzen reset_password: Passwort zurücksetzen resubscribe: Erneut abonnieren role: Rolle search: Suchen search_same_email_domain: Andere Konten mit der gleichen E-Mail-Domain - search_same_ip: Andere Konten mit derselben IP-Adresse + search_same_ip: Andere Konten mit der gleichen IP-Adresse security: Sicherheit security_measures: only_password: Nur Passwort @@ -145,7 +147,7 @@ de: sensitized: Mit Inhaltswarnung versehen shared_inbox_url: Geteilte Posteingangsadresse show: - created_reports: Erstellte Meldungen + created_reports: Eingereichte Meldungen targeted_reports: Von Anderen gemeldet silence: Stummschalten silenced: Stummgeschaltet @@ -209,7 +211,7 @@ de: disable_custom_emoji: Eigenes Emoji deaktivieren disable_relay: Relais deaktivieren disable_sign_in_token_auth_user: E-Mail-Token-Authentisierung für dieses Konto deaktivieren - disable_user: Benutzer*in deaktivieren + disable_user: Profil deaktivieren enable_custom_emoji: Eigenes Emoji aktivieren enable_relay: Relais aktivieren enable_sign_in_token_auth_user: E-Mail-Token-Authentisierung für dieses Konto aktivieren @@ -333,8 +335,8 @@ de: scheduled_for: Geplant für %{time} scheduled_msg: Ankündigung ist zur Veröffentlichung vorgemerkt! title: Ankündigungen - unpublish: Veröffentlichung rückgängig machen - unpublished_msg: Ankündigung ist jetzt nicht mehr sichtbar! + unpublish: Ankündigung zurücknehmen + unpublished_msg: Ankündigung erfolgreich zurückgenommen! updated_msg: Ankündigung erfolgreich aktualisiert! critical_update_pending: Kritisches Update ausstehend custom_emojis: @@ -376,7 +378,7 @@ de: interactions: Interaktionen media_storage: Medien new_users: neue Profile - opened_reports: eingereichte Meldungen + opened_reports: Unbearbeitete Meldungen pending_appeals_html: one: "%{count} ausstehender Einspruch" other: "%{count} ausstehende Einsprüche" @@ -1505,7 +1507,7 @@ de: too_large: Datei ist zu groß failures: Fehler imported: Importiert - mismatched_types_warning: Möglicherweise hast du den falschen Typ für diesen Import ausgewählt. Bitte überprüfe alles noch einmal. + mismatched_types_warning: Möglicherweise hast du das falsche Format für diesen Import ausgewählt. Bitte überprüfe alles noch einmal. modes: merge: Zusammenführen merge_long: Bestehende Datensätze beibehalten und neue hinzufügen @@ -2025,7 +2027,7 @@ de: too_many_requests: Der Übersetzungsdienst hat kürzlich zu viele Anfragen erhalten. two_factor_authentication: add: Hinzufügen - disable: Zwei-Faktor-Authentisierung deaktivieren + disable: Zwei-Faktor-Authentisierung (2FA) deaktivieren disabled_success: Zwei-Faktor-Authentisierung erfolgreich deaktiviert edit: Bearbeiten enabled: Zwei-Faktor-Authentisierung (2FA) ist aktiviert @@ -2155,7 +2157,7 @@ de: users: follow_limit_reached: Du kannst nicht mehr als %{limit} Profilen folgen go_to_sso_account_settings: Kontoeinstellungen des Identitätsanbieters aufrufen - invalid_otp_token: Ungültiger Code der Zwei-Faktor-Authentisierung + invalid_otp_token: Ungültiger Code der Zwei-Faktor-Authentisierung (2FA) otp_lost_help_html: Wenn du sowohl die E-Mail-Adresse als auch das Passwort nicht mehr weißt, melde dich bitte bei uns unter %{email} rate_limited: Zu viele Authentisierungsversuche. Bitte versuche es später noch einmal. seamless_external_login: Du bist über einen externen Dienst angemeldet, daher sind Passwort- und E-Mail-Einstellungen nicht verfügbar. @@ -2186,4 +2188,5 @@ de: otp_required: Um Sicherheitsschlüssel zu verwenden, aktiviere zunächst die Zwei-Faktor-Authentisierung. registered_on: Registriert am %{date} wrapstodon: + description: Sieh dir an, wie %{name} dieses Jahr Mastodon verwendet hat! title: Wrapstodon %{year} für %{name} diff --git a/config/locales/devise.el.yml b/config/locales/devise.el.yml index eaab37f48d94b9..86134b9491f40b 100644 --- a/config/locales/devise.el.yml +++ b/config/locales/devise.el.yml @@ -8,7 +8,7 @@ el: failure: already_authenticated: Έχεις ήδη συνδεθεί. closed_registrations: Η προσπάθεια εγγραφής σας έχει αποκλειστεί λόγω μιας πολιτικής δικτύου. Αν πιστεύετε ότι πρόκειται για σφάλμα, επικοινωνήστε με το %{email}. - inactive: Ο λογαριασμός σου δεν έχει ενεργοποιηθεί ακόμα. + inactive: Ο λογαριασμός σου δεν έχει ενεργοποιηθεί ακόμη. invalid: Λάθος %{authentication_keys} ή συνθηματικό. last_attempt: Έχεις μια ακόμα προσπάθεια πριν κλειδωθεί ο λογαριασμός σου. locked: Ο λογαριασμός σου κλειδώθηκε. diff --git a/config/locales/devise.en-GB.yml b/config/locales/devise.en-GB.yml index 118423c966cfa4..c4650577d77717 100644 --- a/config/locales/devise.en-GB.yml +++ b/config/locales/devise.en-GB.yml @@ -23,66 +23,66 @@ en-GB: action: Verify email address action_with_app: Confirm and return to %{app} explanation: You have created an account on %{host} with this email address. You are one click away from activating it. If this wasn't you, please ignore this email. - explanation_when_pending: You applied for an invite to %{host} with this email address. Once you confirm your e-mail address, we will review your application. You can log in to change your details or delete your account, but you cannot access most of the functions until your account is approved. If your application is rejected, your data will be removed, so no further action will be required from you. If this wasn't you, please ignore this email. + explanation_when_pending: You applied for an invite to %{host} with this email address. Once you confirm your email address, we will review your application. You can log in to change your details or delete your account, but you cannot access most of the functions until your account is approved. If your application is rejected, your data will be removed, so no further action will be required from you. If this wasn't you, please ignore this email. extra_html: Please also check out the rules of the server and our terms of service. - subject: 'Mastodon: Confirmation instructions for %{instance}' + subject: 'Mastodon: confirmation instructions for %{instance}' title: Verify email address email_changed: explanation: 'The email address for your account is being changed to:' extra: If you did not change your email, it is likely that someone has gained access to your account. Please change your password immediately or contact the server admin if you're locked out of your account. - subject: 'Mastodon: Email changed' + subject: 'Mastodon: email changed' title: New email address password_change: explanation: The password for your account has been changed. extra: If you did not change your password, it is likely that someone has gained access to your account. Please change your password immediately or contact the server admin if you're locked out of your account. - subject: 'Mastodon: Password changed' + subject: 'Mastodon: password changed' title: Password changed reconfirmation_instructions: explanation: Confirm the new address to change your email. extra: If this change wasn't initiated by you, please ignore this email. The email address for the Mastodon account won't change until you access the link above. - subject: 'Mastodon: Confirm email for %{instance}' + subject: 'Mastodon: confirm email for %{instance}' title: Verify email address reset_password_instructions: action: Change password explanation: You requested a new password for your account. extra: If you didn't request this, please ignore this email. Your password won't change until you access the link above and create a new one. - subject: 'Mastodon: Reset password instructions' + subject: 'Mastodon: reset password instructions' title: Password reset two_factor_disabled: - explanation: Login is now possible using only e-mail address and password. - subject: 'Mastodon: Two-factor authentication disabled' + explanation: Login is now possible using only email address and password. + subject: 'Mastodon: two-factor authentication disabled' subtitle: Two-factor authentication for your account has been disabled. title: 2FA disabled two_factor_enabled: explanation: A token generated by the paired TOTP app will be required for login. - subject: 'Mastodon: Two-factor authentication enabled' + subject: 'Mastodon: two-factor authentication enabled' subtitle: Two-factor authentication has been enabled for your account. title: 2FA enabled two_factor_recovery_codes_changed: explanation: The previous recovery codes have been invalidated and new ones generated. - subject: 'Mastodon: Two-factor recovery codes re-generated' + subject: 'Mastodon: two-factor recovery codes re-generated' subtitle: The previous recovery codes have been invalidated and new ones generated. title: 2FA recovery codes changed unlock_instructions: - subject: 'Mastodon: Unlock instructions' + subject: 'Mastodon: unlock instructions' webauthn_credential: added: explanation: The following security key has been added to your account - subject: 'Mastodon: New security key' + subject: 'Mastodon: new security key' title: A new security key has been added deleted: explanation: The following security key has been deleted from your account - subject: 'Mastodon: Security key deleted' + subject: 'Mastodon: security key deleted' title: One of your security keys has been deleted webauthn_disabled: explanation: Authentication with security keys has been disabled for your account. extra: Login is now possible using only the token generated by the paired TOTP app. - subject: 'Mastodon: Authentication with security keys disabled' + subject: 'Mastodon: authentication with security keys disabled' title: Security keys disabled webauthn_enabled: explanation: Security key authentication has been enabled for your account. extra: Your security key can now be used for login. - subject: 'Mastodon: Security key authentication enabled' + subject: 'Mastodon: security key authentication enabled' title: Security keys enabled omniauth_callbacks: failure: Could not authenticate you from %{kind} because “%{reason}”. diff --git a/config/locales/doorkeeper.de.yml b/config/locales/doorkeeper.de.yml index 6d0e3010af7523..98a6d45da5f355 100644 --- a/config/locales/doorkeeper.de.yml +++ b/config/locales/doorkeeper.de.yml @@ -101,7 +101,7 @@ de: temporarily_unavailable: Der Autorisierungs-Server ist aufgrund von zwischenzeitlicher Überlastung oder Wartungsarbeiten derzeit nicht in der Lage, die Anfrage zu bearbeiten. unauthorized_client: Der Client ist nicht dazu autorisiert, diese Anfrage mit dieser Methode auszuführen. unsupported_grant_type: Der Autorisierungs-Typ wird nicht vom Autorisierungs-Server unterstützt. - unsupported_response_type: Der Autorisierungs-Server unterstützt diesen Antwort-Typ nicht. + unsupported_response_type: Der Autorisierungsserver unterstützt dieses Antwortformat nicht. flash: applications: create: diff --git a/config/locales/doorkeeper.en-GB.yml b/config/locales/doorkeeper.en-GB.yml index 63a4575e83ce51..5b4b99858cccdb 100644 --- a/config/locales/doorkeeper.en-GB.yml +++ b/config/locales/doorkeeper.en-GB.yml @@ -96,7 +96,7 @@ en-GB: expired: The access token expired revoked: The access token was revoked unknown: The access token is invalid - resource_owner_authenticator_not_configured: Resource Owner find failed due to Doorkeeper.configure.resource_owner_authenticator being unconfiged. + resource_owner_authenticator_not_configured: Resource Owner find failed due to Doorkeeper.configure.resource_owner_authenticator being unconfigured. server_error: The authorisation server encountered an unexpected condition which prevented it from fulfilling the request. temporarily_unavailable: The authorisation server is currently unable to handle the request due to a temporary overloading or maintenance of the server. unauthorized_client: The client is not authorised to perform this request using this method. @@ -130,7 +130,7 @@ en-GB: crypto: End-to-end encryption favourites: Favourites filters: Filters - follow: Follows, Mutes and Blocks + follow: Follows, Mutes, and Blocks follows: Follows lists: Lists media: Media attachments diff --git a/config/locales/el.yml b/config/locales/el.yml index a17c20bdece415..67e3f337ade1fe 100644 --- a/config/locales/el.yml +++ b/config/locales/el.yml @@ -7,6 +7,8 @@ el: hosted_on: Το Mastodon φιλοξενείται στο %{domain} title: Σχετικά accounts: + errors: + cannot_be_added_to_collections: Αυτός ο λογαριασμός δεν μπορεί να προστεθεί σε συλλογές. followers: one: Ακόλουθος other: Ακόλουθοι @@ -308,7 +310,7 @@ el: update_status_html: Ο/Η %{name} ενημέρωσε την ανάρτηση του/της %{target} update_user_role_html: Ο/Η %{name} άλλαξε τον ρόλο %{target} update_username_block_html: "%{name} ενημέρωσε κανόνα για ονόματα χρηστών που περιέχουν %{target}" - deleted_account: διαγεγραμμένος λογαριασμός + deleted_account: λογαριασμός διαγράφηκε empty: Δεν βρέθηκαν αρχεία καταγραφής. filter_by_action: Φιλτράρισμα ανά ενέργεια filter_by_user: Φιλτράρισμα ανά χρήστη @@ -751,7 +753,7 @@ el: description_html: Με τους ρόλους χρηστών, μπορείς να προσαρμόσεις σε ποιες λειτουργίες και περιοχές του Mastodon, οι χρήστες σας μπορούν να έχουν πρόσβαση. edit: Επεξεργασία ρόλου '%{name}' everyone: Προεπιλεγμένα δικαιώματα - everyone_full_description_html: Αυτός είναι ο βασικός ρόλος που επηρεάζει όλους τους χρήστες, ακόμη και εκείνους που δεν έχουν κάποιον ρόλο. Όλοι οι άλλοι ρόλοι κληρονομούν δικαιώματα από αυτόν. + everyone_full_description_html: Αυτός είναι ο βασικός ρόλος που επηρεάζει όλους τους χρήστες, ακόμα και εκείνους που δεν έχουν κάποιον ρόλο. Όλοι οι άλλοι ρόλοι κληρονομούν δικαιώματα από αυτόν. permissions_count: one: "%{count} δικαίωμα" other: "%{count} δικαιώματα" @@ -805,7 +807,7 @@ el: delete: Διαγραφή description_html: Ενώ οι περισσότεροι ισχυρίζονται ότι έχουν διαβάσει και συμφωνούν με τους όρους της υπηρεσίας, συνήθως οι άνθρωποι δεν διαβάζουν μέχρι μετά την εμφάνιση ενός προβλήματος. Κάνε ευκολότερο να δουν τους κανόνες του διακομιστή σας με μια ματιά παρέχοντας τους σε μια λίστα. Προσπάθησε να κρατήσεις τους μεμονωμένους κανόνες σύντομους και απλούς, αλλά προσπάθησε να μην τους χωρίσεις σε πολλά ξεχωριστά αντικείμενα. edit: Επεξεργασία κανόνα - empty: Δεν έχουν οριστεί ακόμα κανόνες διακομιστή. + empty: Δεν έχουν οριστεί ακόμη κανόνες διακομιστή. move_down: Μετακίνηση κάτω move_up: Μετακίνηση πάνω title: Κανόνες διακομιστή @@ -1015,7 +1017,7 @@ el: going_live_on_html: Ενεργό, σε ισχύ από %{date} history: Ιστορικό live: Ενεργό - no_history: Δεν υπάρχουν ακόμα καταγεγραμμένες αλλαγές στους όρους παροχής υπηρεσιών. + no_history: Δεν υπάρχουν ακόμη καταγεγραμμένες αλλαγές στους όρους παροχής υπηρεσιών. no_terms_of_service_html: Δεν έχετε ρυθμίσει τους όρους της υπηρεσίας. Οι όροι της υπηρεσίας αποσκοπούν στην παροχή σαφήνειας και την προστασία σου από πιθανές υποχρεώσεις σε διαφορές με τους χρήστες σου. notified_on_html: Οι χρήστες ειδοποιήθηκαν στις %{date} notify_users: Ειδοποίηση χρηστών @@ -1137,7 +1139,7 @@ el: disable: Απενεργοποίηση disabled: Απενεργοποιημένα edit: Επεξεργασία σημείου τερματισμού - empty: Δεν έχεις ακόμα ρυθμισμένα σημεία τερματισμού webhook. + empty: Δεν έχεις ακόμη ρυθμισμένα σημεία τερματισμού webhook. enable: Ενεργοποίηση enabled: Ενεργό enabled_events: @@ -1226,7 +1228,7 @@ el: apply_for_account: Ζήτα έναν λογαριασμό captcha_confirmation: help_html: Εάν αντιμετωπίζεις προβλήματα με την επίλυση του CAPTCHA, μπορείς να επικοινωνήσεις μαζί μας μέσω %{email} και μπορούμε να σε βοηθήσουμε. - hint_html: Και κάτι ακόμα! Πρέπει να επιβεβαιώσουμε ότι είσαι άνθρωπος (αυτό γίνεται για να κρατήσουμε μακριά το σπαμ!). Λύσε το CAPTCHA παρακάτω και κάνε κλικ "Συνέχεια". + hint_html: Και κάτι ακόμα! Πρέπει να επιβεβαιώσουμε ότι είσαι άνθρωπος (αυτό γίνεται για να κρατήσουμε μακριά το σπαμ!). Λύσε το CAPTCHA παρακάτω και πάτα "Συνέχεια". title: Ελεγχος ασφαλείας confirmations: awaiting_review: Η διεύθυνση email σου επιβεβαιώθηκε! Το προσωπικό του %{domain} εξετάζει τώρα την εγγραφή σου. Θα λάβεις ένα email εάν εγκρίνουν τον λογαριασμό σου! @@ -1827,7 +1829,7 @@ el: over_total_limit: Έχεις υπερβεί το όριο των %{limit} προγραμματισμένων αναρτήσεων too_soon: η ημερομηνία πρέπει να είναι στο μέλλον self_destruct: - lead_html: Δυστυχώς, το %{domain} κλείνει οριστικά. Αν είχατε λογαριασμό εκεί, δεν θα μπορείτε να συνεχίσετε τη χρήση του, αλλά μπορείτε ακόμα να ζητήσετε ένα αντίγραφο ασφαλείας των δεδομένων σας. + lead_html: Δυστυχώς, το %{domain} κλείνει οριστικά. Αν είχατε λογαριασμό εκεί, δεν θα μπορείτε να συνεχίσετε τη χρήση του, αλλά μπορείτε ακόμη να ζητήσετε ένα αντίγραφο ασφαλείας των δεδομένων σας. title: Αυτός ο διακομιστής κλείνει οριστικά sessions: activity: Τελευταία δραστηριότητα @@ -1967,7 +1969,7 @@ el: ignore_favs: Αγνόηση αγαπημένων ignore_reblogs: Αγνόηση ενισχύσεων interaction_exceptions: Εξαιρέσεις βασισμένες σε αλληλεπιδράσεις - interaction_exceptions_explanation: Σημείωσε ότι δεν υπάρχει εγγύηση για πιθανή διαγραφή αναρτήσεων αν αυτά πέσουν κάτω από το όριο αγαπημένων ή ενισχύσεων ακόμα και αν κάποτε το είχαν ξεπεράσει. + interaction_exceptions_explanation: Σημείωσε ότι δεν υπάρχει εγγύηση για πιθανή διαγραφή αναρτήσεων αν αυτά πέσουν κάτω από το όριο αγαπημένων ή ενισχύσεων ακόμη και αν κάποτε το είχαν ξεπεράσει. keep_direct: Διατήρηση άμεσων μηνυμάτων keep_direct_hint: Δεν διαγράφει κανένα από τα άμεσα μηνύματά σου keep_media: Διατήρηση αναρτήσεων με συνημμένα πολυμέσων @@ -2092,8 +2094,8 @@ el: disable: Δεν μπορείς πλέον να χρησιμοποιήσεις τον λογαριασμό σου, αλλά το προφίλ σου και άλλα δεδομένα παραμένουν άθικτα. Μπορείς να ζητήσεις ένα αντίγραφο ασφαλείας των δεδομένων σου, να αλλάξεις τις ρυθμίσεις του λογαριασμού σου ή να διαγράψεις τον λογαριασμό σου. mark_statuses_as_sensitive: Μερικές από τις αναρτήσεις σου έχουν επισημανθεί ως ευαίσθητες από τους συντονιστές του %{instance}. Αυτό σημαίνει ότι οι άνθρωποι θα πρέπει να πατήσουν τα πολυμέσα στις αναρτήσεις πριν εμφανιστεί μια προεπισκόπηση. Μπορείς να επισημάνεις τα πολυμέσα ως ευαίσθητα όταν δημοσιεύεις στο μέλλον. sensitive: Από δω και στο εξής, όλα τα μεταφορτωμένα αρχεία πολυμέσων σου θα επισημανθούν ως ευαίσθητα και κρυμμένα πίσω από μια προειδοποίηση που πρέπει να πατηθεί. - silence: Μπορείς ακόμα να χρησιμοποιείς τον λογαριασμό σου, αλλά μόνο άτομα που σε ακολουθούν ήδη θα δουν τις αναρτήσεις σου σε αυτόν τον διακομιστή και μπορεί να αποκλειστείς από διάφορες δυνατότητες ανακάλυψης. Ωστόσο, οι άλλοι μπορούν ακόμα να σε ακολουθήσουν με μη αυτόματο τρόπο. - suspend: Δε μπορείς πλέον να χρησιμοποιήσεις τον λογαριασμό σου και το προφίλ σου και άλλα δεδομένα δεν είναι πλέον προσβάσιμα. Μπορείς ακόμα να συνδεθείς για να αιτηθείς αντίγραφο των δεδομένων σου μέχρι να αφαιρεθούν πλήρως σε περίπου 30 μέρες αλλά, θα διατηρήσουμε κάποια βασικά δεδομένα για να σε αποτρέψουμε να παρακάμψεις την αναστολή. + silence: Μπορείς ακόμη να χρησιμοποιείς τον λογαριασμό σου, αλλά μόνο άτομα που σε ακολουθούν ήδη θα δουν τις αναρτήσεις σου σε αυτόν τον διακομιστή και μπορεί να αποκλειστείς από διάφορες δυνατότητες ανακάλυψης. Ωστόσο, οι άλλοι μπορούν ακόμη να σε ακολουθήσουν με μη αυτόματο τρόπο. + suspend: Δε μπορείς πλέον να χρησιμοποιήσεις τον λογαριασμό σου, και το προφίλ σου και άλλα δεδομένα δεν είναι πλέον προσβάσιμα. Μπορείς ακόμη να συνδεθείς για να αιτηθείς αντίγραφο των δεδομένων σου μέχρι να αφαιρεθούν πλήρως σε περίπου 30 μέρες αλλά, θα διατηρήσουμε κάποια βασικά δεδομένα για να σε αποτρέψουμε να παρακάμψεις την αναστολή. reason: 'Αιτιολογία:' statuses: 'Αναφερόμενες αναρτήσεις:' subject: @@ -2161,7 +2163,7 @@ el: seamless_external_login: Επειδή έχεις συνδεθεί μέσω τρίτης υπηρεσίας, οι ρυθμίσεις συνθηματικού και email δεν είναι διαθέσιμες. signed_in_as: 'Έχεις συνδεθεί ως:' verification: - extra_instructions_html: Συμβουλή: Ο σύνδεσμος στην ιστοσελίδα σου μπορεί να είναι αόρατος. Το σημαντικό μέρος είναι το rel="me" που αποτρέπει την μίμηση σε ιστοσελίδες με περιεχόμενο παραγόμενο από χρήστες. Μπορείς ακόμη να χρησιμοποιήσεις μια ετικέτα συνδέσμου στην κεφαλίδα της σελίδας αντί για a, αλλά ο κώδικας HTML πρέπει να είναι προσβάσιμος χωρίς την εκτέλεση JavaScript. + extra_instructions_html: Συμβουλή: Ο σύνδεσμος στην ιστοσελίδα σου μπορεί να είναι αόρατος. Το σημαντικό μέρος είναι το rel="me" που αποτρέπει την μίμηση σε ιστοσελίδες με περιεχόμενο παραγόμενο από χρήστες. Μπορείς ακόμα να χρησιμοποιήσεις μια ετικέτα συνδέσμου στην κεφαλίδα της σελίδας αντί για a, αλλά ο κώδικας HTML πρέπει να είναι προσβάσιμος χωρίς την εκτέλεση JavaScript. here_is_how: Δείτε πώς hint_html: Η επαλήθευση της ταυτότητας στο Mastodon είναι για όλους. Βασισμένο σε ανοιχτά πρότυπα ιστού, τώρα και για πάντα δωρεάν. Το μόνο που χρειάζεσαι είναι μια προσωπική ιστοσελίδα που ο κόσμος να σε αναγνωρίζει από αυτή. Όταν συνδέεσαι σε αυτήν την ιστοσελίδα από το προφίλ σου, θα ελέγξουμε ότι η ιστοσελίδα συνδέεται πίσω στο προφίλ σου και θα δείξει μια οπτική ένδειξη σε αυτό. instructions_html: Αντέγραψε και επικόλλησε τον παρακάτω κώδικα στην HTML της ιστοσελίδας σου. Στη συνέχεια, πρόσθεσε τη διεύθυνση της ιστοσελίδας σου σε ένα από τα επιπλέον πεδία στο προφίλ σου από την καρτέλα "Επεξεργασία προφίλ" και αποθήκευσε τις αλλαγές. @@ -2181,9 +2183,10 @@ el: success: Το κλειδί ασφαλείας σου διαγράφηκε με επιτυχία. invalid_credential: Άκυρο κλειδί ασφαλείας nickname_hint: Βάλε το ψευδώνυμο του νέου κλειδιού ασφαλείας σου - not_enabled: Δεν έχεις ενεργοποιήσει το WebAuthn ακόμα + not_enabled: Δεν έχεις ενεργοποιήσει το WebAuthn ακόμη not_supported: Αυτό το πρόγραμμα περιήγησης δεν υποστηρίζει κλειδιά ασφαλείας otp_required: Για να χρησιμοποιήσεις κλειδιά ασφαλείας, ενεργοποίησε πρώτα την ταυτοποίηση δύο παραγόντων. registered_on: Εγγραφή στις %{date} wrapstodon: + description: Δείτε πώς ο/η %{name} χρησιμοποίησε το Mastodon φέτος! title: Wrapstodon %{year} για %{name} diff --git a/config/locales/en-GB.yml b/config/locales/en-GB.yml index 7a08b1c63e853d..2e0e1d47faa420 100644 --- a/config/locales/en-GB.yml +++ b/config/locales/en-GB.yml @@ -7,6 +7,8 @@ en-GB: hosted_on: Mastodon hosted on %{domain} title: About accounts: + errors: + cannot_be_added_to_collections: This account cannot be added to collections. followers: one: Follower other: Followers @@ -102,7 +104,7 @@ en-GB: moderation_notes: Moderation notes most_recent_activity: Most recent activity most_recent_ip: Most recent IP - no_account_selected: No accounts were changed as none were selected + no_account_selected: No accounts were changed, as none were selected no_limits_imposed: No limits imposed no_role_assigned: No role assigned not_subscribed: Not subscribed @@ -154,7 +156,7 @@ en-GB: subscribe: Subscribe suspend: Suspend suspended: Suspended - suspension_irreversible: The data of this account has been irreversibly deleted. You can unsuspend the account to make it usable but it will not recover any data it previously had. + suspension_irreversible: The data of this account has been irreversibly deleted. You can unsuspend the account to make it usable, but it will not recover any data it previously had. suspension_reversible_hint_html: The account has been suspended, and the data will be fully removed on %{date}. Until then, the account can be restored without any ill effects. If you wish to remove all of the account's data immediately, you can do so below. title: Accounts unblock_email: Unblock email address @@ -273,7 +275,7 @@ en-GB: destroy_unavailable_domain_html: "%{name} stopped delivery to domain %{target}" destroy_user_role_html: "%{name} deleted %{target} role" destroy_username_block_html: "%{name} removed rule for usernames containing %{target}" - disable_2fa_user_html: "%{name} disabled two factor requirement for user %{target}" + disable_2fa_user_html: "%{name} disabled two-factor requirement for user %{target}" disable_custom_emoji_html: "%{name} disabled emoji %{target}" disable_relay_html: "%{name} disabled the relay %{target}" disable_sign_in_token_auth_user_html: "%{name} disabled email token authentication for %{target}" @@ -326,7 +328,7 @@ en-GB: title: New announcement preview: disclaimer: As users cannot opt out of them, email notifications should be limited to important announcements such as personal data breach or server closure notifications. - explanation_html: 'The email will be sent to %{display_count} users. The following text will be included in the e-mail:' + explanation_html: 'The email will be sent to %{display_count} users. The following text will be included in the email:' title: Preview announcement notification publish: Publish published_msg: Announcement successfully published! @@ -363,7 +365,7 @@ en-GB: not_permitted: You are not permitted to perform this action overwrite: Overwrite shortcode: Shortcode - shortcode_hint: At least 2 characters, only alphanumeric characters and underscores + shortcode_hint: At least two characters, only alphanumeric characters and underscores title: Custom emojis uncategorized: Uncategorised unlist: Unlist @@ -443,7 +445,7 @@ en-GB: private_comment: Private comment private_comment_hint: Comment about this domain limitation for internal use by the moderators. public_comment: Public comment - public_comment_hint: Comment about this domain limitation for the general public, if advertising the list of domain limitations is enabled. + public_comment_hint: Comment about this domain limitation for the general public if advertising the list of domain limitations is enabled. reject_media: Reject media files reject_media_hint: Removes locally stored media files and refuses to download any in the future. Irrelevant for suspensions reject_reports: Reject reports @@ -547,7 +549,7 @@ en-GB: content_policies: comment: Internal note description_html: You can define content policies that will be applied to all accounts from this domain and any of its subdomains. - limited_federation_mode_description_html: You can chose whether to allow federation with this domain. + limited_federation_mode_description_html: You can choose whether to allow federation with this domain. policies: reject_media: Reject media reject_reports: Reject reports @@ -616,15 +618,15 @@ en-GB: created_msg: Successfully added new IP rule delete: Delete expires_in: - '1209600': 2 weeks - '15778476': 6 months - '2629746': 1 month - '31556952': 1 year - '86400': 1 day - '94670856': 3 years + '1209600': two weeks + '15778476': six months + '2629746': one month + '31556952': one year + '86400': one day + '94670856': three years new: title: Create new IP rule - no_ip_block_selected: No IP rules were changed as none were selected + no_ip_block_selected: No IP rules were changed, as none were selected title: IP rules relationships: title: "%{acct}'s relationships" @@ -640,7 +642,7 @@ en-GB: inbox_url: Relay URL pending: Waiting for relay's approval save_and_enable: Save and enable - setup: Setup a relay connection + setup: Set up a relay connection signatures_not_enabled: Relays may not work correctly while secure mode or limited federation mode is enabled status: Status title: Relays @@ -657,12 +659,12 @@ en-GB: actions: delete_description_html: The reported posts will be deleted and a strike will be recorded to help you escalate on future infractions by the same account. mark_as_sensitive_description_html: The media in the reported posts will be marked as sensitive and a strike will be recorded to help you escalate on future infractions by the same account. - other_description_html: See more options for controlling the account's behaviour and customise communication to the reported account. + other_description_html: See more options for controlling the account's behaviour and customising communication to the reported account. resolve_description_html: No action will be taken against the reported account, no strike recorded, and the report will be closed. - silence_description_html: The account will be visible only to those who already follow it or manually look it up, severely limiting its reach. Can always be reverted. Closes all reports against this account. - suspend_description_html: The account and all its contents will be inaccessible and eventually deleted, and interacting with it will be impossible. Reversible within 30 days. Closes all reports against this account. + silence_description_html: The account will be visible only to those who already follow it or manually look it up, severely limiting its reach. This can always be reverted. This closes all reports against this account. + suspend_description_html: The account and all its contents will be inaccessible and eventually deleted, and interacting with it will be impossible. This is reversible within 30 days. This closes all reports against this account. actions_description_html: Decide which action to take to resolve this report. If you take a punitive action against the reported account, an email notification will be sent to them, except when the Spam category is selected. - actions_description_remote_html: Decide which action to take to resolve this report. This will only affect how your server communicates with this remote account and handle its content. + actions_description_remote_html: Decide which action to take to resolve this report. This will only affect how your server communicates with this remote account and handles its content. actions_no_posts: This report doesn't have any associated posts to delete add_to_report: Add more to report already_suspended_badges: @@ -724,7 +726,7 @@ en-GB: suspend_html: Suspend @%{acct}, making their profile and contents inaccessible and impossible to interact with close_report: 'Mark report #%{id} as resolved' close_reports_html: Mark all reports against @%{acct} as resolved - delete_data_html: Delete @%{acct}'s profile and contents 30 days from now unless they get unsuspended in the meantime + delete_data_html: Delete @%{acct}'s profile and contents 30 days from now, unless they get unsuspended in the meantime preview_preamble_html: "@%{acct} will receive a warning with the following contents:" record_strike_html: Record a strike against @%{acct} to help you escalate on future violations from this account send_email_html: Send @%{acct} a warning email @@ -748,7 +750,7 @@ en-GB: moderation: Moderation special: Special delete: Delete - description_html: With user roles, you can customize which functions and areas of Mastodon your users can access. + description_html: With user roles, you can customise which functions and areas of Mastodon your users can access. edit: Edit '%{name}' role everyone: Default permissions everyone_full_description_html: This is the base role affecting all users, even those without an assigned role. All other roles inherit permissions from it. @@ -815,11 +817,11 @@ en-GB: settings: about: manage_rules: Manage server rules - preamble: Provide in-depth information about how the server is operated, moderated, funded. - rules_hint: There is a dedicated area for rules that your users are expected to adhere to. + preamble: Provide in-depth information about how the server is operated, moderated, and funded. + rules_hint: There is a dedicated area for rules to which your users are expected to adhere. title: About allow_referrer_origin: - desc: When your users click links to external sites, their browser may send the address of your Mastodon server as the referrer. Disable this if this would uniquely identify your users, e.g. if this is a personal Mastodon server. + desc: When your users click links to external sites, their browser may send the address of your Mastodon server as the referrer. Disable this if this would uniquely identify your users, eg if this is a personal Mastodon server. title: Allow external sites to see your Mastodon server as a traffic source appearance: preamble: Customise Mastodon's web interface. @@ -880,7 +882,7 @@ en-GB: delete: Delete uploaded file destroyed_msg: Site upload successfully deleted! software_updates: - critical_update: Critical — please update quickly + critical_update: Critical – please update quickly description: It is recommended to keep your Mastodon installation up to date to benefit from the latest fixes and features. Moreover, it is sometimes critical to update Mastodon in a timely manner to avoid security issues. For these reasons, Mastodon checks for updates every 30 minutes, and will notify you according to your email notification preferences. documentation_link: Learn more release_notes: Release notes @@ -889,7 +891,7 @@ en-GB: types: major: Major release minor: Minor release - patch: Patch release — bugfixes and easy to apply changes + patch: Patch release – bug fixes and easy to apply changes version: Version statuses: account: Author @@ -918,7 +920,7 @@ en-GB: replied_to_html: Replied to %{acct_link} status_changed: Post changed status_title: Post by @%{name} - title: Account posts - @%{name} + title: Account posts – @%{name} trending: Trending view_publicly: View publicly view_quoted_post: View quoted post @@ -973,7 +975,7 @@ en-GB: message_html: A critical Mastodon update is available, please update as quickly as possible. software_version_patch_check: action: See available updates - message_html: A bugfix Mastodon update is available. + message_html: A bug fix Mastodon update is available. upload_check_privacy_error: action: Check here for more information message_html: "Your web server is misconfigured. The privacy of your users is at risk." @@ -1020,7 +1022,7 @@ en-GB: notified_on_html: Users notified on %{date} notify_users: Notify users preview: - explanation_html: 'The email will be sent to %{display_count} users who have signed up before %{date}. The following text will be included in the e-mail:' + explanation_html: 'The email will be sent to %{display_count} users who have signed up before %{date}. The following text will be included in the email:' send_preview: Send preview to %{email} send_to_all: one: Send %{display_count} email @@ -1044,12 +1046,12 @@ en-GB: confirm_allow_provider: Are you sure you want to allow selected providers? confirm_disallow: Are you sure you want to disallow selected links? confirm_disallow_provider: Are you sure you want to disallow selected providers? - description_html: These are links that are currently being shared a lot by accounts that your server sees posts from. It can help your users find out what's going on in the world. No links are displayed publicly until you approve the publisher. You can also allow or reject individual links. + description_html: These are links that are currently being shared a lot by accounts from which your server sees posts. It can help your users find out what's going on in the world. No links are displayed publicly until you approve the publisher. You can also allow or reject individual links. disallow: Disallow link disallow_provider: Disallow publisher - no_link_selected: No links were changed as none were selected + no_link_selected: No links were changed, as none were selected publishers: - no_publisher_selected: No publishers were changed as none were selected + no_publisher_selected: No publishers were changed, as none were selected shared_by_over_week: one: Shared by one person over the last week other: Shared by %{count} people over the last week @@ -1074,7 +1076,7 @@ en-GB: description_html: These are posts that your server knows about that are currently being shared and favourited a lot at the moment. It can help your new and returning users to find more people to follow. No posts are displayed publicly until you approve the author, and the author allows their account to be suggested to others. You can also allow or reject individual posts. disallow: Disallow post disallow_account: Disallow author - no_status_selected: No trending posts were changed as none were selected + no_status_selected: No trending posts were changed, as none were selected not_discoverable: Author has not opted-in to being discoverable shared_by: one: Shared or favourited one time @@ -1090,7 +1092,7 @@ en-GB: tag_uses_measure: total uses description_html: These are hashtags that are currently appearing in a lot of posts that your server sees. It can help your users find out what people are talking the most about at the moment. No hashtags are displayed publicly until you approve them. listable: Can be suggested - no_tag_selected: No tags were changed as none were selected + no_tag_selected: No tags were changed, as none were selected not_listable: Won't be suggested not_trendable: Won't appear under trends not_usable: Cannot be used @@ -1243,7 +1245,7 @@ en-GB: description: prefix_invited_by_user: "@%{name} invites you to join this server of Mastodon!" prefix_sign_up: Sign up on Mastodon today! - suffix: With an account, you will be able to follow people, post updates and exchange messages with users from any Mastodon server and more! + suffix: With an account, you will be able to follow people, post updates, and exchange messages with users from any Mastodon server and more! didnt_get_confirmation: Didn't receive a confirmation link? dont_have_your_security_key: Don't have your security key? forgot_password: Forgot your password? @@ -1313,7 +1315,7 @@ en-GB: title: Author attribution challenge: confirm: Continue - hint_html: "Tip: We won't ask you for your password again for the next hour." + hint_html: "Tip: we won't ask you for your password again for the next hour." invalid_password: Invalid password prompt: Confirm password to continue crypto: @@ -1414,7 +1416,7 @@ en-GB: archive_takeout: date: Date download: Download your archive - hint_html: You can request an archive of your posts and uploaded media. The exported data will be in the ActivityPub format, readable by any compliant software. You can request an archive every 7 days. + hint_html: You can request an archive of your posts and uploaded media. The exported data will be in the ActivityPub format, readable by any compliant software. You can request an archive every seven days. in_progress: Compiling your archive... request: Request your archive size: Size @@ -1429,7 +1431,7 @@ en-GB: add_new: Add new errors: limit: You have already featured the maximum number of hashtags - hint_html: "What are featured hashtags? They are displayed prominently on your public profile and allow people to browse your public posts specifically under those hashtags. They are a great tool for keeping track of creative works or long-term projects." + hint_html: "Feature your most important hashtags on your profile. A great tool for keeping track of your creative works and long-term projects, featured hashtags are displayed prominently on your profile and allow quick access to your own posts." filters: contexts: account: Profiles @@ -1568,8 +1570,8 @@ en-GB: muting: Importing muted accounts type: Import type type_groups: - constructive: Follows & Bookmarks - destructive: Blocks & mutes + constructive: Follows and bookmarks + destructive: Blocks and mutes types: blocking: Blocking list bookmarks: Bookmarks @@ -1642,7 +1644,7 @@ en-GB: images_and_video: Cannot attach a video to a post that already contains images not_found: Media %{ids} not found or already attached to another post not_ready: Cannot attach files that have not finished processing. Try again in a moment! - too_many: Cannot attach more than 4 files + too_many: Cannot attach more than four files migrations: acct: Moved to cancel: Cancel redirect @@ -1776,11 +1778,11 @@ en-GB: privacy: hint_html: "Customise how you want your profile and your posts to be found. A variety of features in Mastodon can help you reach a wider audience when enabled. Take a moment to review these settings to make sure they fit your use case." privacy: Privacy - privacy_hint_html: Control how much you want to disclose for the benefit of others. People discover interesting profiles and cool apps by browsing other people's follows and seeing which apps they post from, but you may prefer to keep it hidden. + privacy_hint_html: Control how much you want to disclose for the benefit of others. People discover interesting profiles and cool apps by browsing other people's follows and seeing from which apps they post, but you may prefer to keep it hidden. reach: Reach reach_hint_html: Control whether you want to be discovered and followed by new people. Do you want your posts to appear on the Explore screen? Do you want other people to see you in their follow recommendations? Do you want to accept all new followers automatically, or have granular control over each one? search: Search - search_hint_html: Control how you want to be found. Do you want people to find you by what you've publicly posted about? Do you want people outside Mastodon to find your profile when searching the web? Please mind that total exclusion from all search engines cannot be guaranteed for public information. + search_hint_html: Control how you want to be found. Do you want people to find you by what you've publicly posted about? Do you want people outside Mastodon to find your profile when searching the web? Please bear in mind that total exclusion from all search engines cannot be guaranteed for public information. title: Privacy and reach privacy_policy: title: Privacy Policy @@ -1991,9 +1993,9 @@ en-GB: '7889238': 3 months min_age_label: Age threshold min_favs: Keep posts favourited at least - min_favs_hint: Doesn't delete any of your posts that has received at least this number of favourites. Leave blank to delete posts regardless of their number of favourites + min_favs_hint: Doesn't delete any of your posts that have received at least this number of favourites. Leave blank to delete posts regardless of their number of favourites min_reblogs: Keep posts boosted at least - min_reblogs_hint: Doesn't delete any of your posts that has been boosted at least this number of times. Leave blank to delete posts regardless of their number of boosts + min_reblogs_hint: Doesn't delete any of your posts that have been boosted at least this number of times. Leave blank to delete posts regardless of their number of boosts stream_entries: sensitive_content: Sensitive content strikes: @@ -2075,8 +2077,8 @@ en-GB: terms_of_service_changed: agreement: By continuing to use %{domain}, you are agreeing to these terms. If you disagree with the updated terms, you may terminate your agreement with %{domain} at any time by deleting your account. changelog: 'At a glance, here is what this update means for you:' - description: 'You are receiving this e-mail because we''re making some changes to our terms of service at %{domain}. These updates will take effect on %{date}. We encourage you to review the updated terms in full here:' - description_html: You are receiving this e-mail because we're making some changes to our terms of service at %{domain}. These updates will take effect on %{date}. We encourage you to review the updated terms in full here. + description: 'You are receiving this email because we''re making some changes to our terms of service at %{domain}. These updates will take effect on %{date}. We encourage you to review the updated terms in full here:' + description_html: You are receiving this email because we're making some changes to our terms of service at %{domain}. These updates will take effect on %{date}. We encourage you to review the updated terms in full here. sign_off: The %{domain} team subject: Updates to our terms of service subtitle: The terms of service of %{domain} are changing @@ -2139,9 +2141,9 @@ en-GB: follows_title: Who to follow follows_view_more: View more people to follow hashtags_recent_count: - one: "%{people} person in the past 2 days" - other: "%{people} people in the past 2 days" - hashtags_subtitle: Explore what’s trending since past 2 days + one: "%{people} person in the past two days" + other: "%{people} people in the past two days" + hashtags_subtitle: Explore what’s trending since the past two days hashtags_title: Trending hashtags hashtags_view_more: View more trending hashtags post_action: Compose @@ -2161,9 +2163,9 @@ en-GB: seamless_external_login: You are logged in via an external service, so password and email settings are not available. signed_in_as: 'Logged in as:' verification: - extra_instructions_html: Tip: The link on your website can be invisible. The important part is rel="me" which prevents impersonation on websites with user-generated content. You can even use a link tag in the header of the page instead of a, but the HTML must be accessible without executing JavaScript. + extra_instructions_html: Tip: the link on your website can be invisible. The important part is rel="me" which prevents impersonation on websites with user-generated content. You can even use a link tag in the header of the page instead of a, but the HTML must be accessible without executing JavaScript. here_is_how: Here's how - hint_html: "Verifying your identity on Mastodon is for everyone. Based on open web standards, now and forever free. All you need is a personal website that people recognize you by. When you link to this website from your profile, we will check that the website links back to your profile and show a visual indicator on it." + hint_html: "Verifying your identity on Mastodon is for everyone. Based on open web standards, now and forever free. All you need is a personal website that people recognise you by. When you link to this website from your profile, we will check that the website links back to your profile and show a visual indicator on it." instructions_html: Copy and paste the code below into the HTML of your website. Then add the address of your website into one of the extra fields on your profile from the "Edit profile" tab and save changes. verification: Verification verified_links: Your verified links @@ -2186,4 +2188,5 @@ en-GB: otp_required: To use security keys please enable two-factor authentication first. registered_on: Registered on %{date} wrapstodon: + description: See how %{name} used Mastodon this year! title: Wrapstodon %{year} for %{name} diff --git a/config/locales/es-AR.yml b/config/locales/es-AR.yml index 097329cc5b8c4b..a6e118e00874ba 100644 --- a/config/locales/es-AR.yml +++ b/config/locales/es-AR.yml @@ -7,6 +7,8 @@ es-AR: hosted_on: Mastodon alojado en %{domain} title: Información accounts: + errors: + cannot_be_added_to_collections: Esta cuenta no se puede añadir a las colecciones. followers: one: Seguidor other: Seguidores @@ -2186,4 +2188,5 @@ es-AR: otp_required: Para usar llaves de seguridad, por favor, primero habilitá la autenticación de dos factores. registered_on: Registrado el %{date} wrapstodon: + description: "¡Enterate cómo %{name} usó Mastodon este año!" title: MastodonAnual %{year} para %{name} diff --git a/config/locales/es-MX.yml b/config/locales/es-MX.yml index 0ca9c86c048d3a..56b539d6b43dad 100644 --- a/config/locales/es-MX.yml +++ b/config/locales/es-MX.yml @@ -7,6 +7,8 @@ es-MX: hosted_on: Mastodon alojado en %{domain} title: Acerca de accounts: + errors: + cannot_be_added_to_collections: Esta cuenta no se puede añadir a las colecciones. followers: one: Seguidor other: Seguidores @@ -40,14 +42,14 @@ es-MX: avatar: Foto de perfil by_domain: Dominio change_email: - changed_msg: Correo cambiado exitosamente! + changed_msg: "¡Correo electrónico cambiado correctamente!" current_email: Correo electrónico actual label: Cambiar el correo electrónico new_email: Nuevo correo electrónico submit: Cambiar el correo electrónico title: Cambiar el correo electrónico de %{username} change_role: - changed_msg: Rol cambiado exitosamente! + changed_msg: "¡Rol cambiado correctamente!" edit_roles: Administrar roles de usuario label: Cambiar de rol no_role: Sin rol @@ -105,7 +107,7 @@ es-MX: no_account_selected: Ninguna cuenta se cambió como ninguna fue seleccionada no_limits_imposed: Sin límites impuestos no_role_assigned: Sin rol asignado - not_subscribed: No se está suscrito + not_subscribed: No suscrito pending: Revisión pendiente perform_full_suspension: Suspender previous_strikes: Amonestaciones previas @@ -139,10 +141,10 @@ es-MX: search_same_ip: Otros usuarios con la misma IP security: Seguridad security_measures: - only_password: Sólo contraseña + only_password: Solo contraseña password_and_2fa: Contraseña y 2FA sensitive: Sensible - sensitized: marcado como sensible + sensitized: Marcado como sensible shared_inbox_url: URL de bandeja compartida show: created_reports: Reportes hechos por esta cuenta @@ -161,10 +163,10 @@ es-MX: unblocked_email_msg: Desbloqueo exitoso de la dirección de correo de %{username} unconfirmed_email: Correo electrónico sin confirmar undo_sensitized: Desmarcar como sensible - undo_silenced: Des-silenciar - undo_suspension: Des-suspender + undo_silenced: Deshacer límite + undo_suspension: Deshacer suspensión unsilenced_msg: Se quitó con éxito el límite de la cuenta %{username} - unsubscribe: Desuscribir + unsubscribe: Cancelar suscripción unsuspended_msg: Se quitó con éxito la suspensión de la cuenta de %{username} username: Nombre de usuario view_domain: Ver resumen del dominio @@ -312,7 +314,7 @@ es-MX: empty: No se encontraron registros. filter_by_action: Filtrar por acción filter_by_user: Filtrar por usuario - title: Log de auditoría + title: Registro de auditoría unavailable_instance: "(nombre de dominio no disponible)" announcements: back: Volver a la sección de anuncios @@ -359,7 +361,7 @@ es-MX: listed: Listados new: title: Añadir nuevo emoji personalizado - no_emoji_selected: No se cambió ningún emoji ya que no se seleccionó ninguno + no_emoji_selected: No se modificó ningún emoji, ya que no se seleccionó ninguno not_permitted: No tienes permiso para realizar esta acción overwrite: Sobrescribir shortcode: Código de atajo @@ -373,8 +375,8 @@ es-MX: upload: Subir dashboard: active_users: usuarios activos - interactions: interaccciones - media_storage: Almacenamiento + interactions: interacciones + media_storage: Almacenamiento multimedia new_users: nuevos usuarios opened_reports: informes abiertos pending_appeals_html: @@ -413,7 +415,7 @@ es-MX: confirm_suspension: cancel: Cancelar confirm: Suspender - permanent_action: Deshacer la suspensión no recuperará ningún data o relaciones. + permanent_action: Anular la suspensión no restaurará ningún dato ni relación. preamble_html: Estás a punto de suspender a %{domain} y sus subdominios. remove_all_data: Esto eliminará todo el contenido, multimedia y datos de perfil de las cuentas de este dominio de tu servidor. stop_communication: Tu servidor dejará de comunicarse con estos servidores. @@ -436,7 +438,7 @@ es-MX: silence: Limitar suspend: Suspender title: Nuevo bloque de dominio - no_domain_block_selected: No se cambió ningún bloqueo de dominio ya que ninguno fue seleccionado + no_domain_block_selected: No se modificó ningún bloqueo de dominio, ya que no se seleccionó ninguno not_permitted: No tienes permiso para realizar esta acción obfuscate: Ocultar nombre de dominio obfuscate_hint: Oculta parcialmente el nombre de dominio en la lista si mostrar la lista de limitaciones de dominio está habilitado @@ -624,12 +626,12 @@ es-MX: '94670856': 3 años new: title: Crear nueva regla IP - no_ip_block_selected: No se han cambiado reglas IP ya que no se ha seleccionado ninguna + no_ip_block_selected: No se modificó ninguna regla de IP, ya que no se seleccionó ninguna title: Reglas IP relationships: title: Relaciones de %{acct} relays: - add_new: Añadir un nuevo relés + add_new: Añadir nuevo relé delete: Borrar description_html: Un relés de federación es un servidor intermedio que intercambia grandes volúmenes de publicaciones públicas entre servidores que se suscriben y publican en él. Puede ayudar a servidores pequeños y medianos a descubrir contenido del fediverso, que de otra manera requeriría que los usuarios locales siguiesen manualmente a personas de servidores remotos. disable: Deshabilitar @@ -659,7 +661,7 @@ es-MX: mark_as_sensitive_description_html: Los archivos multimedia en las publicaciones reportadas se marcarán como sensibles y se aplicará una amonestación para ayudarte a escalar las futuras infracciones de la misma cuenta. other_description_html: Ver más opciones para controlar el comportamiento de la cuenta y personalizar la comunicación de la cuenta reportada. resolve_description_html: No se tomarán medidas contra la cuenta denunciada, no se registrará la amonestación, y se cerrará el informe. - silence_description_html: La cuenta será visible sólo para aquellos que ya la sigan o la busquen manualmente, limitando severamente su visibilidad. Siempre puede ser revertido. Cierra todos los reportes contra esta cuenta. + silence_description_html: La cuenta será visible solo para aquellos que ya la sigan o la busquen manualmente, limitando severamente su visibilidad. Siempre puede ser revertido. Cierra todos los reportes contra esta cuenta. suspend_description_html: La cuenta y todos sus contenidos serán inaccesibles y eventualmente eliminados, e interactuar con ella será imposible. Reversible durante 30 días. Cierra todos los reportes contra esta cuenta. actions_description_html: Decide qué medidas tomar para resolver esta denuncia. Si tomas una acción punitiva contra la cuenta denunciada, se le enviará a dicha cuenta una notificación por correo electrónico, excepto cuando se seleccione la categoría Spam. actions_description_remote_html: Decide qué medidas tomar para resolver este reporte. Esto solo afectará a la forma en que tu servidor se comunica con esta cuenta remota y gestiona su contenido. @@ -2186,4 +2188,5 @@ es-MX: otp_required: Para usar claves de seguridad, por favor habilite primero la autenticación de doble factor. registered_on: Registrado el %{date} wrapstodon: + description: "¡Ve cómo %{name} usó Mastodon este año!" title: Wrapstodon %{year} para %{name} diff --git a/config/locales/es.yml b/config/locales/es.yml index 1dd2760b403567..ccee7cab646819 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -7,6 +7,8 @@ es: hosted_on: Mastodon alojado en %{domain} title: Acerca de accounts: + errors: + cannot_be_added_to_collections: Esta cuenta no se puede añadir a las colecciones. followers: one: Seguidor other: Seguidores @@ -2186,4 +2188,5 @@ es: otp_required: Para usar claves de seguridad, por favor habilite primero la autenticación de doble factor. registered_on: Registrado el %{date} wrapstodon: + description: "¡Mira cómo %{name} ha usado Mastodon este año!" title: Wrapstodon %{year} para %{name} diff --git a/config/locales/fi.yml b/config/locales/fi.yml index 8375136962f248..c2cf09a6354dbf 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -7,6 +7,8 @@ fi: hosted_on: Mastodon palvelimella %{domain} title: Tietoja accounts: + errors: + cannot_be_added_to_collections: Tätä tiliä ei voi lisätä kokoelmiin. followers: one: seuraaja other: seuraajaa @@ -2185,3 +2187,6 @@ fi: not_supported: Tämä selain ei tue suojausavaimia otp_required: Jos haluat käyttää suojausavaimia, ota ensin kaksivaiheinen todennus käyttöön. registered_on: Rekisteröity %{date} + wrapstodon: + description: Katso, kuinka %{name} käytti Mastodonia tänä vuonna! + title: Käyttäjän %{name} Wrapstodon vuodelle %{year} diff --git a/config/locales/fo.yml b/config/locales/fo.yml index a94f0d1feda343..4216367aef5efa 100644 --- a/config/locales/fo.yml +++ b/config/locales/fo.yml @@ -7,6 +7,8 @@ fo: hosted_on: Mastodon hýst á %{domain} title: Um accounts: + errors: + cannot_be_added_to_collections: Hendan kontan kann ikki leggjast afturat søvnum. followers: one: Fylgjari other: Fylgjarar @@ -2186,4 +2188,5 @@ fo: otp_required: Fyri at brúka trygdarlyklar er neyðugt at gera váttan í tveimum stigum virkna fyrst. registered_on: Skrásett %{date} wrapstodon: + description: Sí hvussu %{name} brúkti Mastodon í ár! title: Wrapstodon %{year} fyri %{name} diff --git a/config/locales/fr-CA.yml b/config/locales/fr-CA.yml index 78e0d4263a42c3..555e8a5aaa2e81 100644 --- a/config/locales/fr-CA.yml +++ b/config/locales/fr-CA.yml @@ -7,6 +7,8 @@ fr-CA: hosted_on: Serveur Mastodon hébergé sur %{domain} title: À propos accounts: + errors: + cannot_be_added_to_collections: Ce compte ne peut pas être ajouté aux collections. followers: one: Abonné·e other: Abonné·e·s @@ -2189,4 +2191,5 @@ fr-CA: otp_required: Pour utiliser les clés de sécurité, veuillez d'abord activer l'authentification à deux facteurs. registered_on: Inscrit le %{date} wrapstodon: + description: Voir comment %{name} a utilisé Mastodon cette année ! title: Wrapstodon %{year} pour %{name} diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 0767c223bb4262..c54aa068052fa7 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -7,6 +7,8 @@ fr: hosted_on: Serveur Mastodon hébergé sur %{domain} title: À propos accounts: + errors: + cannot_be_added_to_collections: Ce compte ne peut pas être ajouté aux collections. followers: one: Abonné·e other: Abonné·e·s @@ -2189,4 +2191,5 @@ fr: otp_required: Pour utiliser les clés de sécurité, veuillez d'abord activer l'authentification à deux facteurs. registered_on: Inscrit le %{date} wrapstodon: + description: Voir comment %{name} a utilisé Mastodon cette année ! title: Wrapstodon %{year} pour %{name} diff --git a/config/locales/ga.yml b/config/locales/ga.yml index 9c5ea95f847753..72d9262cca6433 100644 --- a/config/locales/ga.yml +++ b/config/locales/ga.yml @@ -7,6 +7,8 @@ ga: hosted_on: Mastodon arna óstáil ar %{domain} title: Maidir le accounts: + errors: + cannot_be_added_to_collections: Ní féidir an cuntas seo a chur le bailiúcháin. followers: few: Leantóirí many: Leantóirí @@ -2320,4 +2322,5 @@ ga: otp_required: Chun eochracha slándála a úsáid cumasaigh fíordheimhniú dhá fhachtóir ar dtús. registered_on: Cláraithe ar %{date} wrapstodon: + description: Féach conas a d'úsáid %{name} Mastodon i mbliana! title: Wrapstodon %{year} do %{name} diff --git a/config/locales/gl.yml b/config/locales/gl.yml index b9c4ba5427d33e..615f15f0daece7 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -7,6 +7,8 @@ gl: hosted_on: Mastodon aloxado en %{domain} title: Sobre accounts: + errors: + cannot_be_added_to_collections: Non se pode engadir esta conta ás coleccións. followers: one: Seguidora other: Seguidoras @@ -2186,4 +2188,5 @@ gl: otp_required: Para usar chaves de seguridade tes que activar primeiro o segundo factor. registered_on: Rexistrado o %{date} wrapstodon: + description: Mira como usou %{name} Mastodon este ano! title: Wrapstodon %{year} de %{name} diff --git a/config/locales/he.yml b/config/locales/he.yml index 6550f17cf5a16e..98baeb601c3cee 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -7,6 +7,8 @@ he: hosted_on: מסטודון שיושב בכתובת %{domain} title: אודות accounts: + errors: + cannot_be_added_to_collections: לא ניתן להוסיף חשבון זה לאוספים. followers: many: עוקבים one: עוקב @@ -2274,4 +2276,5 @@ he: otp_required: על מנת להשתמש במפתחות אבטחה אנא אפשר.י אימות דו-שלבי קודם. registered_on: נרשם ב %{date} wrapstodon: + description: ראו איך %{name} השתמשו במסטודון השנה! title: סיכומודון %{year} עבור %{name} diff --git a/config/locales/hu.yml b/config/locales/hu.yml index abaa78e1e43222..d89078d8fdafaf 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -7,6 +7,8 @@ hu: hosted_on: "%{domain} Mastodon-kiszolgáló" title: Névjegy accounts: + errors: + cannot_be_added_to_collections: Ez a fiók nem adható hozzá gyűjteményekhez. followers: one: Követő other: Követő @@ -2185,3 +2187,6 @@ hu: not_supported: Ez a böngésző nem támogatja a biztonsági kulcsokat otp_required: A biztonsági kulcsok használatához először engedélyezd a kétlépcsős hitelesítést. registered_on: 'Regisztráció ekkor: %{date}' + wrapstodon: + description: Nézd meg, hogy %{name} hogyan használta a Mastodont az éven! + title: Wrapstodon %{year} – %{name} diff --git a/config/locales/is.yml b/config/locales/is.yml index f964c1ad2ee3ab..72c8607e9d7851 100644 --- a/config/locales/is.yml +++ b/config/locales/is.yml @@ -7,6 +7,8 @@ is: hosted_on: Mastodon hýst á %{domain} title: Um hugbúnaðinn accounts: + errors: + cannot_be_added_to_collections: Þessum aðgangi er ekki hægt að bæta í söfn. followers: one: fylgjandi other: fylgjendur @@ -2190,4 +2192,5 @@ is: otp_required: Til að nota öryggislykla skaltu fyrst virkja tveggja-þátta auðkenningu. registered_on: Skráði sig %{date} wrapstodon: + description: Sjáðu hvernig %{name} notaði Mastodon á árinu! title: Wrapstodon %{year} fyrir %{name} diff --git a/config/locales/it.yml b/config/locales/it.yml index 1be6d50ad3da4a..77072e7a374840 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -7,6 +7,8 @@ it: hosted_on: Mastodon ospitato su %{domain} title: Info accounts: + errors: + cannot_be_added_to_collections: Questo account non può essere aggiunto alle collezioni. followers: one: Seguace other: Seguaci @@ -2186,4 +2188,5 @@ it: otp_required: Per utilizzare le chiavi di sicurezza, prima abilita l'autenticazione a due fattori. registered_on: Registrato il %{date} wrapstodon: + description: Guarda come %{name} ha utilizzato Mastodon quest'anno! title: Wrapstodon %{year} per %{name} diff --git a/config/locales/ko.yml b/config/locales/ko.yml index 4f2e8a538502dd..36dabb67cf5b09 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -7,6 +7,8 @@ ko: hosted_on: "%{domain}에서 호스팅 되는 마스토돈" title: 정보 accounts: + errors: + cannot_be_added_to_collections: 이 계정은 컬렉션에 추가할 수 없습니다. followers: other: 팔로워 following: 팔로잉 @@ -2136,3 +2138,5 @@ ko: not_supported: 이 브라우저는 보안 키를 지원하지 않습니다 otp_required: 보안 키를 사용하기 위해서는 2단계 인증을 먼저 활성화 해 주세요 registered_on: "%{date}에 등록됨" + wrapstodon: + title: "%{name} 님의 %{year} 랩스토돈" diff --git a/config/locales/nan.yml b/config/locales/nan.yml index 34c702a714ab1e..e51b8f506b4d63 100644 --- a/config/locales/nan.yml +++ b/config/locales/nan.yml @@ -7,6 +7,8 @@ nan: hosted_on: 佇 %{domain} 運作 ê Mastodon站 title: 關係本站 accounts: + errors: + cannot_be_added_to_collections: Tsit ê口座袂當加入kàu集合。 followers: other: 跟tuè ê following: Leh跟tuè @@ -1488,6 +1490,34 @@ nan: overwrite_preambles: blocking_html: other: Lí teh-beh用 %{filename} ê %{count} ê口座替換lí ê封鎖列單。 + bookmarks_html: + other: Lí teh-beh用 %{filename} ê %{count} ê PO文替換lí ê冊籤。 + domain_blocking_html: + other: Lí teh-beh用 %{filename} ê %{count} ê域名替換lí ê域名封鎖列單。 + following_html: + other: Lí當beh跟tuè%{filename} 內底ê %{count} ê口座,而且停止跟tuè別lâng。 + lists_html: + other: Lí當beh用 %{filename} ê內容取代lí ê列單%{count} ê口座會加添kàu新列單。 + muting_html: + other: Lí teh-beh用 %{filename} ê %{count} ê口座替換lí ê消音口座ê列單。 + preambles: + blocking_html: + other: Lí teh-beh kā %{filename}內底ê%{count} ê口座封鎖。 + bookmarks_html: + other: Lí當beh對 %{filename} 加添 %{count} 篇PO文kàu lí ê 冊籤。 + domain_blocking_html: + other: Lí teh-beh kā %{filename}內底ê%{count} ê域名封鎖。 + following_html: + other: Lí teh-beh kā %{filename}內底ê%{count} ê口座跟tuè。 + lists_html: + other: Lí當beh對 %{filename}%{count} ê口座 kàu lí ê列單。若無列單通加添,新ê列單ē建立。 + muting_html: + other: Lí teh-beh kā %{filename}內底ê%{count} ê口座消音。 + preface: Lí ē當輸入lí對別ê服侍器輸出ê資料,比如lí所跟tuè ê á是封鎖ê ê列單。 + recent_imports: 最近輸入ê + login_activities: + authentication_methods: + webauthn: 安全檢查 scheduled_statuses: too_soon: Tio̍h用未來ê日期。 statuses: diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 72c8ece6f2bbb8..bacad16d67abdf 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -7,6 +7,8 @@ nl: hosted_on: Mastodon op %{domain} title: Over accounts: + errors: + cannot_be_added_to_collections: Dit account kan niet aan collecties worden toegevoegd. followers: one: Volger other: Volgers @@ -2186,4 +2188,5 @@ nl: otp_required: Om beveiligingssleutels te kunnen gebruiken, moet je eerst tweestapsverificatie inschakelen. registered_on: Geregistreerd op %{date} wrapstodon: + description: Bekijk hoe %{name} dit jaar Mastodon heeft gebruikt! title: Wrapstodon %{year} voor %{name} diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index 657ab9f6ad6da2..7e3344efff4a86 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -7,6 +7,8 @@ pt-BR: hosted_on: Mastodon hospedado em %{domain} title: Sobre accounts: + errors: + cannot_be_added_to_collections: Esta conta não pode ser adicionada a coleções. followers: one: Seguidor other: Seguidores @@ -2187,4 +2189,5 @@ pt-BR: otp_required: Para usar chaves de segurança, ative a autenticação de dois fatores. registered_on: Registrado em %{date} wrapstodon: + description: Veja como %{name} usou o Mastodon este ano! title: Wrapstodon de %{year} para %{name} diff --git a/config/locales/pt-PT.yml b/config/locales/pt-PT.yml index 5aca8c4ec4cfee..bb1919e69c3b1d 100644 --- a/config/locales/pt-PT.yml +++ b/config/locales/pt-PT.yml @@ -7,6 +7,8 @@ pt-PT: hosted_on: Mastodon alojado em %{domain} title: Sobre accounts: + errors: + cannot_be_added_to_collections: Esta conta não pode ser adicionada às coleções. followers: one: Seguidor other: Seguidores @@ -1715,7 +1717,7 @@ pt-PT: subject: "%{name} citou a sua publicação" title: Nova citação quoted_update: - subject: "%{name} editou uma publicação que citaste" + subject: "%{name} editou uma publicação que citou" reblog: body: 'A tua publicação foi partilhada por %{name}:' subject: "%{name} partilhou a sua publicação" @@ -2185,3 +2187,6 @@ pt-PT: not_supported: Este navegador não funciona com chaves de segurança otp_required: Para utilizares chaves de segurança, ativa primeiro a autenticação de dois fatores. registered_on: Registado em %{date} + wrapstodon: + description: Veja como %{name} utilizou o Mastodon este ano! + title: Wrapstodon %{year} de %{name} diff --git a/config/locales/ru.yml b/config/locales/ru.yml index 4e61fd52b392f8..7441211dd11672 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -521,10 +521,12 @@ ru: registrations: confirm: Подтвердить reject: Отклонить + title: Подтвердить регистрацию FASP save: Сохранить select_capabilities: Выберите возможности sign_in: status: Пост + title: Fediverse Auxiliary Service Providers title: FASP follow_recommendations: description_html: "Рекомендации профилей помогают новым пользователям быстрее найти что-нибудь интересное. Если пользователь мало взаимодействовал с другими и составить персонализированные рекомендации не получается, будут предложены указанные здесь профили. Эти рекомендации обновляются ежедневно из совокупности учётных записей с наибольшим количеством недавних взаимодействий и наибольшим количеством подписчиков с этого сервера для данного языка." diff --git a/config/locales/simple_form.el.yml b/config/locales/simple_form.el.yml index f033d90dcfaae1..5d1885a1553bbf 100644 --- a/config/locales/simple_form.el.yml +++ b/config/locales/simple_form.el.yml @@ -49,7 +49,7 @@ el: email: Θα σου σταλεί email επιβεβαίωσης header: WEBP, PNG, GIF ή JPG. Το πολύ %{size}. Θα υποβαθμιστεί σε %{dimensions}px inbox_url: Αντέγραψε το URL της αρχικής σελίδας του ανταποκριτή που θέλεις να χρησιμοποιήσεις - irreversible: Οι φιλτραρισμένες αναρτήσεις θα εξαφανιστούν αμετάκλητα, ακόμα και αν το φίλτρο αργότερα αφαιρεθεί + irreversible: Οι φιλτραρισμένες αναρτήσεις θα εξαφανιστούν αμετάκλητα, ακόμη και αν το φίλτρο αργότερα αφαιρεθεί locale: Η γλώσσα χρήσης, των email και των ειδοποιήσεων push password: Χρησιμοποίησε τουλάχιστον 8 χαρακτήρες phrase: Θα ταιριάζει ανεξαρτήτως πεζών/κεφαλαίων ή προειδοποίησης περιεχομένου μιας ανάρτησης @@ -95,7 +95,7 @@ el: favicon: WEBP, PNG, GIF ή JPG. Παρακάμπτει το προεπιλεγμένο favicon του Mastodon με ένα προσαρμοσμένο εικονίδιο. landing_page: Επιλέγει ποια σελίδα βλέπουν οι νέοι επισκέπτες όταν φτάνουν για πρώτη φορά στο διακομιστή σας. Αν επιλέξετε "Τάσεις", τότε οι τάσεις πρέπει να είναι ενεργοποιημένες στις Ρυθμίσεις Ανακάλυψης. Αν επιλέξετε "Τοπική ροή", τότε το "Πρόσβαση σε ζωντανές ροές με τοπικές αναρτήσεις" πρέπει να οριστεί σε "Όλοι" στις Ρυθμίσεις Ανακάλυψης. mascot: Παρακάμπτει την εικονογραφία στην προηγμένη διεπαφή ιστού. - media_cache_retention_period: Τα αρχεία πολυμέσων από αναρτήσεις που γίνονται από απομακρυσμένους χρήστες αποθηκεύονται προσωρινά στο διακομιστή σου. Όταν οριστεί μια θετική τιμή, τα μέσα θα διαγραφούν μετά τον καθορισμένο αριθμό ημερών. Αν τα δεδομένα πολυμέσων ζητηθούν μετά τη διαγραφή τους, θα γίνει ε, αν το πηγαίο περιεχόμενο είναι ακόμα διαθέσιμο. Λόγω περιορισμών σχετικά με το πόσο συχνά οι κάρτες προεπισκόπησης συνδέσμων συνδέονται σε ιστοσελίδες τρίτων, συνιστάται να ορίσεις αυτή την τιμή σε τουλάχιστον 14 ημέρες ή οι κάρτες προεπισκόπησης συνδέσμων δεν θα ενημερώνονται κατ' απάιτηση πριν από εκείνη την ώρα. + media_cache_retention_period: Τα αρχεία πολυμέσων από αναρτήσεις που γίνονται από απομακρυσμένους χρήστες αποθηκεύονται προσωρινά στο διακομιστή σου. Όταν οριστεί μια θετική τιμή, τα μέσα θα διαγραφούν μετά τον καθορισμένο αριθμό ημερών. Αν τα δεδομένα πολυμέσων ζητηθούν μετά τη διαγραφή τους, θα γίνει λήψη τους ξανά, αν το πηγαίο περιεχόμενο είναι ακόμη διαθέσιμο. Λόγω περιορισμών σχετικά με το πόσο συχνά οι κάρτες προεπισκόπησης συνδέσμων συνδέονται σε ιστοσελίδες τρίτων, συνιστάται να ορίσεις αυτή την τιμή σε τουλάχιστον 14 ημέρες ή οι κάρτες προεπισκόπησης συνδέσμων δεν θα ενημερώνονται κατ' απάιτηση πριν από εκείνη την ώρα. min_age: Οι χρήστες θα κληθούν να επιβεβαιώσουν την ημερομηνία γέννησής τους κατά την εγγραφή peers_api_enabled: Μια λίστα με ονόματα τομέα που συνάντησε αυτός ο διακομιστής στο fediverse. Δεν περιλαμβάνονται δεδομένα εδώ για το αν συναλλάσσετε με ένα συγκεκριμένο διακομιστή, μόνο ότι ο διακομιστής σας το ξέρει. Χρησιμοποιείται από υπηρεσίες που συλλέγουν στατιστικά στοιχεία για την συναλλαγή με γενική έννοια. profile_directory: Ο κατάλογος προφίλ παραθέτει όλους τους χρήστες που έχουν επιλέξει να είναι ανακαλύψιμοι. @@ -109,7 +109,7 @@ el: status_page_url: Το URL μιας σελίδας όπου κάποιος μπορεί να δει την κατάσταση αυτού του διακομιστή κατά τη διάρκεια μιας διακοπής λειτουργίας theme: Θέμα που βλέπουν αποσυνδεδεμένοι επισκέπτες ή νέοι χρήστες. thumbnail: Μια εικόνα περίπου 2:1 που εμφανίζεται παράλληλα με τις πληροφορίες του διακομιστή σου. - trendable_by_default: Παράλειψη χειροκίνητης αξιολόγησης του περιεχομένου σε τάση. Μεμονωμένα στοιχεία μπορούν ακόμα να αφαιρεθούν από τις τάσεις μετέπειτα. + trendable_by_default: Παράλειψη χειροκίνητης αξιολόγησης του περιεχομένου σε τάση. Μεμονωμένα στοιχεία μπορούν ακόμη να αφαιρεθούν από τις τάσεις μετέπειτα. trends: Τάσεις δείχνουν ποιες δημοσιεύσεις, ετικέτες και ειδήσεις προκαλούν έλξη στο διακομιστή σας. form_challenge: current_password: Μπαίνεις σε ασφαλή περιοχή diff --git a/config/locales/simple_form.en-GB.yml b/config/locales/simple_form.en-GB.yml index a749302353821d..39889086b1cc1f 100644 --- a/config/locales/simple_form.en-GB.yml +++ b/config/locales/simple_form.en-GB.yml @@ -10,13 +10,13 @@ en-GB: indexable: Your public posts may appear in search results on Mastodon. People who have interacted with your posts may be able to search them regardless. note: 'You can @mention other people or #hashtags.' show_collections: People will be able to browse through your follows and followers. People that you follow will see that you follow them regardless. - unlocked: People will be able to follow you without requesting approval. Uncheck if you want to review follow requests and choose whether to accept or reject new followers. + unlocked: People will be able to follow you without requesting approval. Untick if you want to review follow requests and choose whether to accept or reject new followers. account_alias: acct: Specify the username@domain of the account you want to move from account_migration: acct: Specify the username@domain of the account you want to move to account_warning_preset: - text: You can use post syntax, such as URLs, hashtags and mentions + text: You can use post syntax, such as URLs, hashtags, and mentions title: Optional. Not visible to the recipient admin_account_action: include_statuses: The user will see which posts have caused the moderation action or warning @@ -29,9 +29,9 @@ en-GB: sensitive: Force all this user's media attachments to be flagged as sensitive. silence: Prevent the user from being able to post with public visibility, hide their posts and notifications from people not following them. Closes all reports against this account. suspend: Prevent any interaction from or to this account and delete its contents. Revertible within 30 days. Closes all reports against this account. - warning_preset_id: Optional. You can still add custom text to end of the preset + warning_preset_id: Optional. You can still add custom text to the end of the preset announcement: - all_day: When checked, only the dates of the time range will be displayed + all_day: When ticked, only the dates of the time range will be displayed ends_at: Optional. Announcement will be automatically unpublished at this time scheduled_at: Leave blank to publish the announcement immediately starts_at: Optional. In case your announcement is bound to a specific time range @@ -43,20 +43,20 @@ en-GB: avatar: WEBP, PNG, GIF or JPG. At most %{size}. Will be downscaled to %{dimensions}px bot: Signal to others that the account mainly performs automated actions and might not be monitored context: One or multiple contexts where the filter should apply - current_password: For security purposes please enter the password of the current account + current_password: For security purposes, please enter the password of the current account current_username: To confirm, please enter the username of the current account digest: Only sent after a long period of inactivity and only if you have received any personal messages in your absence - email: You will be sent a confirmation e-mail + email: You will be sent a confirmation email header: WEBP, PNG, GIF or JPG. At most %{size}. Will be downscaled to %{dimensions}px - inbox_url: Copy the URL from the frontpage of the relay you want to use - irreversible: Filtered posts will disappear irreversibly, even if filter is later removed - locale: The language of the user interface, e-mails and push notifications - password: Use at least 8 characters + inbox_url: Copy the URL from the front page of the relay you want to use + irreversible: Filtered posts will disappear irreversibly, even if the filter is later removed + locale: The language of the user interface, emails, and push notifications + password: Use at least eight characters phrase: Will be matched regardless of casing in text or content warning of a post scopes: Which APIs the application will be allowed to access. If you select a top-level scope, you don't need to select individual ones. setting_advanced_layout: Display Mastodon as a multi-column layout, allowing you to view the timeline, notifications, and a third column of your choosing. Not recommended for smaller screens. setting_aggregate_reblogs: Do not show new boosts for posts that have been recently boosted (only affects newly-received boosts) - setting_always_send_emails: Normally e-mail notifications won't be sent when you are actively using Mastodon + setting_always_send_emails: Normally email notifications won't be sent when you are actively using Mastodon setting_boost_modal: When enabled, boosting will first open a confirmation dialogue in which you can change the visibility of your boost. setting_default_quote_policy_private: Followers-only posts authored on Mastodon can't be quoted by others. setting_default_quote_policy_unlisted: When people quote you, their post will also be hidden from trending timelines. @@ -67,14 +67,14 @@ en-GB: setting_emoji_style: How to display emojis. "Auto" will try using native emoji, but falls back to Twemoji for legacy browsers. setting_quick_boosting_html: When enabled, clicking on the %{boost_icon} Boost icon will immediately boost instead of opening the boost/quote dropdown menu. Relocates the quoting action to the %{options_icon} (Options) menu. setting_system_scrollbars_ui: Applies only to desktop browsers based on Safari and Chrome - setting_use_blurhash: Gradients are based on the colors of the hidden visuals but obfuscate any details + setting_use_blurhash: Gradients are based on the colours of the hidden visuals but obfuscate any details setting_use_pending_items: Hide timeline updates behind a click instead of automatically scrolling the feed username: You can use letters, numbers, and underscores whole_word: When the keyword or phrase is alphanumeric only, it will only be applied if it matches the whole word domain_allow: domain: This domain will be able to fetch data from this server and incoming data from it will be processed and stored email_domain_block: - domain: This can be the domain name that shows up in the e-mail address or the MX record it uses. They will be checked upon sign-up. + domain: This can be the domain name that shows up in the email address or the MX record it uses. They will be checked upon sign-up. with_dns_records: An attempt to resolve the given domain's DNS records will be made and the results will also be blocked featured_tag: name: 'Here are some of the hashtags you used the most recently:' @@ -90,14 +90,14 @@ en-GB: backups_retention_period: Users have the ability to generate archives of their posts to download later. When set to a positive value, these archives will be automatically deleted from your storage after the specified number of days. bootstrap_timeline_accounts: These accounts will be pinned to the top of new users' follow recommendations. Provide a comma-separated list of accounts. closed_registrations_message: Displayed when sign-ups are closed - content_cache_retention_period: All posts from other servers (including boosts and replies) will be deleted after the specified number of days, without regard to any local user interaction with those posts. This includes posts where a local user has marked it as bookmarks or favorites. Private mentions between users from different instances will also be lost and impossible to restore. Use of this setting is intended for special purpose instances and breaks many user expectations when implemented for general purpose use. + content_cache_retention_period: All posts from other servers (including boosts and replies) will be deleted after the specified number of days, without regard to any local user interaction with those posts. This includes posts where a local user has marked it as bookmarks or favourites. Private mentions between users from different instances will also be lost and impossible to restore. Use of this setting is intended for special purpose instances and breaks many user expectations when implemented for general purpose use. custom_css: You can apply custom styles on the web version of Mastodon. favicon: WEBP, PNG, GIF or JPG. Overrides the default Mastodon favicon with a custom icon. landing_page: Selects what page new visitors see when they first arrive on your server. If you select "Trends", then Trends needs to be enabled in the Discovery Settings. If you select "Local feed", then "Access to live feeds featuring local posts" needs to be set to "Everyone" in the Discovery Settings. mascot: Overrides the illustration in the advanced web interface. media_cache_retention_period: Media files from posts made by remote users are cached on your server. When set to a positive value, media will be deleted after the specified number of days. If the media data is requested after it is deleted, it will be re-downloaded, if the source content is still available. Due to restrictions on how often link preview cards poll third-party sites, it is recommended to set this value to at least 14 days, or link preview cards will not be updated on demand before that time. min_age: Users will be asked to confirm their date of birth during sign-up - peers_api_enabled: A list of domain names this server has encountered in the fediverse. No data is included here about whether you federate with a given server, just that your server knows about it. This is used by services that collect statistics on federation in a general sense. + peers_api_enabled: A list of domain names this server has encountered in the Fediverse. No data is included here about whether you federate with a given server, just that your server knows about it. This is used by services that collect statistics on federation in a general sense. profile_directory: The profile directory lists all users who have opted-in to be discoverable. require_invite_text: When sign-ups require manual approval, make the “Why do you want to join?” text input mandatory rather than optional site_contact_email: How people can reach you for legal or support inquiries. @@ -110,7 +110,7 @@ en-GB: theme: Theme that logged out visitors and new users see. thumbnail: A roughly 2:1 image displayed alongside your server information. trendable_by_default: Skip manual review of trending content. Individual items can still be removed from trends after the fact. - trends: Trends show which posts, hashtags and news stories are gaining traction on your server. + trends: Trends show which posts, hashtags, and news stories are gaining traction on your server. form_challenge: current_password: You are entering a secure area imports: @@ -131,7 +131,7 @@ en-GB: text: Describe a rule or requirement for users on this server. Try to keep it short and simple sessions: otp: 'Enter the two-factor code generated by your phone app or use one of your recovery codes:' - webauthn: If it's an USB key be sure to insert it and, if necessary, tap it. + webauthn: If it's a USB key be sure to insert it and, if necessary, tap it. settings: indexable: Your profile page may appear in search results on Google, Bing, and others. show_application: You will always be able to see which app published your post regardless. @@ -145,11 +145,11 @@ en-GB: admin_email: Legal notices include counternotices, court orders, takedown requests, and law enforcement requests. arbitration_address: Can be the same as Physical address above, or “N/A” if using email. arbitration_website: Can be a web form, or “N/A” if using email. - choice_of_law: City, region, territory or state the internal substantive laws of which shall govern any and all claims. + choice_of_law: City, region, territory, or state, the internal substantive laws of which shall govern any and all claims. dmca_address: For US operators, use the address registered in the DMCA Designated Agent Directory. A P.O. Box listing is available upon direct request, use the DMCA Designated Agent Post Office Box Waiver Request to email the Copyright Office and describe that you are a home-based content moderator who fears revenge or retribution for your actions and need to use a P.O. Box to remove your home address from public view. dmca_email: Can be the same email used for “Email address for legal notices” above. domain: Unique identification of the online service you are providing. - jurisdiction: List the country where whoever pays the bills lives. If it’s a company or other entity, list the country where it’s incorporated, and the city, region, territory or state as appropriate. + jurisdiction: List the country where whoever pays the bills lives. If it’s a company or other entity, list the country where it’s incorporated, and the city, region, territory, or state as appropriate. min_age: Should not be below the minimum age required by the laws of your jurisdiction. user: chosen_languages: When checked, only posts in selected languages will be displayed in public timelines @@ -158,7 +158,7 @@ en-GB: other: We have to make sure you're at least %{count} to use %{domain}. We won't store this. role: The role controls which permissions the user has. user_role: - color: Color to be used for the role throughout the UI, as RGB in hex format + color: Colour to be used for the role throughout the UI, as RGB in hex format highlighted: This makes the role publicly visible name: Public name of the role, if role is set to be displayed as a badge permissions_as_keys: Users with this role will have access to... @@ -170,7 +170,7 @@ en-GB: webhook: events: Select events to send template: Compose your own JSON payload using variable interpolation. Leave blank for default JSON. - url: Where events will be sent to + url: Where events will be sent labels: account: attribution_domains: Websites allowed to credit you @@ -189,8 +189,8 @@ en-GB: text: Preset text title: Title admin_account_action: - include_statuses: Include reported posts in the e-mail - send_email_notification: Notify the user per e-mail + include_statuses: Include reported posts in the email + send_email_notification: Notify the user per email text: Custom warning type: Action types: @@ -219,7 +219,7 @@ en-GB: current_password: Current password data: Data display_name: Display name - email: E-mail address + email: Email address expires_in: Expire after fields: Profile metadata header: Header @@ -227,7 +227,7 @@ en-GB: inbox_url: URL of the relay inbox irreversible: Drop instead of hide locale: Interface language - max_uses: Max number of uses + max_uses: Maximum number of uses new_password: New password note: Bio otp_attempt: Two-factor code @@ -235,7 +235,7 @@ en-GB: phrase: Keyword or phrase setting_advanced_layout: Enable advanced web interface setting_aggregate_reblogs: Group boosts in timelines - setting_always_send_emails: Always send e-mail notifications + setting_always_send_emails: Always send email notifications setting_auto_play_gif: Auto-play animated GIFs setting_boost_modal: Control boosting visibility setting_default_language: Posting language @@ -259,7 +259,7 @@ en-GB: setting_system_scrollbars_ui: Use system's default scrollbar setting_theme: Site theme setting_trends: Show today's trends - setting_unfollow_modal: Show confirmation dialog before unfollowing someone + setting_unfollow_modal: Show confirmation dialogue before unfollowing someone setting_use_blurhash: Show colourful gradients for hidden media setting_use_pending_items: Slow mode severity: Severity @@ -295,13 +295,13 @@ en-GB: min_age: Minimum age requirement peers_api_enabled: Publish list of discovered servers in the API profile_directory: Enable profile directory - registrations_mode: Who can sign-up + registrations_mode: Who can sign up remote_live_feed_access: Access to live feeds featuring remote posts remote_topic_feed_access: Access to hashtag and link feeds featuring remote posts require_invite_text: Require a reason to join show_domain_blocks: Show domain blocks show_domain_blocks_rationale: Show why domains were blocked - site_contact_email: Contact e-mail + site_contact_email: Contact email site_contact_username: Contact username site_extended_description: Extended description site_short_description: Server description @@ -344,7 +344,7 @@ en-GB: critical: Notify on critical updates only label: A new Mastodon version is available none: Never notify of updates (not recommended) - patch: Notify on bugfix updates + patch: Notify on bug fix updates trending_tag: New trend requires review rule: hint: Additional information diff --git a/config/locales/simple_form.ko.yml b/config/locales/simple_form.ko.yml index 2f0e09bc94d1ea..5d96fd07215dfb 100644 --- a/config/locales/simple_form.ko.yml +++ b/config/locales/simple_form.ko.yml @@ -54,6 +54,7 @@ ko: password: 최소 8글자 phrase: 게시물 내용이나 열람주의 내용 안에서 대소문자 구분 없이 매칭 됩니다 scopes: 애플리케이션에 허용할 API들입니다. 최상위 스코프를 선택하면 개별적인 것은 선택하지 않아도 됩니다. + setting_advanced_layout: 마스토돈을 멀티컬럼으로 보여주어 타임라인, 알림, 그리고 내가 원하는 컬럼을 한 번에 볼 수 있도록 합니다. 작은 화면에선 추천하지 않습니다. setting_aggregate_reblogs: 최근에 부스트 됐던 게시물은 새로 부스트 되어도 보여주지 않기 (새로 받은 부스트에만 적용됩니다) setting_always_send_emails: 기본적으로 마스토돈을 활동적으로 사용하고 있을 때에는 이메일 알림이 보내지지 않습니다 setting_boost_modal: 활성화하면 부스트하기 전에 부스트의 공개설정을 바꿀 수 있는 확인창이 먼저 뜨게 됩니다. diff --git a/config/locales/simple_form.zh-TW.yml b/config/locales/simple_form.zh-TW.yml index e371d0ac077b23..e114ee0d237b7d 100644 --- a/config/locales/simple_form.zh-TW.yml +++ b/config/locales/simple_form.zh-TW.yml @@ -109,8 +109,8 @@ zh-TW: status_page_url: 當服務中斷時,可以提供使用者了解伺服器資訊頁面之 URL theme: 未登入之訪客或新使用者所見之佈景主題。 thumbnail: 大約 2:1 圖片會顯示於您伺服器資訊之旁。 - trendable_by_default: 跳過手動審核熱門內容。仍能於登上熱門趨勢後移除個別內容。 - trends: 熱門趨勢將顯示於您伺服器上正在吸引大量注意力的嘟文、主題標籤、或者新聞。 + trendable_by_default: 跳過手動審核熱門內容。您仍能於登上熱門趨勢後移除個別內容。 + trends: 熱門趨勢將顯示於您伺服器上正在吸引大量注意力之嘟文、主題標籤、或新聞。 form_challenge: current_password: 您正要進入安全區域 imports: @@ -354,7 +354,7 @@ zh-TW: tag: listable: 允許此主題標籤於搜尋及個人檔案目錄中顯示 name: 主題標籤 - trendable: 允許此主題標籤於熱門趨勢下顯示 + trendable: 允許此主題標籤於熱門趨勢中顯示 usable: 允許嘟文使用此主題標籤 terms_of_service: changelog: 有何異動? diff --git a/config/locales/sq.yml b/config/locales/sq.yml index 8171dcea85c069..89eeac7c547b81 100644 --- a/config/locales/sq.yml +++ b/config/locales/sq.yml @@ -7,6 +7,8 @@ sq: hosted_on: Server Mastodon i strehuar në %{domain} title: Mbi accounts: + errors: + cannot_be_added_to_collections: Kjo llogari s’mund të shtohet në koleksione. followers: one: Ndjekës other: Ndjekës @@ -2169,3 +2171,5 @@ sq: not_supported: Ky shfletues nuk mbulon kyçe sigurie otp_required: Që të përdoren kyçe sigurie, ju lutemi, së pari aktivizoni mirëfilltësimin dyfaktorësh. registered_on: Regjistruar më %{date} + wrapstodon: + description: Shihni si u përdor Mastodon-in këtë vit nga %{name}! diff --git a/config/locales/tr.yml b/config/locales/tr.yml index 749088b7191d16..13f1e6a62f7d07 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -7,6 +7,8 @@ tr: hosted_on: Mastodon %{domain} üzerinde barındırılıyor title: Hakkında accounts: + errors: + cannot_be_added_to_collections: Bu hesap koleksiyonlara eklenemez. followers: one: Takipçi other: Takipçiler @@ -2186,4 +2188,5 @@ tr: otp_required: Güvenlik anahtarlarını kullanmak için lütfen önce iki adımlı kimlik doğrulamayı etkinleştirin. registered_on: "%{date} tarihinde kaydoldu" wrapstodon: + description: "%{name} kullanıcısının bu yıl Mastodon'u nasıl kullandığını görün!" title: "%{name} için %{year} Wrapstodon'u" diff --git a/config/locales/vi.yml b/config/locales/vi.yml index 59bd33fffd9525..4e4c8c762498ae 100644 --- a/config/locales/vi.yml +++ b/config/locales/vi.yml @@ -7,6 +7,8 @@ vi: hosted_on: "%{domain} vận hành nhờ Mastodon" title: Giới thiệu accounts: + errors: + cannot_be_added_to_collections: Tài khoản này không thể thêm vào bộ sưu tập. followers: other: Người theo dõi following: Theo dõi @@ -2142,4 +2144,5 @@ vi: otp_required: Để dùng khóa bảo mật, trước tiên hãy kích hoạt xác thực 2 bước. registered_on: Đăng ký vào %{date} wrapstodon: + description: Xem năm nay %{name} đã dùng Mastodon như thế nào! title: Wrapstodon %{year} cho %{name} diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index bfe2c9917ad9a3..9dffdcd2495e00 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -7,6 +7,8 @@ zh-CN: hosted_on: 运行在 %{domain} 上的 Mastodon 实例 title: 关于本站 accounts: + errors: + cannot_be_added_to_collections: 此账号无法被添加到关注列表内。 followers: other: 关注者 following: 正在关注 @@ -2142,4 +2144,5 @@ zh-CN: otp_required: 要使用安全密钥,请先启用双因素认证。 registered_on: 注册于 %{date} wrapstodon: + description: 来看看%{name}今年是怎么使用Mastodon的! title: "%{name}的%{year}年Wrapstodon年度回顾" diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index ec19a2424769f1..07edf91c9aaaca 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -7,6 +7,8 @@ zh-TW: hosted_on: 於 %{domain} 託管之 Mastodon 站點 title: 關於本站 accounts: + errors: + cannot_be_added_to_collections: 此帳號無法被加至集合中。 followers: other: 跟隨者 following: 正在跟隨 @@ -2148,4 +2150,5 @@ zh-TW: otp_required: 請先啟用兩階段驗證以使用安全金鑰。 registered_on: 註冊於 %{date} wrapstodon: + description: 來瞧瞧 %{name} 今年是如何使用 Mastodon 吧! title: "%{name} 的 %{year} Mastodon 年度回顧 (Wrapstodon)" From 42d4753d3060cf3ca3952de192e408d188457c42 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 14:15:05 +0100 Subject: [PATCH 819/853] Update dependency vite-tsconfig-paths to v6.0.2 (#37279) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index cac2a0c716b82b..eeb029e59fb4cf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14069,8 +14069,8 @@ __metadata: linkType: hard "vite-tsconfig-paths@npm:^6.0.0": - version: 6.0.1 - resolution: "vite-tsconfig-paths@npm:6.0.1" + version: 6.0.2 + resolution: "vite-tsconfig-paths@npm:6.0.2" dependencies: debug: "npm:^4.1.1" globrex: "npm:^0.1.2" @@ -14080,7 +14080,7 @@ __metadata: peerDependenciesMeta: vite: optional: true - checksum: 10c0/c0702f1d2b9d2e3e6ebb44d8e9c27b17b1102e86946ab54b6bbd290419b134e84df4e451b55db973bc97d9de5689df6f67e479633df20244aa0c62ffd0b16e43 + checksum: 10c0/878189e38a253b699998f94706b15718a03d59467b091e064f33090240f9ccfa4bf273c3b30b5f9711822c56a58b786c3e6c6cebb8859e56ec5ab49e360ff8c0 languageName: node linkType: hard From a5362a40023b416649e8784e57f43d017b721ded Mon Sep 17 00:00:00 2001 From: Nicholas La Roux Date: Wed, 17 Dec 2025 09:06:45 -0500 Subject: [PATCH 820/853] Upgrade Bundler from 4.0.1 to 4.0.2 (#37283) --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 0692e07135ac2a..20e4ff9fe71b6f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1093,4 +1093,4 @@ RUBY VERSION ruby 3.4.1p0 BUNDLED WITH - 4.0.1 + 4.0.2 From d6a40c2891770d2bd5dfa881d482a34c4acd646f Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 17 Dec 2025 15:28:53 +0100 Subject: [PATCH 821/853] Fix hashtag autocomplete replacing suggestion's first characters with input (#37281) --- app/javascript/mastodon/actions/compose.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/javascript/mastodon/actions/compose.js b/app/javascript/mastodon/actions/compose.js index bd1cb3ca9bc3a5..6e39db4756c857 100644 --- a/app/javascript/mastodon/actions/compose.js +++ b/app/javascript/mastodon/actions/compose.js @@ -673,7 +673,16 @@ export function selectComposeSuggestion(position, token, suggestion, path) { dispatch(useEmoji(suggestion)); } else if (suggestion.type === 'hashtag') { - completion = token + suggestion.name.slice(token.length - 1); + // TODO: it could make sense to keep the “most capitalized” of the two + const tokenName = token.slice(1); // strip leading '#' + const suggestionPrefix = suggestion.name.slice(0, tokenName.length); + const prefixMatchesSuggestion = suggestionPrefix.localeCompare(tokenName, undefined, { sensitivity: 'accent' }) === 0; + if (prefixMatchesSuggestion) { + completion = token + suggestion.name.slice(tokenName.length); + } else { + completion = `${token.slice(0, 1)}${suggestion.name}`; + } + startPosition = position - 1; } else if (suggestion.type === 'account') { completion = `@${getState().getIn(['accounts', suggestion.id, 'acct'])}`; From 71af094f9735cea10cb0e2da92ebac1608393ebb Mon Sep 17 00:00:00 2001 From: diondiondion Date: Wed, 17 Dec 2025 15:38:46 +0100 Subject: [PATCH 822/853] Fix notifications page error in Tor browser (#37285) --- .../components/status_action_bar/remove_quote_hint.module.css | 3 +++ .../components/status_action_bar/remove_quote_hint.tsx | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 app/javascript/mastodon/components/status_action_bar/remove_quote_hint.module.css diff --git a/app/javascript/mastodon/components/status_action_bar/remove_quote_hint.module.css b/app/javascript/mastodon/components/status_action_bar/remove_quote_hint.module.css new file mode 100644 index 00000000000000..5045b6d1b95590 --- /dev/null +++ b/app/javascript/mastodon/components/status_action_bar/remove_quote_hint.module.css @@ -0,0 +1,3 @@ +.inlineIcon { + vertical-align: middle; +} diff --git a/app/javascript/mastodon/components/status_action_bar/remove_quote_hint.tsx b/app/javascript/mastodon/components/status_action_bar/remove_quote_hint.tsx index 69795945a02716..cfa72feb6843a5 100644 --- a/app/javascript/mastodon/components/status_action_bar/remove_quote_hint.tsx +++ b/app/javascript/mastodon/components/status_action_bar/remove_quote_hint.tsx @@ -12,6 +12,8 @@ import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react'; import { Button } from '../button'; import { Icon } from '../icon'; +import classes from './remove_quote_hint.module.css'; + const DISMISSIBLE_BANNER_ID = 'notifications/remove_quote_hint'; /** @@ -92,7 +94,7 @@ export const RemoveQuoteHint: React.FC<{ id: 'status.more', defaultMessage: 'More', })} - style={{ verticalAlign: 'middle' }} + className={classes.inlineIcon} /> ), }} From dbc5af6641b06e19b2dbb36274bb647b7564d3f5 Mon Sep 17 00:00:00 2001 From: Echo Date: Wed, 17 Dec 2025 15:40:34 +0100 Subject: [PATCH 823/853] Remove rendering of custom emoji using the database (#37284) --- .storybook/main.ts | 1 + .../components/emoji/emoji.stories.tsx | 15 ++--- .../mastodon/features/emoji/render.test.ts | 31 ++--------- .../mastodon/features/emoji/render.ts | 55 +++++++++---------- app/javascript/testing/factories.ts | 4 +- 5 files changed, 41 insertions(+), 65 deletions(-) diff --git a/.storybook/main.ts b/.storybook/main.ts index c249d1c06dcff1..2f70c80dbfe00a 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -27,6 +27,7 @@ const config: StorybookConfig = { 'oops.gif', 'oops.png', ].map((path) => ({ from: `../public/${path}`, to: `/${path}` })), + { from: '../app/javascript/images/logo.svg', to: '/custom-emoji/logo.svg' }, ], viteFinal(config) { // For an unknown reason, Storybook does not use the root diff --git a/app/javascript/mastodon/components/emoji/emoji.stories.tsx b/app/javascript/mastodon/components/emoji/emoji.stories.tsx index fcc81db6c3a98e..e7d1887aa9a3a8 100644 --- a/app/javascript/mastodon/components/emoji/emoji.stories.tsx +++ b/app/javascript/mastodon/components/emoji/emoji.stories.tsx @@ -2,6 +2,9 @@ import type { ComponentProps } from 'react'; import type { Meta, StoryObj } from '@storybook/react-vite'; +import { customEmojiFactory } from '@/testing/factories'; + +import { CustomEmojiProvider } from './context'; import { Emoji } from './index'; type EmojiProps = ComponentProps & { @@ -34,7 +37,11 @@ const meta = { }, }, render(args) { - return ; + return ( + + + + ); }, } satisfies Meta; @@ -49,9 +56,3 @@ export const CustomEmoji: Story = { code: ':custom:', }, }; - -export const LegacyEmoji: Story = { - args: { - code: ':copyright:', - }, -}; diff --git a/app/javascript/mastodon/features/emoji/render.test.ts b/app/javascript/mastodon/features/emoji/render.test.ts index 782148b36e377c..dffebd1f8c576c 100644 --- a/app/javascript/mastodon/features/emoji/render.test.ts +++ b/app/javascript/mastodon/features/emoji/render.test.ts @@ -83,12 +83,8 @@ describe('stringToEmojiState', () => { }); }); - test('returns custom emoji state for valid custom emoji', () => { - expect(stringToEmojiState(':smile:')).toEqual({ - type: 'custom', - code: 'smile', - data: undefined, - }); + test('returns null for custom emoji without data', () => { + expect(stringToEmojiState(':smile:')).toBeNull(); }); test('returns custom emoji state with data when provided', () => { @@ -108,7 +104,6 @@ describe('stringToEmojiState', () => { test('returns null for invalid emoji strings', () => { expect(stringToEmojiState('notanemoji')).toBeNull(); - expect(stringToEmojiState(':invalid-emoji:')).toBeNull(); }); }); @@ -142,21 +137,13 @@ describe('loadEmojiDataToState', () => { }); }); - test('loads custom emoji data into state', async () => { - const dbCall = vi - .spyOn(db, 'loadCustomEmojiByShortcode') - .mockResolvedValueOnce(customEmojiFactory()); + test('returns null for custom emoji without data', async () => { const customState = { type: 'custom', code: 'smile', } as const satisfies EmojiStateCustom; const result = await loadEmojiDataToState(customState, 'en'); - expect(dbCall).toHaveBeenCalledWith('smile'); - expect(result).toEqual({ - type: 'custom', - code: 'smile', - data: customEmojiFactory(), - }); + expect(result).toBeNull(); }); test('loads unicode data using legacy shortcode', async () => { @@ -194,16 +181,6 @@ describe('loadEmojiDataToState', () => { expect(result).toBeNull(); }); - test('returns null if custom emoji not found in database', async () => { - vi.spyOn(db, 'loadCustomEmojiByShortcode').mockResolvedValueOnce(undefined); - const customState = { - type: 'custom', - code: 'smile', - } as const satisfies EmojiStateCustom; - const result = await loadEmojiDataToState(customState, 'en'); - expect(result).toBeNull(); - }); - test('retries loading emoji data once if initial load fails', async () => { const dbCall = vi .spyOn(db, 'loadEmojiByHexcode') diff --git a/app/javascript/mastodon/features/emoji/render.ts b/app/javascript/mastodon/features/emoji/render.ts index e00525fe0a110e..38bc7fd7e52129 100644 --- a/app/javascript/mastodon/features/emoji/render.ts +++ b/app/javascript/mastodon/features/emoji/render.ts @@ -5,7 +5,6 @@ import { EMOJI_TYPE_CUSTOM, } from './constants'; import { - loadCustomEmojiByShortcode, loadEmojiByHexcode, loadLegacyShortcodesByShortcode, LocaleNotLoadedError, @@ -80,7 +79,7 @@ export function tokenizeText(text: string): TokenizedText { export function stringToEmojiState( code: string, customEmoji: ExtraCustomEmojiMap = {}, -): EmojiState | null { +): EmojiStateUnicode | Required | null { if (isUnicodeEmoji(code)) { return { type: EMOJI_TYPE_UNICODE, @@ -90,11 +89,13 @@ export function stringToEmojiState( if (isCustomEmoji(code)) { const shortCode = code.slice(1, -1); - return { - type: EMOJI_TYPE_CUSTOM, - code: shortCode, - data: customEmoji[shortCode], - }; + if (customEmoji[shortCode]) { + return { + type: EMOJI_TYPE_CUSTOM, + code: shortCode, + data: customEmoji[shortCode], + }; + } } return null; @@ -115,33 +116,29 @@ export async function loadEmojiDataToState( return state; } + // Don't try to load data for custom emoji. + if (state.type === EMOJI_TYPE_CUSTOM) { + return null; + } + // First, try to load the data from IndexedDB. try { const legacyCode = await loadLegacyShortcodesByShortcode(state.code); // This is duplicative, but that's because TS can't distinguish the state type easily. - if (state.type === EMOJI_TYPE_UNICODE || legacyCode) { - const data = await loadEmojiByHexcode( - legacyCode?.hexcode ?? state.code, - locale, - ); - if (data) { - return { - ...state, - type: EMOJI_TYPE_UNICODE, - data, - // TODO: Use CLDR shortcodes when the picker supports them. - shortcode: legacyCode?.shortcodes.at(0), - }; - } - } else { - const data = await loadCustomEmojiByShortcode(state.code); - if (data) { - return { - ...state, - data, - }; - } + const data = await loadEmojiByHexcode( + legacyCode?.hexcode ?? state.code, + locale, + ); + if (data) { + return { + ...state, + type: EMOJI_TYPE_UNICODE, + data, + // TODO: Use CLDR shortcodes when the picker supports them. + shortcode: legacyCode?.shortcodes.at(0), + }; } + // If not found, assume it's not an emoji and return null. log( 'Could not find emoji %s of type %s for locale %s', diff --git a/app/javascript/testing/factories.ts b/app/javascript/testing/factories.ts index 72d7abe000805a..28c0eca809722f 100644 --- a/app/javascript/testing/factories.ts +++ b/app/javascript/testing/factories.ts @@ -128,8 +128,8 @@ export function customEmojiFactory( ): CustomEmojiData { return { shortcode: 'custom', - static_url: 'emoji/custom/static', - url: 'emoji/custom', + static_url: '/custom-emoji/logo.svg', + url: '/custom-emoji/logo.svg', visible_in_picker: true, ...data, }; From c4a760d6ba4394f07d1147259ebf280b0bade33f Mon Sep 17 00:00:00 2001 From: diondiondion Date: Wed, 17 Dec 2025 15:42:07 +0100 Subject: [PATCH 824/853] Improve search menu keyboard navigation (#37255) --- .../features/compose/components/search.tsx | 77 +++++++++++++------ 1 file changed, 54 insertions(+), 23 deletions(-) diff --git a/app/javascript/mastodon/features/compose/components/search.tsx b/app/javascript/mastodon/features/compose/components/search.tsx index 285a352268b8a1..c2855e8cb58676 100644 --- a/app/javascript/mastodon/features/compose/components/search.tsx +++ b/app/javascript/mastodon/features/compose/components/search.tsx @@ -1,4 +1,11 @@ -import { useCallback, useState, useRef, useEffect, useMemo } from 'react'; +import { + useCallback, + useState, + useRef, + useEffect, + useMemo, + useId, +} from 'react'; import { defineMessages, @@ -432,12 +439,17 @@ export const Search: React.FC<{ switch (e.key) { case 'Escape': e.preventDefault(); - unfocus(); + searchInputRef.current?.focus(); + setExpanded(false); break; case 'ArrowDown': e.preventDefault(); + if (!expanded) { + setExpanded(true); + } + if (navigableOptions.length > 0) { setSelectedOption( Math.min(selectedOption + 1, navigableOptions.length - 1), @@ -476,10 +488,10 @@ export const Search: React.FC<{ break; } }, - [unfocus, navigableOptions, selectedOption, submit, value], + [expanded, navigableOptions, selectedOption, submit, value], ); - const handleFocus = useCallback(() => { + const handleInputFocus = useCallback(() => { setExpanded(true); setSelectedOption(-1); @@ -495,10 +507,16 @@ export const Search: React.FC<{ } }, [setExpanded, setSelectedOption, singleColumn]); - const handleBlur = useCallback(() => { + const handleInputBlur = useCallback(() => { setSelectedOption(-1); }, [setSelectedOption]); + const getOptionFocusHandler = useCallback((index: number) => { + return () => { + setSelectedOption(index); + }; + }, []); + const formRef = useRef(null); useEffect(() => { @@ -526,6 +544,8 @@ export const Search: React.FC<{ return () => null; }, [expanded]); + const searchOptionsHeading = useId(); + return (
-
+ {/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions */} +
{!hasValue && ( <>

@@ -565,6 +592,7 @@ export const Search: React.FC<{ tabIndex={0} role='button' onMouseDown={action} + onFocus={getOptionFocusHandler(i)} className={classNames( 'search__popout__menu__item search__popout__menu__item--flex', { selected: selectedOption === i }, @@ -606,6 +634,7 @@ export const Search: React.FC<{ - ))} + {searchOptions.map(({ key, label, action }, i) => { + const currentIndex = (quickActions.length || recent.length) + i; + return ( + + ); + })}

) : (
From 7e817f2471f150b0aa32b2e3f6d8e03ebb706522 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 17 Dec 2025 09:48:58 -0500 Subject: [PATCH 825/853] Extract `filter_keywords` helper method for listing filter keyword groups (#35921) --- app/helpers/filters_helper.rb | 8 ++++++++ app/views/filters/_filter.html.haml | 4 +--- spec/helpers/filters_helper_spec.rb | 24 ++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 spec/helpers/filters_helper_spec.rb diff --git a/app/helpers/filters_helper.rb b/app/helpers/filters_helper.rb index 22a1c172de2c86..ec0d55788327d7 100644 --- a/app/helpers/filters_helper.rb +++ b/app/helpers/filters_helper.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true module FiltersHelper + KEYWORDS_LIMIT = 5 + def filter_action_label(action) safe_join( [ @@ -9,4 +11,10 @@ def filter_action_label(action) ] ) end + + def filter_keywords(filter) + filter.keywords.map(&:keyword).take(KEYWORDS_LIMIT).tap do |list| + list << '…' if filter.keywords.size > KEYWORDS_LIMIT + end.join(', ') + end end diff --git a/app/views/filters/_filter.html.haml b/app/views/filters/_filter.html.haml index 15326f300626e8..bf2f4dd7d1d736 100644 --- a/app/views/filters/_filter.html.haml +++ b/app/views/filters/_filter.html.haml @@ -19,9 +19,7 @@ .permissions-list__item__text__title = t('filters.index.keywords', count: filter.keywords.size) .permissions-list__item__text__type - - keywords = filter.keywords.map(&:keyword) - - keywords = keywords.take(5) + ['…'] if keywords.size > 5 # TODO - = keywords.join(', ') + = filter_keywords(filter) - unless filter.statuses.empty? %li.permissions-list__item .permissions-list__item__icon diff --git a/spec/helpers/filters_helper_spec.rb b/spec/helpers/filters_helper_spec.rb new file mode 100644 index 00000000000000..7cbacdfa34b319 --- /dev/null +++ b/spec/helpers/filters_helper_spec.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe FiltersHelper do + describe '#filter_keywords' do + subject { helper.filter_keywords(filter) } + + let(:filter) { Fabricate.build :custom_filter, keywords: } + let(:keywords) { words.map { |keyword| Fabricate.build(:custom_filter_keyword, keyword:) } } + + context 'with few keywords' do + let(:words) { %w(One) } + + it { is_expected.to eq('One') } + end + + context 'with many keywords' do + let(:words) { %w(One Two Three Four Five Six Seven Eight Nine Ten) } + + it { is_expected.to eq('One, Two, Three, Four, Five, …') } + end + end +end From 3d55dcdf7fbbebe3006ef86e765e9fc2455d34e1 Mon Sep 17 00:00:00 2001 From: Echo Date: Wed, 17 Dec 2025 15:58:22 +0100 Subject: [PATCH 826/853] Emoji: Refresh custom emoji on new (#37271) --- .../mastodon/actions/importer/emoji.ts | 22 ++++++ .../mastodon/actions/importer/index.js | 9 +++ .../mastodon/actions/importer/normalizer.js | 6 ++ .../mastodon/features/emoji/database.test.ts | 17 ++++- .../mastodon/features/emoji/database.ts | 24 +++++- .../mastodon/features/emoji/index.ts | 75 ++++++++++++------- .../mastodon/features/emoji/loader.ts | 2 +- 7 files changed, 123 insertions(+), 32 deletions(-) create mode 100644 app/javascript/mastodon/actions/importer/emoji.ts diff --git a/app/javascript/mastodon/actions/importer/emoji.ts b/app/javascript/mastodon/actions/importer/emoji.ts new file mode 100644 index 00000000000000..c4baa57d56c1c1 --- /dev/null +++ b/app/javascript/mastodon/actions/importer/emoji.ts @@ -0,0 +1,22 @@ +import type { ApiCustomEmojiJSON } from '@/mastodon/api_types/custom_emoji'; +import { loadCustomEmoji } from '@/mastodon/features/emoji'; + +export async function importCustomEmoji(emojis: ApiCustomEmojiJSON[]) { + if (emojis.length === 0) { + return; + } + + // First, check if we already have them all. + const { searchCustomEmojisByShortcodes, clearEtag } = + await import('@/mastodon/features/emoji/database'); + + const existingEmojis = await searchCustomEmojisByShortcodes( + emojis.map((emoji) => emoji.shortcode), + ); + + // If there's a mismatch, re-import all custom emojis. + if (existingEmojis.length < emojis.length) { + await clearEtag('custom'); + await loadCustomEmoji(); + } +} diff --git a/app/javascript/mastodon/actions/importer/index.js b/app/javascript/mastodon/actions/importer/index.js index 6a85231bb69dbd..fe31b84bff0bde 100644 --- a/app/javascript/mastodon/actions/importer/index.js +++ b/app/javascript/mastodon/actions/importer/index.js @@ -1,6 +1,7 @@ import { createPollFromServerJSON } from 'mastodon/models/poll'; import { importAccounts } from './accounts'; +import { importCustomEmoji } from './emoji'; import { normalizeStatus } from './normalizer'; import { importPolls } from './polls'; @@ -39,6 +40,10 @@ export function importFetchedAccounts(accounts) { if (account.moved) { processAccount(account.moved); } + + if (account.emojis && account.username === account.acct) { + importCustomEmoji(account.emojis); + } } accounts.forEach(processAccount); @@ -80,6 +85,10 @@ export function importFetchedStatuses(statuses, options = {}) { if (status.card) { status.card.authors.forEach(author => author.account && pushUnique(accounts, author.account)); } + + if (status.emojis && status.account.username === status.account.acct) { + importCustomEmoji(status.emojis); + } } statuses.forEach(processStatus); diff --git a/app/javascript/mastodon/actions/importer/normalizer.js b/app/javascript/mastodon/actions/importer/normalizer.js index 075dc84ef1c56b..854865104ac84d 100644 --- a/app/javascript/mastodon/actions/importer/normalizer.js +++ b/app/javascript/mastodon/actions/importer/normalizer.js @@ -2,6 +2,8 @@ import escapeTextContentForBrowser from 'escape-html'; import { expandSpoilers } from '../../initial_state'; +import { importCustomEmoji } from './emoji'; + const domParser = new DOMParser(); export function searchTextFromRawStatus (status) { @@ -151,5 +153,9 @@ export function normalizeAnnouncement(announcement) { normalAnnouncement.contentHtml = normalAnnouncement.content; + if (normalAnnouncement.emojis) { + importCustomEmoji(normalAnnouncement.emojis); + } + return normalAnnouncement; } diff --git a/app/javascript/mastodon/features/emoji/database.test.ts b/app/javascript/mastodon/features/emoji/database.test.ts index 5931a238eabbd2..6b6ea952b74cdc 100644 --- a/app/javascript/mastodon/features/emoji/database.test.ts +++ b/app/javascript/mastodon/features/emoji/database.test.ts @@ -43,11 +43,26 @@ describe('emoji database', () => { describe('putCustomEmojiData', () => { test('loads custom emoji into indexedDB', async () => { const { db } = await testGet(); - await putCustomEmojiData([customEmojiFactory()]); + await putCustomEmojiData({ emojis: [customEmojiFactory()] }); await expect(db.get('custom', 'custom')).resolves.toEqual( customEmojiFactory(), ); }); + + test('clears existing custom emoji if specified', async () => { + const { db } = await testGet(); + await putCustomEmojiData({ + emojis: [customEmojiFactory({ shortcode: 'emoji1' })], + }); + await putCustomEmojiData({ + emojis: [customEmojiFactory({ shortcode: 'emoji2' })], + clear: true, + }); + await expect(db.get('custom', 'emoji1')).resolves.toBeUndefined(); + await expect(db.get('custom', 'emoji2')).resolves.toEqual( + customEmojiFactory({ shortcode: 'emoji2' }), + ); + }); }); describe('putLegacyShortcodes', () => { diff --git a/app/javascript/mastodon/features/emoji/database.ts b/app/javascript/mastodon/features/emoji/database.ts index 2e8de712217570..9e03b53d3c6ad8 100644 --- a/app/javascript/mastodon/features/emoji/database.ts +++ b/app/javascript/mastodon/features/emoji/database.ts @@ -161,11 +161,26 @@ export async function putEmojiData(emojis: UnicodeEmojiData[], locale: Locale) { await trx.done; } -export async function putCustomEmojiData(emojis: CustomEmojiData[]) { +export async function putCustomEmojiData({ + emojis, + clear = false, +}: { + emojis: CustomEmojiData[]; + clear?: boolean; +}) { const db = await loadDB(); const trx = db.transaction('custom', 'readwrite'); + + // When importing from the API, clear everything first. + if (clear) { + await trx.store.clear(); + log('Cleared existing custom emojis in database'); + } + await Promise.all(emojis.map((emoji) => trx.store.put(emoji))); await trx.done; + + log('Imported %d custom emojis into database', emojis.length); } export async function putLegacyShortcodes(shortcodes: ShortcodesDataset) { @@ -188,6 +203,13 @@ export async function putLatestEtag(etag: string, localeString: string) { await db.put('etags', etag, locale); } +export async function clearEtag(localeString: string) { + const locale = toSupportedLocaleOrCustom(localeString); + const db = await loadDB(); + await db.delete('etags', locale); + log('Cleared etag for %s', locale); +} + export async function loadEmojiByHexcode( hexcode: string, localeString: string, diff --git a/app/javascript/mastodon/features/emoji/index.ts b/app/javascript/mastodon/features/emoji/index.ts index bd38dea77a0a39..b0b0fb49b22abb 100644 --- a/app/javascript/mastodon/features/emoji/index.ts +++ b/app/javascript/mastodon/features/emoji/index.ts @@ -3,7 +3,6 @@ import type { Locale } from 'emojibase'; import { initialState } from '@/mastodon/initial_state'; import type { EMOJI_DB_NAME_SHORTCODES, EMOJI_TYPE_CUSTOM } from './constants'; -import { importLegacyShortcodes, localeToShortcodesPath } from './loader'; import { toSupportedLocale } from './locale'; import type { LocaleOrCustom } from './types'; import { emojiLogger } from './utils'; @@ -16,48 +15,54 @@ let worker: Worker | null = null; const log = emojiLogger('index'); -const WORKER_TIMEOUT = 1_000; // 1 second +// This is too short, but better to fallback quickly than wait. +const WORKER_TIMEOUT = 1_000; export function initializeEmoji() { log('initializing emojis'); + + // Create a temp worker, and assign it to the module-level worker once we know it's ready. + let tempWorker: Worker | null = null; if (!worker && 'Worker' in window) { try { - worker = new EmojiWorker(); + tempWorker = new EmojiWorker(); } catch (err) { console.warn('Error creating web worker:', err); } } - if (worker) { - const timeoutId = setTimeout(() => { - log('worker is not ready after timeout'); - worker = null; - void fallbackLoad(); - }, WORKER_TIMEOUT); - worker.addEventListener('message', (event: MessageEvent) => { - const { data: message } = event; - if (message === 'ready') { - log('worker ready, loading data'); - clearTimeout(timeoutId); - messageWorker('custom'); - messageWorker('shortcodes'); - void loadEmojiLocale(userLocale); - } else { - log('got worker message: %s', message); - } - }); - } else { + if (!tempWorker) { void fallbackLoad(); + return; } + + const timeoutId = setTimeout(() => { + log('worker is not ready after timeout'); + void fallbackLoad(); + }, WORKER_TIMEOUT); + + tempWorker.addEventListener('message', (event: MessageEvent) => { + const { data: message } = event; + + worker ??= tempWorker; + + if (message === 'ready') { + log('worker ready, loading data'); + clearTimeout(timeoutId); + messageWorker('shortcodes'); + void loadCustomEmoji(); + void loadEmojiLocale(userLocale); + } else { + log('got worker message: %s', message); + } + }); } async function fallbackLoad() { log('falling back to main thread for loading'); - const { importCustomEmojiData } = await import('./loader'); - const emojis = await importCustomEmojiData(); - if (emojis) { - log('loaded %d custom emojis', emojis.length); - } + + await loadCustomEmoji(); + const { importLegacyShortcodes } = await import('./loader'); const shortcodes = await importLegacyShortcodes(); if (shortcodes.length) { log('loaded %d legacy shortcodes', shortcodes.length); @@ -67,11 +72,11 @@ async function fallbackLoad() { async function loadEmojiLocale(localeString: string) { const locale = toSupportedLocale(localeString); - const { importEmojiData, localeToEmojiPath: localeToPath } = + const { importEmojiData, localeToEmojiPath, localeToShortcodesPath } = await import('./loader'); if (worker) { - const path = await localeToPath(locale); + const path = await localeToEmojiPath(locale); const shortcodesPath = await localeToShortcodesPath(locale); log('asking worker to load locale %s from %s', locale, path); messageWorker(locale, path, shortcodesPath); @@ -83,6 +88,18 @@ async function loadEmojiLocale(localeString: string) { } } +export async function loadCustomEmoji() { + if (worker) { + messageWorker('custom'); + } else { + const { importCustomEmojiData } = await import('./loader'); + const emojis = await importCustomEmojiData(); + if (emojis && emojis.length > 0) { + log('loaded %d custom emojis', emojis.length); + } + } +} + function messageWorker( locale: typeof EMOJI_TYPE_CUSTOM | typeof EMOJI_DB_NAME_SHORTCODES, ): void; diff --git a/app/javascript/mastodon/features/emoji/loader.ts b/app/javascript/mastodon/features/emoji/loader.ts index b2407697dfff5f..0dfa22b99d08d1 100644 --- a/app/javascript/mastodon/features/emoji/loader.ts +++ b/app/javascript/mastodon/features/emoji/loader.ts @@ -76,7 +76,7 @@ export async function importCustomEmojiData() { if (!emojis) { return; } - await putCustomEmojiData(emojis); + await putCustomEmojiData({ emojis, clear: true }); return emojis; } From 009275e66b55729f754da7b4c814b37b67dc76dc Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 17 Dec 2025 10:19:21 -0500 Subject: [PATCH 827/853] Use `link_to` for contribute translation link (#36011) --- app/views/settings/preferences/appearance/show.html.haml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/views/settings/preferences/appearance/show.html.haml b/app/views/settings/preferences/appearance/show.html.haml index e6e96f97d5583a..45a27eb4822a5d 100644 --- a/app/views/settings/preferences/appearance/show.html.haml +++ b/app/views/settings/preferences/appearance/show.html.haml @@ -43,7 +43,8 @@ - unless I18n.locale == :en .flash-message.translation-prompt - #{t 'appearance.localization.body'} #{content_tag(:a, t('appearance.localization.guide_link_text'), href: t('appearance.localization.guide_link'), target: '_blank', rel: 'noopener')} + = t 'appearance.localization.body' + = link_to t('appearance.localization.guide_link_text'), t('appearance.localization.guide_link'), target: '_blank', rel: 'noopener' = f.simple_fields_for :settings, current_user.settings do |ff| %h4= t 'appearance.animations_and_accessibility' From 22724d236754aaae9ee44792101cddc0b133aa84 Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 17 Dec 2025 15:28:53 +0100 Subject: [PATCH 828/853] [Glitch] Fix hashtag autocomplete replacing suggestion's first characters with input Port d6a40c2891770d2bd5dfa881d482a34c4acd646f to glitch-soc Signed-off-by: Claire --- app/javascript/flavours/glitch/actions/compose.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/javascript/flavours/glitch/actions/compose.js b/app/javascript/flavours/glitch/actions/compose.js index 0e2b2f110cf977..a7d491377bcf5f 100644 --- a/app/javascript/flavours/glitch/actions/compose.js +++ b/app/javascript/flavours/glitch/actions/compose.js @@ -709,7 +709,16 @@ export function selectComposeSuggestion(position, token, suggestion, path) { dispatch(useEmoji(suggestion)); } else if (suggestion.type === 'hashtag') { - completion = token + suggestion.name.slice(token.length - 1); + // TODO: it could make sense to keep the “most capitalized” of the two + const tokenName = token.slice(1); // strip leading '#' + const suggestionPrefix = suggestion.name.slice(0, tokenName.length); + const prefixMatchesSuggestion = suggestionPrefix.localeCompare(tokenName, undefined, { sensitivity: 'accent' }) === 0; + if (prefixMatchesSuggestion) { + completion = token + suggestion.name.slice(tokenName.length); + } else { + completion = `${token.slice(0, 1)}${suggestion.name}`; + } + startPosition = position - 1; } else if (suggestion.type === 'account') { completion = `@${getState().getIn(['accounts', suggestion.id, 'acct'])}`; From 516f0ce131d510895286085a2dee7ae7b44829d9 Mon Sep 17 00:00:00 2001 From: diondiondion Date: Wed, 17 Dec 2025 15:38:46 +0100 Subject: [PATCH 829/853] [Glitch] Fix notifications page error in Tor browser Port 71af094f9735cea10cb0e2da92ebac1608393ebb to glitch-soc Signed-off-by: Claire --- .../components/status_action_bar/remove_quote_hint.module.css | 3 +++ .../glitch/components/status_action_bar/remove_quote_hint.tsx | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 app/javascript/flavours/glitch/components/status_action_bar/remove_quote_hint.module.css diff --git a/app/javascript/flavours/glitch/components/status_action_bar/remove_quote_hint.module.css b/app/javascript/flavours/glitch/components/status_action_bar/remove_quote_hint.module.css new file mode 100644 index 00000000000000..5045b6d1b95590 --- /dev/null +++ b/app/javascript/flavours/glitch/components/status_action_bar/remove_quote_hint.module.css @@ -0,0 +1,3 @@ +.inlineIcon { + vertical-align: middle; +} diff --git a/app/javascript/flavours/glitch/components/status_action_bar/remove_quote_hint.tsx b/app/javascript/flavours/glitch/components/status_action_bar/remove_quote_hint.tsx index ea08cba68890df..ab76ed6407d1ef 100644 --- a/app/javascript/flavours/glitch/components/status_action_bar/remove_quote_hint.tsx +++ b/app/javascript/flavours/glitch/components/status_action_bar/remove_quote_hint.tsx @@ -12,6 +12,8 @@ import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react'; import { Button } from '../button'; import { Icon } from '../icon'; +import classes from './remove_quote_hint.module.css'; + const DISMISSIBLE_BANNER_ID = 'notifications/remove_quote_hint'; /** @@ -92,7 +94,7 @@ export const RemoveQuoteHint: React.FC<{ id: 'status.more', defaultMessage: 'More', })} - style={{ verticalAlign: 'middle' }} + className={classes.inlineIcon} /> ), }} From 34dbea26a74d4b4955b8edbceb46c92b6c8c3dbf Mon Sep 17 00:00:00 2001 From: Echo Date: Wed, 17 Dec 2025 15:40:34 +0100 Subject: [PATCH 830/853] [Glitch] Remove rendering of custom emoji using the database Port dbc5af6641b06e19b2dbb36274bb647b7564d3f5 to glitch-soc Signed-off-by: Claire --- .../glitch/components/emoji/emoji.stories.tsx | 15 ++--- .../glitch/features/emoji/render.test.ts | 31 ++--------- .../flavours/glitch/features/emoji/render.ts | 55 +++++++++---------- 3 files changed, 38 insertions(+), 63 deletions(-) diff --git a/app/javascript/flavours/glitch/components/emoji/emoji.stories.tsx b/app/javascript/flavours/glitch/components/emoji/emoji.stories.tsx index fcc81db6c3a98e..e7d1887aa9a3a8 100644 --- a/app/javascript/flavours/glitch/components/emoji/emoji.stories.tsx +++ b/app/javascript/flavours/glitch/components/emoji/emoji.stories.tsx @@ -2,6 +2,9 @@ import type { ComponentProps } from 'react'; import type { Meta, StoryObj } from '@storybook/react-vite'; +import { customEmojiFactory } from '@/testing/factories'; + +import { CustomEmojiProvider } from './context'; import { Emoji } from './index'; type EmojiProps = ComponentProps & { @@ -34,7 +37,11 @@ const meta = { }, }, render(args) { - return ; + return ( + + + + ); }, } satisfies Meta; @@ -49,9 +56,3 @@ export const CustomEmoji: Story = { code: ':custom:', }, }; - -export const LegacyEmoji: Story = { - args: { - code: ':copyright:', - }, -}; diff --git a/app/javascript/flavours/glitch/features/emoji/render.test.ts b/app/javascript/flavours/glitch/features/emoji/render.test.ts index 782148b36e377c..dffebd1f8c576c 100644 --- a/app/javascript/flavours/glitch/features/emoji/render.test.ts +++ b/app/javascript/flavours/glitch/features/emoji/render.test.ts @@ -83,12 +83,8 @@ describe('stringToEmojiState', () => { }); }); - test('returns custom emoji state for valid custom emoji', () => { - expect(stringToEmojiState(':smile:')).toEqual({ - type: 'custom', - code: 'smile', - data: undefined, - }); + test('returns null for custom emoji without data', () => { + expect(stringToEmojiState(':smile:')).toBeNull(); }); test('returns custom emoji state with data when provided', () => { @@ -108,7 +104,6 @@ describe('stringToEmojiState', () => { test('returns null for invalid emoji strings', () => { expect(stringToEmojiState('notanemoji')).toBeNull(); - expect(stringToEmojiState(':invalid-emoji:')).toBeNull(); }); }); @@ -142,21 +137,13 @@ describe('loadEmojiDataToState', () => { }); }); - test('loads custom emoji data into state', async () => { - const dbCall = vi - .spyOn(db, 'loadCustomEmojiByShortcode') - .mockResolvedValueOnce(customEmojiFactory()); + test('returns null for custom emoji without data', async () => { const customState = { type: 'custom', code: 'smile', } as const satisfies EmojiStateCustom; const result = await loadEmojiDataToState(customState, 'en'); - expect(dbCall).toHaveBeenCalledWith('smile'); - expect(result).toEqual({ - type: 'custom', - code: 'smile', - data: customEmojiFactory(), - }); + expect(result).toBeNull(); }); test('loads unicode data using legacy shortcode', async () => { @@ -194,16 +181,6 @@ describe('loadEmojiDataToState', () => { expect(result).toBeNull(); }); - test('returns null if custom emoji not found in database', async () => { - vi.spyOn(db, 'loadCustomEmojiByShortcode').mockResolvedValueOnce(undefined); - const customState = { - type: 'custom', - code: 'smile', - } as const satisfies EmojiStateCustom; - const result = await loadEmojiDataToState(customState, 'en'); - expect(result).toBeNull(); - }); - test('retries loading emoji data once if initial load fails', async () => { const dbCall = vi .spyOn(db, 'loadEmojiByHexcode') diff --git a/app/javascript/flavours/glitch/features/emoji/render.ts b/app/javascript/flavours/glitch/features/emoji/render.ts index e00525fe0a110e..38bc7fd7e52129 100644 --- a/app/javascript/flavours/glitch/features/emoji/render.ts +++ b/app/javascript/flavours/glitch/features/emoji/render.ts @@ -5,7 +5,6 @@ import { EMOJI_TYPE_CUSTOM, } from './constants'; import { - loadCustomEmojiByShortcode, loadEmojiByHexcode, loadLegacyShortcodesByShortcode, LocaleNotLoadedError, @@ -80,7 +79,7 @@ export function tokenizeText(text: string): TokenizedText { export function stringToEmojiState( code: string, customEmoji: ExtraCustomEmojiMap = {}, -): EmojiState | null { +): EmojiStateUnicode | Required | null { if (isUnicodeEmoji(code)) { return { type: EMOJI_TYPE_UNICODE, @@ -90,11 +89,13 @@ export function stringToEmojiState( if (isCustomEmoji(code)) { const shortCode = code.slice(1, -1); - return { - type: EMOJI_TYPE_CUSTOM, - code: shortCode, - data: customEmoji[shortCode], - }; + if (customEmoji[shortCode]) { + return { + type: EMOJI_TYPE_CUSTOM, + code: shortCode, + data: customEmoji[shortCode], + }; + } } return null; @@ -115,33 +116,29 @@ export async function loadEmojiDataToState( return state; } + // Don't try to load data for custom emoji. + if (state.type === EMOJI_TYPE_CUSTOM) { + return null; + } + // First, try to load the data from IndexedDB. try { const legacyCode = await loadLegacyShortcodesByShortcode(state.code); // This is duplicative, but that's because TS can't distinguish the state type easily. - if (state.type === EMOJI_TYPE_UNICODE || legacyCode) { - const data = await loadEmojiByHexcode( - legacyCode?.hexcode ?? state.code, - locale, - ); - if (data) { - return { - ...state, - type: EMOJI_TYPE_UNICODE, - data, - // TODO: Use CLDR shortcodes when the picker supports them. - shortcode: legacyCode?.shortcodes.at(0), - }; - } - } else { - const data = await loadCustomEmojiByShortcode(state.code); - if (data) { - return { - ...state, - data, - }; - } + const data = await loadEmojiByHexcode( + legacyCode?.hexcode ?? state.code, + locale, + ); + if (data) { + return { + ...state, + type: EMOJI_TYPE_UNICODE, + data, + // TODO: Use CLDR shortcodes when the picker supports them. + shortcode: legacyCode?.shortcodes.at(0), + }; } + // If not found, assume it's not an emoji and return null. log( 'Could not find emoji %s of type %s for locale %s', From 392a241637422942f4e70f83796f8a0f4a45d839 Mon Sep 17 00:00:00 2001 From: diondiondion Date: Wed, 17 Dec 2025 15:42:07 +0100 Subject: [PATCH 831/853] [Glitch] Improve search menu keyboard navigation Port c4a760d6ba4394f07d1147259ebf280b0bade33f to glitch-soc Signed-off-by: Claire --- .../features/compose/components/search.tsx | 77 +++++++++++++------ 1 file changed, 54 insertions(+), 23 deletions(-) diff --git a/app/javascript/flavours/glitch/features/compose/components/search.tsx b/app/javascript/flavours/glitch/features/compose/components/search.tsx index f9aebd58c77408..f4eeaacf20f273 100644 --- a/app/javascript/flavours/glitch/features/compose/components/search.tsx +++ b/app/javascript/flavours/glitch/features/compose/components/search.tsx @@ -1,4 +1,11 @@ -import { useCallback, useState, useRef, useEffect, useMemo } from 'react'; +import { + useCallback, + useState, + useRef, + useEffect, + useMemo, + useId, +} from 'react'; import { defineMessages, @@ -432,12 +439,17 @@ export const Search: React.FC<{ switch (e.key) { case 'Escape': e.preventDefault(); - unfocus(); + searchInputRef.current?.focus(); + setExpanded(false); break; case 'ArrowDown': e.preventDefault(); + if (!expanded) { + setExpanded(true); + } + if (navigableOptions.length > 0) { setSelectedOption( Math.min(selectedOption + 1, navigableOptions.length - 1), @@ -476,10 +488,10 @@ export const Search: React.FC<{ break; } }, - [unfocus, navigableOptions, selectedOption, submit, value], + [expanded, navigableOptions, selectedOption, submit, value], ); - const handleFocus = useCallback(() => { + const handleInputFocus = useCallback(() => { setExpanded(true); setSelectedOption(-1); @@ -495,10 +507,16 @@ export const Search: React.FC<{ } }, [setExpanded, setSelectedOption, singleColumn]); - const handleBlur = useCallback(() => { + const handleInputBlur = useCallback(() => { setSelectedOption(-1); }, [setSelectedOption]); + const getOptionFocusHandler = useCallback((index: number) => { + return () => { + setSelectedOption(index); + }; + }, []); + const formRef = useRef(null); useEffect(() => { @@ -526,6 +544,8 @@ export const Search: React.FC<{ return () => null; }, [expanded]); + const searchOptionsHeading = useId(); + return ( -
+ {/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions */} +
{!hasValue && ( <>

@@ -565,6 +592,7 @@ export const Search: React.FC<{ tabIndex={0} role='button' onMouseDown={action} + onFocus={getOptionFocusHandler(i)} className={classNames( 'search__popout__menu__item search__popout__menu__item--flex', { selected: selectedOption === i }, @@ -606,6 +634,7 @@ export const Search: React.FC<{ - ))} + {searchOptions.map(({ key, label, action }, i) => { + const currentIndex = (quickActions.length || recent.length) + i; + return ( + + ); + })}

) : (
From 177d3c59d0be8ed552c19980166532f6ec2e3dbc Mon Sep 17 00:00:00 2001 From: Echo Date: Wed, 17 Dec 2025 15:58:22 +0100 Subject: [PATCH 832/853] [Glitch] Emoji: Refresh custom emoji on new Port 3d55dcdf7fbbebe3006ef86e765e9fc2455d34e1 to glitch-soc Signed-off-by: Claire --- .../flavours/glitch/actions/importer/emoji.ts | 22 ++++++ .../flavours/glitch/actions/importer/index.js | 9 +++ .../glitch/actions/importer/normalizer.js | 6 ++ .../glitch/features/emoji/database.test.ts | 17 ++++- .../glitch/features/emoji/database.ts | 24 +++++- .../flavours/glitch/features/emoji/index.ts | 75 ++++++++++++------- .../flavours/glitch/features/emoji/loader.ts | 2 +- 7 files changed, 123 insertions(+), 32 deletions(-) create mode 100644 app/javascript/flavours/glitch/actions/importer/emoji.ts diff --git a/app/javascript/flavours/glitch/actions/importer/emoji.ts b/app/javascript/flavours/glitch/actions/importer/emoji.ts new file mode 100644 index 00000000000000..ef834ab50fe54d --- /dev/null +++ b/app/javascript/flavours/glitch/actions/importer/emoji.ts @@ -0,0 +1,22 @@ +import type { ApiCustomEmojiJSON } from '@/flavours/glitch/api_types/custom_emoji'; +import { loadCustomEmoji } from '@/flavours/glitch/features/emoji'; + +export async function importCustomEmoji(emojis: ApiCustomEmojiJSON[]) { + if (emojis.length === 0) { + return; + } + + // First, check if we already have them all. + const { searchCustomEmojisByShortcodes, clearEtag } = + await import('@/flavours/glitch/features/emoji/database'); + + const existingEmojis = await searchCustomEmojisByShortcodes( + emojis.map((emoji) => emoji.shortcode), + ); + + // If there's a mismatch, re-import all custom emojis. + if (existingEmojis.length < emojis.length) { + await clearEtag('custom'); + await loadCustomEmoji(); + } +} diff --git a/app/javascript/flavours/glitch/actions/importer/index.js b/app/javascript/flavours/glitch/actions/importer/index.js index 1de479c820e742..a25df5705e17a4 100644 --- a/app/javascript/flavours/glitch/actions/importer/index.js +++ b/app/javascript/flavours/glitch/actions/importer/index.js @@ -1,6 +1,7 @@ import { createPollFromServerJSON } from 'flavours/glitch/models/poll'; import { importAccounts } from './accounts'; +import { importCustomEmoji } from './emoji'; import { normalizeStatus } from './normalizer'; import { importPolls } from './polls'; @@ -39,6 +40,10 @@ export function importFetchedAccounts(accounts) { if (account.moved) { processAccount(account.moved); } + + if (account.emojis && account.username === account.acct) { + importCustomEmoji(account.emojis); + } } accounts.forEach(processAccount); @@ -80,6 +85,10 @@ export function importFetchedStatuses(statuses, options = {}) { if (status.card) { status.card.authors.forEach(author => author.account && pushUnique(accounts, author.account)); } + + if (status.emojis && status.account.username === status.account.acct) { + importCustomEmoji(status.emojis); + } } statuses.forEach(processStatus); diff --git a/app/javascript/flavours/glitch/actions/importer/normalizer.js b/app/javascript/flavours/glitch/actions/importer/normalizer.js index ca26b9e055fda3..366375c3f634f3 100644 --- a/app/javascript/flavours/glitch/actions/importer/normalizer.js +++ b/app/javascript/flavours/glitch/actions/importer/normalizer.js @@ -2,6 +2,8 @@ import escapeTextContentForBrowser from 'escape-html'; import { autoHideCW } from '../../utils/content_warning'; +import { importCustomEmoji } from './emoji'; + const domParser = new DOMParser(); export function searchTextFromRawStatus (status) { @@ -143,5 +145,9 @@ export function normalizeAnnouncement(announcement) { normalAnnouncement.contentHtml = normalAnnouncement.content; + if (normalAnnouncement.emojis) { + importCustomEmoji(normalAnnouncement.emojis); + } + return normalAnnouncement; } diff --git a/app/javascript/flavours/glitch/features/emoji/database.test.ts b/app/javascript/flavours/glitch/features/emoji/database.test.ts index 5931a238eabbd2..6b6ea952b74cdc 100644 --- a/app/javascript/flavours/glitch/features/emoji/database.test.ts +++ b/app/javascript/flavours/glitch/features/emoji/database.test.ts @@ -43,11 +43,26 @@ describe('emoji database', () => { describe('putCustomEmojiData', () => { test('loads custom emoji into indexedDB', async () => { const { db } = await testGet(); - await putCustomEmojiData([customEmojiFactory()]); + await putCustomEmojiData({ emojis: [customEmojiFactory()] }); await expect(db.get('custom', 'custom')).resolves.toEqual( customEmojiFactory(), ); }); + + test('clears existing custom emoji if specified', async () => { + const { db } = await testGet(); + await putCustomEmojiData({ + emojis: [customEmojiFactory({ shortcode: 'emoji1' })], + }); + await putCustomEmojiData({ + emojis: [customEmojiFactory({ shortcode: 'emoji2' })], + clear: true, + }); + await expect(db.get('custom', 'emoji1')).resolves.toBeUndefined(); + await expect(db.get('custom', 'emoji2')).resolves.toEqual( + customEmojiFactory({ shortcode: 'emoji2' }), + ); + }); }); describe('putLegacyShortcodes', () => { diff --git a/app/javascript/flavours/glitch/features/emoji/database.ts b/app/javascript/flavours/glitch/features/emoji/database.ts index 2e8de712217570..9e03b53d3c6ad8 100644 --- a/app/javascript/flavours/glitch/features/emoji/database.ts +++ b/app/javascript/flavours/glitch/features/emoji/database.ts @@ -161,11 +161,26 @@ export async function putEmojiData(emojis: UnicodeEmojiData[], locale: Locale) { await trx.done; } -export async function putCustomEmojiData(emojis: CustomEmojiData[]) { +export async function putCustomEmojiData({ + emojis, + clear = false, +}: { + emojis: CustomEmojiData[]; + clear?: boolean; +}) { const db = await loadDB(); const trx = db.transaction('custom', 'readwrite'); + + // When importing from the API, clear everything first. + if (clear) { + await trx.store.clear(); + log('Cleared existing custom emojis in database'); + } + await Promise.all(emojis.map((emoji) => trx.store.put(emoji))); await trx.done; + + log('Imported %d custom emojis into database', emojis.length); } export async function putLegacyShortcodes(shortcodes: ShortcodesDataset) { @@ -188,6 +203,13 @@ export async function putLatestEtag(etag: string, localeString: string) { await db.put('etags', etag, locale); } +export async function clearEtag(localeString: string) { + const locale = toSupportedLocaleOrCustom(localeString); + const db = await loadDB(); + await db.delete('etags', locale); + log('Cleared etag for %s', locale); +} + export async function loadEmojiByHexcode( hexcode: string, localeString: string, diff --git a/app/javascript/flavours/glitch/features/emoji/index.ts b/app/javascript/flavours/glitch/features/emoji/index.ts index 4a04f99bed2a0b..44c84db3218561 100644 --- a/app/javascript/flavours/glitch/features/emoji/index.ts +++ b/app/javascript/flavours/glitch/features/emoji/index.ts @@ -3,7 +3,6 @@ import type { Locale } from 'emojibase'; import { initialState } from '@/flavours/glitch/initial_state'; import type { EMOJI_DB_NAME_SHORTCODES, EMOJI_TYPE_CUSTOM } from './constants'; -import { importLegacyShortcodes, localeToShortcodesPath } from './loader'; import { toSupportedLocale } from './locale'; import type { LocaleOrCustom } from './types'; import { emojiLogger } from './utils'; @@ -16,48 +15,54 @@ let worker: Worker | null = null; const log = emojiLogger('index'); -const WORKER_TIMEOUT = 1_000; // 1 second +// This is too short, but better to fallback quickly than wait. +const WORKER_TIMEOUT = 1_000; export function initializeEmoji() { log('initializing emojis'); + + // Create a temp worker, and assign it to the module-level worker once we know it's ready. + let tempWorker: Worker | null = null; if (!worker && 'Worker' in window) { try { - worker = new EmojiWorker(); + tempWorker = new EmojiWorker(); } catch (err) { console.warn('Error creating web worker:', err); } } - if (worker) { - const timeoutId = setTimeout(() => { - log('worker is not ready after timeout'); - worker = null; - void fallbackLoad(); - }, WORKER_TIMEOUT); - worker.addEventListener('message', (event: MessageEvent) => { - const { data: message } = event; - if (message === 'ready') { - log('worker ready, loading data'); - clearTimeout(timeoutId); - messageWorker('custom'); - messageWorker('shortcodes'); - void loadEmojiLocale(userLocale); - } else { - log('got worker message: %s', message); - } - }); - } else { + if (!tempWorker) { void fallbackLoad(); + return; } + + const timeoutId = setTimeout(() => { + log('worker is not ready after timeout'); + void fallbackLoad(); + }, WORKER_TIMEOUT); + + tempWorker.addEventListener('message', (event: MessageEvent) => { + const { data: message } = event; + + worker ??= tempWorker; + + if (message === 'ready') { + log('worker ready, loading data'); + clearTimeout(timeoutId); + messageWorker('shortcodes'); + void loadCustomEmoji(); + void loadEmojiLocale(userLocale); + } else { + log('got worker message: %s', message); + } + }); } async function fallbackLoad() { log('falling back to main thread for loading'); - const { importCustomEmojiData } = await import('./loader'); - const emojis = await importCustomEmojiData(); - if (emojis) { - log('loaded %d custom emojis', emojis.length); - } + + await loadCustomEmoji(); + const { importLegacyShortcodes } = await import('./loader'); const shortcodes = await importLegacyShortcodes(); if (shortcodes.length) { log('loaded %d legacy shortcodes', shortcodes.length); @@ -67,11 +72,11 @@ async function fallbackLoad() { async function loadEmojiLocale(localeString: string) { const locale = toSupportedLocale(localeString); - const { importEmojiData, localeToEmojiPath: localeToPath } = + const { importEmojiData, localeToEmojiPath, localeToShortcodesPath } = await import('./loader'); if (worker) { - const path = await localeToPath(locale); + const path = await localeToEmojiPath(locale); const shortcodesPath = await localeToShortcodesPath(locale); log('asking worker to load locale %s from %s', locale, path); messageWorker(locale, path, shortcodesPath); @@ -83,6 +88,18 @@ async function loadEmojiLocale(localeString: string) { } } +export async function loadCustomEmoji() { + if (worker) { + messageWorker('custom'); + } else { + const { importCustomEmojiData } = await import('./loader'); + const emojis = await importCustomEmojiData(); + if (emojis && emojis.length > 0) { + log('loaded %d custom emojis', emojis.length); + } + } +} + function messageWorker( locale: typeof EMOJI_TYPE_CUSTOM | typeof EMOJI_DB_NAME_SHORTCODES, ): void; diff --git a/app/javascript/flavours/glitch/features/emoji/loader.ts b/app/javascript/flavours/glitch/features/emoji/loader.ts index 18c04dc64d5501..51fd2eafaf0fe1 100644 --- a/app/javascript/flavours/glitch/features/emoji/loader.ts +++ b/app/javascript/flavours/glitch/features/emoji/loader.ts @@ -76,7 +76,7 @@ export async function importCustomEmojiData() { if (!emojis) { return; } - await putCustomEmojiData(emojis); + await putCustomEmojiData({ emojis, clear: true }); return emojis; } From 830ffbe2da9c8895beaa4fd9b358d26c79dd8e3c Mon Sep 17 00:00:00 2001 From: diondiondion Date: Thu, 18 Dec 2025 09:58:06 +0100 Subject: [PATCH 833/853] Remove required field markers from unclearable fields in user preferences (#37291) --- app/views/settings/preferences/appearance/show.html.haml | 9 ++++++--- .../settings/preferences/notifications/show.html.haml | 3 ++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/views/settings/preferences/appearance/show.html.haml b/app/views/settings/preferences/appearance/show.html.haml index 45a27eb4822a5d..911a544ddbcdb8 100644 --- a/app/views/settings/preferences/appearance/show.html.haml +++ b/app/views/settings/preferences/appearance/show.html.haml @@ -29,7 +29,8 @@ include_blank: false, label_method: ->(theme) { I18n.t("themes.#{theme}", default: theme) }, label: I18n.t('simple_form.labels.defaults.setting_theme'), - wrapper: :with_label + wrapper: :with_label, + required: false .fields-group = f.simple_fields_for :settings, current_user.settings do |ff| @@ -39,7 +40,8 @@ hint: I18n.t('simple_form.hints.defaults.setting_emoji_style'), label: I18n.t('simple_form.labels.defaults.setting_emoji_style'), label_method: ->(emoji_style) { I18n.t("emoji_styles.#{emoji_style}", default: emoji_style) }, - wrapper: :with_label + wrapper: :with_label, + required: false - unless I18n.locale == :en .flash-message.translation-prompt @@ -87,7 +89,8 @@ item_wrapper_tag: 'li', label_method: ->(item) { t("simple_form.hints.defaults.setting_display_media_#{item}") }, label: I18n.t('simple_form.labels.defaults.setting_display_media'), - wrapper: :with_floating_label + wrapper: :with_floating_label, + required: false .fields-group = ff.input :'web.use_blurhash', diff --git a/app/views/settings/preferences/notifications/show.html.haml b/app/views/settings/preferences/notifications/show.html.haml index 08bcc32e9b47e3..2efbb50bc37aee 100644 --- a/app/views/settings/preferences/notifications/show.html.haml +++ b/app/views/settings/preferences/notifications/show.html.haml @@ -40,4 +40,5 @@ include_blank: false, label_method: ->(setting) { I18n.t("simple_form.labels.notification_emails.software_updates.#{setting}") }, label: I18n.t('simple_form.labels.notification_emails.software_updates.label'), - wrapper: :with_label + wrapper: :with_label, + required: false From ed2a8c32ce7beb62d8e729f1f543776ac3b312e9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 18 Dec 2025 10:20:07 +0100 Subject: [PATCH 834/853] New Crowdin Translations (automated) (#37293) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/es-AR.json | 3 + app/javascript/mastodon/locales/eu.json | 5 +- app/javascript/mastodon/locales/ga.json | 3 + app/javascript/mastodon/locales/gl.json | 3 + app/javascript/mastodon/locales/hu.json | 7 ++ app/javascript/mastodon/locales/is.json | 10 +- app/javascript/mastodon/locales/ja.json | 5 + app/javascript/mastodon/locales/pt-BR.json | 3 + app/javascript/mastodon/locales/tr.json | 3 + config/locales/be.yml | 1 + config/locales/da.yml | 1 + config/locales/de.yml | 1 + config/locales/el.yml | 1 + config/locales/en-GB.yml | 1 + config/locales/es-AR.yml | 3 +- config/locales/es-MX.yml | 1 + config/locales/eu.yml | 131 +++++++++++++++++++++ config/locales/fi.yml | 1 + config/locales/fr-CA.yml | 1 + config/locales/fr.yml | 1 + config/locales/ga.yml | 1 + config/locales/gl.yml | 1 + config/locales/hu.yml | 1 + config/locales/is.yml | 3 +- config/locales/it.yml | 1 + config/locales/pt-PT.yml | 1 + config/locales/simple_form.be.yml | 2 + config/locales/simple_form.da.yml | 2 + config/locales/simple_form.de.yml | 2 + config/locales/simple_form.el.yml | 2 + config/locales/simple_form.en-GB.yml | 2 + config/locales/simple_form.es-AR.yml | 2 + config/locales/simple_form.es-MX.yml | 2 + config/locales/simple_form.eu.yml | 48 ++++++++ config/locales/simple_form.fi.yml | 1 + config/locales/simple_form.fr-CA.yml | 2 + config/locales/simple_form.fr.yml | 2 + config/locales/simple_form.ga.yml | 2 + config/locales/simple_form.gl.yml | 2 + config/locales/simple_form.hu.yml | 2 + config/locales/simple_form.is.yml | 2 + config/locales/simple_form.it.yml | 2 + config/locales/simple_form.pt-PT.yml | 2 + config/locales/simple_form.sq.yml | 2 + config/locales/simple_form.sv.yml | 1 + config/locales/simple_form.vi.yml | 2 + config/locales/simple_form.zh-TW.yml | 2 + config/locales/sq.yml | 1 + config/locales/sv.yml | 1 + config/locales/vi.yml | 1 + config/locales/zh-TW.yml | 1 + 51 files changed, 275 insertions(+), 8 deletions(-) diff --git a/app/javascript/mastodon/locales/es-AR.json b/app/javascript/mastodon/locales/es-AR.json index 51fe6e89956f9c..65c8e7f6411fbb 100644 --- a/app/javascript/mastodon/locales/es-AR.json +++ b/app/javascript/mastodon/locales/es-AR.json @@ -121,6 +121,7 @@ "annual_report.nav_item.badge": "Nueva", "annual_report.shared_page.donate": "Donar", "annual_report.shared_page.footer": "Generado con {heart} por el equipo de Mastodon", + "annual_report.shared_page.footer_server_info": "{username} usa {domain}, una de las tantas comunidades de Mastodon.", "annual_report.summary.archetype.booster.desc_public": "{name} permaneció al acecho en busca de mensajes para adherir, apuntando a otros creadores con perfecta puntería.", "annual_report.summary.archetype.booster.desc_self": "Permaneciste al acecho en busca de mensajes para adherir, apuntando a otros creadores con perfecta puntería.", "annual_report.summary.archetype.booster.name": "El arquero", @@ -440,6 +441,8 @@ "follow_suggestions.who_to_follow": "A quién seguir", "followed_tags": "Etiquetas seguidas", "footer.about": "Información", + "footer.about_mastodon": "Acerca de Mastodon", + "footer.about_server": "Acerca de {domain}", "footer.about_this_server": "Información", "footer.directory": "Directorio de perfiles", "footer.get_app": "Conseguí la aplicación", diff --git a/app/javascript/mastodon/locales/eu.json b/app/javascript/mastodon/locales/eu.json index be79158d982492..8b6699864bf952 100644 --- a/app/javascript/mastodon/locales/eu.json +++ b/app/javascript/mastodon/locales/eu.json @@ -121,6 +121,7 @@ "annual_report.nav_item.badge": "Berria", "annual_report.shared_page.donate": "Egin dohaintza", "annual_report.shared_page.footer": "Mastodonen taldeak {heart} sortua", + "annual_report.shared_page.footer_server_info": "{username}(e)k {domain} erabiltzen du, Mastodonek bultzatutako komunitate ugarietako bat.", "annual_report.summary.archetype.booster.desc_public": "{name}(e)k promozionatzeko argitalpenen bila jarraitu zuen, beste sortzaile batzuk punteria perfektuarekin anplifikatuz.", "annual_report.summary.archetype.booster.desc_self": "Bultzatu beharreko argitalpenen zelatan egon zinen, punteria perfektua zuten beste sortzaile batzuk anplifikatuz.", "annual_report.summary.archetype.booster.name": "Arkularia", @@ -440,6 +441,8 @@ "follow_suggestions.who_to_follow": "Zein jarraitu", "followed_tags": "Jarraitutako traolak", "footer.about": "Honi buruz", + "footer.about_mastodon": "Mastodoni buruz", + "footer.about_server": "{domain}-i buruz", "footer.about_this_server": "Honi buruz", "footer.directory": "Profil-direktorioa", "footer.get_app": "Eskuratu aplikazioa", @@ -788,7 +791,7 @@ "privacy.quote.limited": "{visibility}, aipuak mugatuta", "privacy.unlisted.additional": "Aukera honek publiko modua bezala funtzionatzen du, baina argitalpena ez da agertuko zuzeneko jarioetan edo traoletan, \"Arakatu\" atalean edo Mastodonen bilaketan, nahiz eta kontua zabaltzeko onartu duzun.", "privacy.unlisted.long": "Ezkutatuta Mastodon bilaketen emaitzetatik, joeretatik, eta denbora-lerro publikoetatik", - "privacy.unlisted.short": "Deiadar urrikoa", + "privacy.unlisted.short": "Ikusgarritasun mugatua", "privacy_policy.last_updated": "Azkenengo eguneraketa {date}", "privacy_policy.title": "Pribatutasun politika", "quote_error.edit": "Aipuak ezin dira gehitu bidalketa bat editatzean.", diff --git a/app/javascript/mastodon/locales/ga.json b/app/javascript/mastodon/locales/ga.json index 489616943be056..f1c51200ff30b3 100644 --- a/app/javascript/mastodon/locales/ga.json +++ b/app/javascript/mastodon/locales/ga.json @@ -121,6 +121,7 @@ "annual_report.nav_item.badge": "Nua", "annual_report.shared_page.donate": "Tabhair Síntiús", "annual_report.shared_page.footer": "Gineadh le {heart} ag foireann Mastodon", + "annual_report.shared_page.footer_server_info": "Úsáideann {username} {domain}, ceann de go leor pobail atá faoi thiomáint ag Mastodon.", "annual_report.summary.archetype.booster.desc_public": "D’fhan {name} ag cuardach postálacha le cur chun cinn, ag cur le cruthaitheoirí eile le cuspóir foirfe.", "annual_report.summary.archetype.booster.desc_self": "D’fhan tú ag cuardach postálacha le borradh a chur fúthu, ag cur le cruthaitheoirí eile le cuspóir foirfe.", "annual_report.summary.archetype.booster.name": "An Saighdeoir", @@ -440,6 +441,8 @@ "follow_suggestions.who_to_follow": "Cé le leanúint", "followed_tags": "Hashtags le leanúint", "footer.about": "Maidir le", + "footer.about_mastodon": "Maidir le Mastodon", + "footer.about_server": "Maidir le {domain}", "footer.about_this_server": "Maidir", "footer.directory": "Eolaire próifílí", "footer.get_app": "Faigh an aip", diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json index b68b33b4ec2fa6..d707ba57100b2b 100644 --- a/app/javascript/mastodon/locales/gl.json +++ b/app/javascript/mastodon/locales/gl.json @@ -121,6 +121,7 @@ "annual_report.nav_item.badge": "Novidade", "annual_report.shared_page.donate": "Doar", "annual_report.shared_page.footer": "Creado con {heart} polo equipo de Mastodon", + "annual_report.shared_page.footer_server_info": "{username} utiliza {domain}, unha das moitas comunidades de Mastodon.", "annual_report.summary.archetype.booster.desc_public": "{name} á caza de publicacións para promover, dando relevancia a outras creadoras.", "annual_report.summary.archetype.booster.desc_self": "Á caza de publicacións para promover, dando relevancia a outras creadoras.", "annual_report.summary.archetype.booster.name": "Arqueire", @@ -440,6 +441,8 @@ "follow_suggestions.who_to_follow": "A quen seguir", "followed_tags": "Cancelos seguidos", "footer.about": "Sobre", + "footer.about_mastodon": "Sobre Mastodon", + "footer.about_server": "Sobre {domain}", "footer.about_this_server": "Sobre", "footer.directory": "Directorio de perfís", "footer.get_app": "Descarga a app", diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json index 755dbd1bede1b5..c21b6016f08e46 100644 --- a/app/javascript/mastodon/locales/hu.json +++ b/app/javascript/mastodon/locales/hu.json @@ -114,11 +114,14 @@ "alt_text_modal.done": "Kész", "announcement.announcement": "Közlemény", "annual_report.announcement.action_build": "Saját Wrapstodon összeállítása", + "annual_report.announcement.action_dismiss": "Nem, köszönöm", "annual_report.announcement.action_view": "Saját Wrapstodon megtekintése", "annual_report.announcement.description": "Fedezz fel többet a Mastodonon az elmúlt évben végzett tevékenységeidről.", "annual_report.announcement.title": "A Wrapstodon {year} megérkezett", + "annual_report.nav_item.badge": "Új", "annual_report.shared_page.donate": "Adományozás", "annual_report.shared_page.footer": "A Mastodon által {heart}-tel előállítva", + "annual_report.shared_page.footer_server_info": "{username} a {domain} domaint használja, amely a Mastodon által működtetett számos közösség egyike.", "annual_report.summary.archetype.booster.desc_public": "{name} megtolandó bejegyzésekre vadászott, tökéletes célzással felerősítve mások üzeneteit.", "annual_report.summary.archetype.booster.desc_self": "Megtolandó bejegyzésekre vadásztál, tökéletes célzással felerősítve mások üzeneteit.", "annual_report.summary.archetype.booster.name": "Az íjász", @@ -140,6 +143,7 @@ "annual_report.summary.archetype.title_public": "{name} archetípusa", "annual_report.summary.archetype.title_self": "Saját archetípus", "annual_report.summary.close": "Bezárás", + "annual_report.summary.copy_link": "Hivatkozás másolása", "annual_report.summary.followers.new_followers": "{count, plural, one {új követő} other {új követők}}", "annual_report.summary.highlighted_post.boost_count": "Ez a bejegyzés {count, plural, one {egyszer} other {# alkalommal}} volt megtolva.", "annual_report.summary.highlighted_post.favourite_count": "Ez a bejegyzés {count, plural, one {egyszer} other {# alkalommal}} volt kedvencnek jelölve.", @@ -152,6 +156,7 @@ "annual_report.summary.new_posts.new_posts": "új bejegyzés", "annual_report.summary.percentile.text": "Ezzel a csúcs{domain} felhasználó között vagy.", "annual_report.summary.percentile.we_wont_tell_bernie": "Nem mondjuk el Bernie-nek.", + "annual_report.summary.share_elsewhere": "Megosztás máshol", "annual_report.summary.share_message": "{archetype} lett az archetípusom!", "annual_report.summary.share_on_mastodon": "Megosztás a Mastodonon", "attachments_list.unprocessed": "(feldolgozatlan)", @@ -436,6 +441,8 @@ "follow_suggestions.who_to_follow": "Kit érdemes követni", "followed_tags": "Követett hashtagek", "footer.about": "Névjegy", + "footer.about_mastodon": "A Mastodonról", + "footer.about_server": "A {domain} domainről", "footer.about_this_server": "Névjegy", "footer.directory": "Profiltár", "footer.get_app": "Alkalmazás beszerzése", diff --git a/app/javascript/mastodon/locales/is.json b/app/javascript/mastodon/locales/is.json index d83074a08a9276..a9b8011b4aee01 100644 --- a/app/javascript/mastodon/locales/is.json +++ b/app/javascript/mastodon/locales/is.json @@ -113,11 +113,11 @@ "alt_text_modal.describe_for_people_with_visual_impairments": "Lýstu þessu fyrir fólk með skerta sjón…", "alt_text_modal.done": "Lokið", "announcement.announcement": "Auglýsing", - "annual_report.announcement.action_build": "Byggja Wrapstodon fyrir mig", + "annual_report.announcement.action_build": "Búa til ársuppgjör fyrir mig", "annual_report.announcement.action_dismiss": "Nei takk", - "annual_report.announcement.action_view": "Skoða minn Wrapstodon", + "annual_report.announcement.action_view": "Skoða ársuppgjörið mitt", "annual_report.announcement.description": "Skoðaðu meira um virkni þína á Mastodon á síðastliðnu ári.", - "annual_report.announcement.title": "Wrapstodon {year} er komið", + "annual_report.announcement.title": "Ársuppgjörið {year} er komið", "annual_report.nav_item.badge": "Nýtt", "annual_report.shared_page.donate": "Styrkja", "annual_report.shared_page.footer": "{heart}-kveðjur frá Mastodon-teyminu", @@ -638,8 +638,8 @@ "notification.admin.report_statuses_other": "{name} kærði {target}", "notification.admin.sign_up": "{name} skráði sig", "notification.admin.sign_up.name_and_others": "{name} og {count, plural, one {# í viðbót hefur} other {# í viðbót hafa}} skráð sig", - "notification.annual_report.message": "{year} á #Wrapstodon bíður! Afhjúpaðu hvað bar hæst á árinu og minnistæðustu augnablikin á Mastodon!", - "notification.annual_report.view": "Skoða #Wrapstodon", + "notification.annual_report.message": "Ársuppgjörið {year} bíður á #Wrapstodon! Afhjúpaðu hvað bar hæst á árinu og minnistæðustu augnablikin á Mastodon!", + "notification.annual_report.view": "Skoða ársuppgjör á #Wrapstodon", "notification.favourite": "{name} setti færsluna þína í eftirlæti", "notification.favourite.name_and_others_with_link": "{name} og {count, plural, one {# í viðbót hefur} other {# í viðbót hafa}} sett færsluna þína í eftirlæti", "notification.favourite_pm": "{name} setti í eftirlæti færslu í einkaspjalli þar sem þú minntist á viðkomandi", diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json index 428009b29825cb..342cc4fc323727 100644 --- a/app/javascript/mastodon/locales/ja.json +++ b/app/javascript/mastodon/locales/ja.json @@ -113,8 +113,13 @@ "alt_text_modal.describe_for_people_with_visual_impairments": "目が不自由な方のために説明してください…", "alt_text_modal.done": "完了", "announcement.announcement": "お知らせ", + "annual_report.summary.followers.new_followers": "{count, plural, other {新しいフォロワー}}", + "annual_report.summary.highlighted_post.boost_count": "この投稿は {count, plural, other {# 回}}ブーストされました。", + "annual_report.summary.highlighted_post.favourite_count": "この投稿は {count, plural, other {# 回}}お気に入りされました。", + "annual_report.summary.highlighted_post.title": "最も人気のある投稿", "annual_report.summary.most_used_app.most_used_app": "最も使用されているアプリ", "annual_report.summary.most_used_hashtag.most_used_hashtag": "最も使用されたハッシュタグ", + "annual_report.summary.most_used_hashtag.used_count": "あなたはこのハッシュタグを {count, plural, other {# 件の投稿}}に含めました。", "annual_report.summary.new_posts.new_posts": "新しい投稿", "annual_report.summary.percentile.text": "{domain}で 上位に入ります!", "annual_report.summary.percentile.we_wont_tell_bernie": "バー二ーには秘密にしておくよ。", diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json index cb5c7028880c88..8fdd502accb36a 100644 --- a/app/javascript/mastodon/locales/pt-BR.json +++ b/app/javascript/mastodon/locales/pt-BR.json @@ -121,6 +121,7 @@ "annual_report.nav_item.badge": "Novo", "annual_report.shared_page.donate": "Doe", "annual_report.shared_page.footer": "Criado com {heart} pela equipe do Mastodon", + "annual_report.shared_page.footer_server_info": "{username} utiliza {domain}, uma das várias comunidades baseadas no Mastodon.", "annual_report.summary.archetype.booster.desc_public": "{name} se manteve na caça por publicações para impulsionar, amplificando outros criadores com uma mira perfeita.", "annual_report.summary.archetype.booster.desc_self": "Você se manteve na caça por publicações para impulsionar, amplificando outros criadores com uma mira perfeita.", "annual_report.summary.archetype.booster.name": "O Arqueiro", @@ -440,6 +441,8 @@ "follow_suggestions.who_to_follow": "Quem seguir", "followed_tags": "Hashtags seguidas", "footer.about": "Sobre", + "footer.about_mastodon": "Sobre o mastodon", + "footer.about_server": "Sobre {domain}", "footer.about_this_server": "Sobre", "footer.directory": "Diretório de perfis", "footer.get_app": "Baixe o app", diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json index fed0220a7be8dd..98291db5c0d051 100644 --- a/app/javascript/mastodon/locales/tr.json +++ b/app/javascript/mastodon/locales/tr.json @@ -120,6 +120,7 @@ "annual_report.announcement.title": "{year} Wrapstodon'u yayında", "annual_report.shared_page.donate": "Bağış Yap", "annual_report.shared_page.footer": "Mastodon ekibi tarafından {heart} ile oluşturulmuştur", + "annual_report.shared_page.footer_server_info": "{username}, Mastodon tarafından desteklenen birçok topluluktan biri olan {domain} kullanıyor.", "annual_report.summary.archetype.booster.desc_public": "{name} mükemmel bir hedefle diğer içerik üreticilerini desteklemek için paylaşımları yeniden yayınlamaya devam etti.", "annual_report.summary.archetype.booster.desc_self": "Mükemmel bir hedefle diğer içerik üreticilerini desteklemek için paylaşımları yeniden yayınlamaya devam ettin.", "annual_report.summary.archetype.booster.name": "Okçu", @@ -439,6 +440,8 @@ "follow_suggestions.who_to_follow": "Takip edebileceklerin", "followed_tags": "Takip edilen etiketler", "footer.about": "Hakkında", + "footer.about_mastodon": "Mastodon Hakkında", + "footer.about_server": "{domain} Hakkında", "footer.about_this_server": "Hakkında", "footer.directory": "Profil dizini", "footer.get_app": "Uygulamayı indir", diff --git a/config/locales/be.yml b/config/locales/be.yml index bbe64c59511728..77d515b37c92a8 100644 --- a/config/locales/be.yml +++ b/config/locales/be.yml @@ -876,6 +876,7 @@ be: publish_statistics: Апублікаваць статыстыку title: Выяўленне trends: Трэнды + wrapstodon: Вынікадон domain_blocks: all: Для ўсіх disabled: Нікому diff --git a/config/locales/da.yml b/config/locales/da.yml index e15eeb7dda6637..ea5cbe33370ba6 100644 --- a/config/locales/da.yml +++ b/config/locales/da.yml @@ -848,6 +848,7 @@ da: publish_statistics: Udgiv statistik title: Opdagelse trends: Trends + wrapstodon: Wrapstodon domain_blocks: all: Til alle disabled: Til ingen diff --git a/config/locales/de.yml b/config/locales/de.yml index 04dc47b0387943..0ecff0e276342d 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -848,6 +848,7 @@ de: publish_statistics: Statistiken veröffentlichen title: Entdecken trends: Trends + wrapstodon: Wrapstodon domain_blocks: all: Allen disabled: Niemandem diff --git a/config/locales/el.yml b/config/locales/el.yml index 67e3f337ade1fe..ddc822f1ba7e20 100644 --- a/config/locales/el.yml +++ b/config/locales/el.yml @@ -848,6 +848,7 @@ el: publish_statistics: Δημοσίευση στατιστικών title: Ανακάλυψη trends: Τάσεις + wrapstodon: Wrapstodon domain_blocks: all: Για όλους disabled: Για κανέναν diff --git a/config/locales/en-GB.yml b/config/locales/en-GB.yml index 2e0e1d47faa420..e616adfedc13a6 100644 --- a/config/locales/en-GB.yml +++ b/config/locales/en-GB.yml @@ -848,6 +848,7 @@ en-GB: publish_statistics: Publish statistics title: Discovery trends: Trends + wrapstodon: Wrapstodon domain_blocks: all: To everyone disabled: To no one diff --git a/config/locales/es-AR.yml b/config/locales/es-AR.yml index a6e118e00874ba..573c3ac859241e 100644 --- a/config/locales/es-AR.yml +++ b/config/locales/es-AR.yml @@ -8,7 +8,7 @@ es-AR: title: Información accounts: errors: - cannot_be_added_to_collections: Esta cuenta no se puede añadir a las colecciones. + cannot_be_added_to_collections: Esta cuenta no puede ser agregada a colecciones. followers: one: Seguidor other: Seguidores @@ -848,6 +848,7 @@ es-AR: publish_statistics: Publicar estadísticas title: Descubrí trends: Tendencias + wrapstodon: MastodonAnual domain_blocks: all: A todos disabled: A nadie diff --git a/config/locales/es-MX.yml b/config/locales/es-MX.yml index 56b539d6b43dad..5fcefbce28d5e2 100644 --- a/config/locales/es-MX.yml +++ b/config/locales/es-MX.yml @@ -848,6 +848,7 @@ es-MX: publish_statistics: Publicar estadísticas title: Descubrimiento trends: Tendencias + wrapstodon: Wrapstodon domain_blocks: all: A todos disabled: A nadie diff --git a/config/locales/eu.yml b/config/locales/eu.yml index f73a1284d889da..f60c4bcce4bb2c 100644 --- a/config/locales/eu.yml +++ b/config/locales/eu.yml @@ -7,6 +7,8 @@ eu: hosted_on: Mastodon %{domain} domeinuan ostatatua title: Honi buruz accounts: + errors: + cannot_be_added_to_collections: Ezin da kontu hau bildumetara gehitu. followers: one: Jarraitzaile other: jarraitzaile @@ -190,6 +192,7 @@ eu: create_relay: Erreleboa sortu create_unavailable_domain: Sortu eskuragarri ez dagoen domeinua create_user_role: Sortu rola + create_username_block: Sortu erabiltzaile-izenaren araua demote_user: Jaitsi erabiltzailearen maila destroy_announcement: Ezabatu iragarpena destroy_canonical_email_block: Ezabatu email blokeoa @@ -203,12 +206,14 @@ eu: destroy_status: Ezabatu bidalketa destroy_unavailable_domain: Ezabatu eskuragarri ez dagoen domeinua destroy_user_role: Ezabatu rola + destroy_username_block: Ezabatu erabiltzaile-izenaren araua disable_2fa_user: Desgaitu 2FA disable_custom_emoji: Desgaitu emoji pertsonalizatua disable_relay: Erreleboa desaktibatu disable_sign_in_token_auth_user: Desgaitu email token autentifikazioa erabiltzailearentzat disable_user: Desgaitu erabiltzailea enable_custom_emoji: Gaitu emoji pertsonalizatua + enable_relay: Gaitu errelea enable_sign_in_token_auth_user: Gaitu email token autentifikazioa erabiltzailearentzat enable_user: Gaitu erabiltzailea memorialize_account: Bihurtu kontua oroigarri @@ -236,6 +241,7 @@ eu: update_report: Txostena eguneratu update_status: Eguneratu bidalketa update_user_role: Eguneratu rola + update_username_block: Eguneratu erabiltzaile-izenaren araua actions: approve_appeal_html: "%{name} erabiltzaileak %{target} erabiltzailearen moderazio erabakiaren apelazioa onartu du" approve_user_html: "%{name} erabiltzaileak %{target} erabiltzailearen izen-ematea onartu du" @@ -310,7 +316,9 @@ eu: create: Sortu iragarpena title: Iragarpen berria preview: + disclaimer: Erabiltzaileek ezin dutenez horiei uko egin, posta elektroniko bidezko jakinarazpenak iragarpen garrantzitsuetara mugatu behar dira; adibidez, datu pertsonalen segurtasun-haustura edo zerbitzariaren itxiera jakinarazpenetara. explanation_html: 'Mezu elektronikoa %{display_count} erabiltzaileei bidaliko zaie. Testu hau gehituko zaio mezu elektronikoari:' + title: Aurreikusi iragarpenaren aurrebista publish: Argitaratu published_msg: Iragarpena ongi argitaratu da! scheduled_for: "%{time}-rako programatuta" @@ -441,6 +449,7 @@ eu: attempts_over_week: one: Izen-emateko saiakera %{count} azken astean other: Izen-emateko %{count} saiakera azken astean + created_msg: Ongi gehitu da e-mail helbidea domeinuen zerrenda beltzera delete: Ezabatu dns: types: @@ -450,7 +459,9 @@ eu: create: Gehitu domeinua resolve: Ebatzi domeinua title: Posta domeinu berria blokeatu + no_email_domain_block_selected: Ez da eposta domeinu blokeorik aldatu ez delako bat ere hautatu not_permitted: Baimendu gabea + resolved_dns_records_hint_html: Domeinu-izena ondorengo MX domeinuetara ebazten da, zeinek eposta onartzeko ardura duten. MX domeinu bat blokeatzeak MX domeinu hori erabiltzen duen edozein helbide elektronikotatik izena-ematea blokeatzen du, baita ikusgai dagoen domeinu-izena beste bat bada ere. Kontuz ibili eposta hornitzaile nagusiak blokeatu gabe. resolved_through_html: "%{domain} domeinuaren bidez ebatzia" title: Email domeinua blokeatuta export_domain_allows: @@ -479,6 +490,7 @@ eu: providers: active: Aktibo base_url: Oinarrizko URL-a + callback: Dei-erantzuna delete: Ezabatu edit: Editatu hornitzailea finish_registration: Izen-ematea bukatu @@ -488,8 +500,11 @@ eu: registration_requested: Izen-ematea eskatuta registrations: confirm: Berretsi + description: Erregistro bat jaso duzu FASP batetik. Ukatu ez baduzu zuk zeuk abiarazi. Zuk abiarazi baduzu, alderatu arretaz izena eta gakoaren hatz-marka erregistroa berretsi aurretik. reject: Ukatu + title: Berretsi FASP erregistroa save: Gorde + select_capabilities: Hautatu ahalmenak sign_in: Hasi saioa status: Egoera title: Fedibertsoko zerbitzu osagarrien hornitzaileak @@ -503,6 +518,9 @@ eu: title: Jarraitzeko gomendioak unsuppress: Berrezarri jarraitzeko gomendioa instances: + audit_log: + title: Oraintsuko ikuskapen-erregistroak + view_all: Ikusi ikuskapen-erregistro osoak availability: description_html: one: Domeinura entregatzeak arrakastarik gabe huts egiten badu egun %{count} igaro ondoren, ez da entregatzeko saiakera gehiago egingo, ez bada domeinu horretatik entregarik jasotzen. @@ -563,6 +581,8 @@ eu: create: Gehitu Moderazio Oharra created_msg: Instantziako moderazio oharra ongi sortu da! description_html: Ikusi eta idatzi oharrak beste moderatzaileentzat eta zuretzat etorkizunerako + destroyed_msg: Instantziako moderazio oharra ongi ezabatu da! + placeholder: Instantzia honi buruzko informazioa, burututako ekintzak edo etorkizunean instantzia hau moderatzen lagunduko dizun beste edozein gauza. title: Moderazio oharrak private_comment: Iruzkin pribatua public_comment: Iruzkin publikoa @@ -634,7 +654,9 @@ eu: resolve_description_html: Ez da ekintzarik hartuko salatutako kontuaren aurka, ez da neurria gordeko eta salaketa itxiko da. silence_description_html: Kontua soilik honen jarraitzaile edo espresuki bilatzen dutenentzat izango da ikusgarri, kontuaren irisgarritasuna gogorki mugatzen delarik. suspend_description_html: Kontua bera eta honen edukiak eskuraezinak izango dira, eta azkenean, ezabatuak. Kontu honekin erlazionatzea ezinezkoa izango da. Prozesua 30 egunez itzulgarria izango da. Kontu honen aurkako txosten guztiak baztertuko lirateke. + actions_description_html: Erabaki txosten hau konpontzeko ze ekintza hartu. Salatutako kontuaren aurka zigor ekintza bat hartzen baduzu, eposta jakinarazpen bat bidaliko zaie, Spam kategoria hautatzean ezik. actions_description_remote_html: Hautatu txosten honi konponbidea aurkitzeko zein neurri hartu. Hau soilik zure zerbitzaria urruneko kontu honekin nola komunikatu eta bere edukia nola maneiatzeko da. + actions_no_posts: Txosten honek ez du ezabatzeko lotutako argitalpenik add_to_report: Gehitu gehiago txostenera already_suspended_badges: local: Dagoeneko kanporatu da zerbitzari honetatik @@ -675,6 +697,7 @@ eu: report: 'Salaketa #%{id}' reported_account: Salatutako kontua reported_by: Salatzailea + reported_with_application: Aplikazioaren bidez salatua resolved: Konponduta resolved_msg: Salaketa ongi konpondu da! skip_to_actions: Salto ekintzetara @@ -737,6 +760,7 @@ eu: manage_appeals: Kudeatu apelazioak manage_appeals_description: Baimendu erabiltzaileek moderazio ekintzen aurkako apelazioak berrikustea manage_blocks: Kudeatu blokeatzeak + manage_blocks_description: Baimendu erabiltzaileek eposta hornitzaile eta IP helbideak blokeatzea manage_custom_emojis: Kudeatu emoji pertsonalizatuak manage_custom_emojis_description: Baimendu erabiltzaileek zerbitzariko emoji pertsonalizatuak kudeatzea manage_federation: Kudeatu federazioa @@ -754,6 +778,7 @@ eu: manage_taxonomies: Kudeatu taxonomiak manage_taxonomies_description: Baimendu erabiltzaileek joerak berrikustea eta traolen ezarpenak eguneratzea manage_user_access: Kudeatu erabiltzaileen sarbidea + manage_user_access_description: Baimendu erabiltzaileek beste erabiltzaileen bi faktoreko autentifikazioa desaktibatzea, eposta helbideak aldatzea eta pasahitzak berrezartzea manage_users: Kudeatu erabiltzaileak manage_users_description: Baimendu erabiltzaileek beste erabiltzaileen xehetasunak ikusi eta moderazio ekintzak burutzea manage_webhooks: Kudeatu webhook-ak @@ -801,18 +826,22 @@ eu: title: Erabiltzaileei bilaketa-motorraren indexaziotik at egoteko aukera ematen die lehenetsitako aukera modura discovery: follow_recommendations: Jarraitzeko gomendioak + preamble: Eduki interesgarria aurkitzea garrantzitsua da Mastodoneko erabiltzaile berrientzat, behar bada inor ez dutelako ezagutuko. Kontrolatu zure zerbitzariko aurkikuntza-ezaugarriek nola funtzionatzen duten. privacy: Pribatutasuna profile_directory: Profil-direktorioa public_timelines: Denbora-lerro publikoak publish_statistics: Argitaratu estatistikak title: Aurkitzea trends: Joerak + wrapstodon: Wrapstodon domain_blocks: all: Guztiei disabled: Inori ez users: Saioa hasita duten erabiltzaile lokalei feed_access: modes: + authenticated: Saioa hasi duten erabiltzaileentzat soilik + disabled: Erabiltzaile-rol jakin bat behar da public: Edonork landing_page: values: @@ -942,8 +971,10 @@ eu: not_trendable: Ez dago modan not_usable: Ez erabilgarri pending_review: Berrikusketaren zain + review_requested: Berrikuspena eskatuta reviewed: Berrikusita title: Egoera + trendable: Joera bihur daiteke unreviewed: Berrikusi gabe usable: Erabilgarri name: Izena @@ -969,6 +1000,9 @@ eu: going_live_on_html: Argitaratua, indarrean %{date} history: Historia live: Zuzenean + notify_users: Jakinarazi erabiltzaileak + preview: + send_preview: 'Bidali aurrebista hona: %{email}' publish: Argitaratu published_on_html: "%{date}(e)an argitaratua" save_draft: Gorde zirriborroa @@ -977,11 +1011,14 @@ eu: trends: allow: Onartu approved: Onartua + confirm_allow: Ziur zaude hautatutako etiketak gaitu nahi dituzula? confirm_disallow: Ziur zaude hautatutako etiketak desgaitu nahi dituzula? disallow: Ukatu links: allow: Onartu esteka allow_provider: Onartu argitaratzailea + confirm_allow: Ziur zaude hautatutako estekak gaitu nahi dituzula? + confirm_disallow: Ziur zaude hautatutako estekak desgaitu nahi dituzula? description_html: Esteka hauek zure zerbitzariak ikusten dituen kontuek asko zabaltzen ari diren estekak dira. Zure erabiltzaileei munduan ze berri den jakiteko lagungarriak izan daitezke. Ez da estekarik bistaratzen argitaratzaileak onartu arte. Esteka bakoitza onartu edo baztertu dezakezu. disallow: Ukatu esteka disallow_provider: Ukatu argitaratzailea @@ -1037,9 +1074,23 @@ eu: used_by_over_week: one: Pertsona batek erabilia azken astean other: "%{count} pertsonak erabilia azken astean" + title: Gomendioak eta joerak trending: Joerak username_blocks: add_new: Gehitu berria + block_registrations: Blokeatu izen-emateak + comparison: + equals: Berdin + delete: Ezabatu + edit: + title: Editatu erabiltzaile-izena araua + matches_exactly_html: 'Berdin: %{string}' + new: + create: Sortu araua + title: Sortu erabiltzaile-izen araua berria + no_username_block_selected: Ez da erabiltzaile-izen araurik aldatu, ez delako bat ere hautatu + not_permitted: Baimendu gabea + title: Erabiltzaile-izen arauak warning_presets: add_new: Gehitu berria delete: Ezabatu @@ -1111,6 +1162,7 @@ eu: hint_html: Beste kontu batetik hona migratu nahi baduzu, hemen ezizen bat sortu dezakezu, hau beharrezkoa da kontu zaharreko jarraitzaileak hona ekartzeko. Ekintza hau berez kaltegabea eta desegingarria da. Kontuaren migrazioa kontu zaharretik abiatzen da. remove: Deslotu ezizena appearance: + advanced_settings: Ezarpen aurreratuak animations_and_accessibility: Animazioak eta irisgarritasuna discovery: Aurkitzea localization: @@ -1119,6 +1171,7 @@ eu: guide_link_text: Edonork lagundu dezake. sensitive_content: Eduki hunkigarria application_mailer: + notification_preferences: Posta elektronikoaren lehentasunak aldatu salutation: "%{name}," settings: 'Posta elektronikoaren lehentasunak aldatu: %{link}' unsubscribe: Kendu harpidetza @@ -1140,6 +1193,7 @@ eu: hint_html: Azken kontu bat! Gizakia zarela berretsi behar dugu (zabor-kontuak kanpoan mantentzeko baino ez da!) Ebatzi azpiko CAPTCHA eta sakatu "Jarraitu". title: Segurtasun txekeoa confirmations: + awaiting_review: Zure helbide elektronikoa baieztatu da! %{domain} lan taldea zure erregistroa berrikusten ari da. Mezu elektroniko bat jasoko duzu zure kontua onartzen badute! awaiting_review_title: Zure izen-ematea berrikusten ari da clicking_this_link: lotura hau klikatzen login_link: hasi saioa @@ -1147,6 +1201,7 @@ eu: redirect_to_app_html: "%{app_name} aplikaziora berbideratua izan beharko zenuke. Hori gertatu ez bada, saiatu %{clicking_this_link} edo eskuz itzuli." registration_complete: Osatuta dago orain zure izen-ematea %{domain} -en! welcome_title: Ongi etorri, %{name}! + wrong_email_hint: Helbide-elektroniko hori zuzena ez bada, kontuaren ezarpenetan alda dezakezu. delete_account: Ezabatu kontua delete_account_html: Kontua ezabatu nahi baduzu, jarraitu hemen. Berrestea eskatuko zaizu. description: @@ -1197,9 +1252,11 @@ eu: title: "%{domain}-(e)an saioa hasi" sign_up: manual_review: "%{domain}-(e)n eginiko izen-emateak gure moderatzaileek eskuz aztertzen dituzte. Zure izen-ematea prozesatzen lagun gaitzazun, idatz ezazu zertxobait zuri buruz eta azaldu zergatik nahi duzun %{domain}-(e)n kontu bat." + preamble: Mastodon zerbitzari honetako kontu batekin, aukera izango duzu fedibertsoko edozein pertsona jarraitzeko, ez dio axola kontua non ostatatua dagoen. title: "%{domain} zerbitzariko kontua prestatuko dizugu." status: account_status: Kontuaren egoera + confirming: E-mail baieztapena osatu bitartean zain. functional: Zure kontua guztiz erabilgarri dago. pending: Gure taldea zure eskaera berrikusten ari da. Honek denbora pixka bat beharko du. Mezu elektroniko bat jasoko duzu zure eskaera onartzen bada. redirecting_to: Zure kontua ez dago aktibo orain %{acct} kontura birbideratzen duelako. @@ -1207,6 +1264,9 @@ eu: view_strikes: Ikusi zure kontuaren aurkako neurriak too_fast: Formularioa azkarregi bidali duzu, saiatu berriro. use_security_key: Erabili segurtasun gakoa + author_attribution: + example_title: Testu-lagina + more_from_html: "%{name} erabiltzaileaz gehiago jakin" challenge: confirm: Jarraitu hint_html: "Oharra: Ez dizugu pasahitza berriro eskatuko ordu batez." @@ -1243,6 +1303,7 @@ eu: before: 'Jarraitu aurretik, irakurri adi ohar hauek:' caches: Beste zerbitzariek cachean duten edukia mantentzea gerta daiteke data_removal: Zure bidalketak eta beste datuak behin betiko ezabatuko dira + email_reconfirmation_html: Ez baduzu baieztamen e-maila jasotzen, berriro eskatu dezakezu irreversible: Ezin izango duzu kontua berreskuratu edo berraktibatu more_details_html: Xehetasun gehiagorako, ikusi pribatutasun politika. username_available: Zure erabiltzaile-izena berriro eskuragarri egongo da @@ -1281,6 +1342,10 @@ eu: basic_information: Oinarrizko informazioa hint_html: "Pertsonalizatu jendeak zer ikusi dezakeen zure profil publikoan eta zure bidalketen baitan. Segur aski, jende gehiagok jarraituko dizu eta interakzio gehiago izango dituzu profila osatuta baduzu, profil irudia eta guzti." other: Bestelakoak + emoji_styles: + auto: Automatikoa + native: Bertakoa + twemoji: Twemoji errors: '400': Bidali duzun eskaera baliogabea da edo gaizki osatua dago. '403': Ez duzu orri hau ikusteko baimenik. @@ -1452,6 +1517,13 @@ eu: expires_at: Iraungitzea uses: Erabilerak title: Gonbidatu jendea + link_preview: + author_html: 'Egilea: %{name}' + potentially_sensitive_content: + action: Egin klik erakusteko + confirm_visit: Ziur zaude esteka hau ireki nahi duzula? + hide_button: Ezkutatu + label: Eduki sentikorra izan daiteke lists: errors: limit: Gehienezko zerrenda kopurura iritsi zara @@ -1459,6 +1531,7 @@ eu: authentication_methods: otp: bi faktoreko autentifikazio aplikazioa password: pasahitza + sign_in_token: e-posta segurtasun kodea webauthn: segurtasun gakoak description_html: Ezagutzen ez duzun aktibitatea ikusten baduzu, pasahitza aldatu eta bi faktoreko autentifikazioa gaitzea gomendatzen dizugu. empty: Ez dago autentifikazio historiarik eskuragarri @@ -1469,9 +1542,18 @@ eu: unsubscribe: action: Bai, kendu harpidetza complete: Harpidetza kenduta + confirmation_html: |- + Ziur Mastodonen %{domain} zerbitzariko %{type} %{email} helbide elektronikoan jasotzeari utzi nahi diozula? + Beti harpidetu zaitezke berriro eposta jakinarazpenen hobespenetan. emails: notification_emails: + favourite: zure argitalpena gogoko egin dutenaren jakinarazpen e-mailak follow: jarraitu jakinarazpen-mezu elektronikoak + follow_request: jarraipen-eskaeren jakinarazpen e-mailak + mention: aipamenen jakinarazpen e-mailak + reblog: bultzaden jakinarazpen e-mailak + resubscribe_html: Nahi gabe utzi badiozu jakinarazpenak jasotzeari, berriro harpidetu zaitezke e-mail jakinarazpenen hobespenetan. + success_html: Ez duzu Mastodonen %{domain} zerbitzariko %{type} jasoko %{email} helbide elektronikoan. title: Kendu harpidetza media_attachments: validations: @@ -1507,6 +1589,7 @@ eu: disabled_account: Zure uneko kontua ezin izango da gero erabili. Hala ere, datua exporatu ahal izango dituzu, eta berriro aktibatu. followers: Ekintza honek jarraitzaile guztiak eramango ditu uneko kontutik kontu berrira only_redirect_html: Bestela, zure profilean birbideratze bat jar dezakezu. + other_data: Ez da beste daturik automatikoki mugituko (zure argitalpenak eta jarraitzen dituzun kontuen zerrenda barne) redirect: Zure uneko kontuaren profila eguneratuko da birbideratze ohar batekin eta bilaketetatik kenduko da moderation: title: Moderazioa @@ -1540,17 +1623,29 @@ eu: body: "%{name}(e)k aipatu zaitu:" subject: "%{name}(e)k aipatu zaitu" title: Aipamen berria + moderation_warning: + subject: Moderazio-abisu bat jaso duzu poll: subject: "%{name} erabiltzailearen inkesta bat amaitu da" + quote: + body: "%{name}(e)k zure bidalketari aipamena egin dio:" + subject: "%{name} erabiltzaileak zure bidalketa aipatu du" + title: Aipamen berria + quoted_update: + subject: "%{name} erabiltzaileak aipatu duzun post bat editatu du" reblog: body: "%{name}(e)k bultzada eman dio zure bidalketari:" subject: "%{name}(e)k bultzada eman dio zure bidalketari" title: Bultzada berria + severed_relationships: + subject: Harremanak galdu dituzu moderazio-erabaki baten ondorioz status: subject: "%{name} erabiltzaileak bidalketa egin berri du" update: subject: "%{name} erabiltzaileak bidalketa bat editatu du" notifications: + administration_emails: Administratzailearen posta elektroniko bidezko jakinarazpenak + email_events: E-mail jakinarazpenentzako gertaerak email_events_hint: 'Hautatu jaso nahi dituzun gertaeren jakinarazpenak:' number: human: @@ -1588,6 +1683,9 @@ eu: self_vote: Ezin duzu zuk sortutako inkestetan bozka eman too_few_options: elementu bat baino gehiago izan behar du too_many_options: ezin ditu %{max} elementu baino gehiago izan + vote: Bozkatu + posting_defaults: + explanation: Konfigurazio hau lehenetsi gisa erabiliko da argitalpen berriak sortzen dituzunean, baina aldatu egin dezakezu argitalpen bat idaztean. preferences: other: Denetarik posting_defaults: Bidalketarako lehenetsitakoak @@ -1644,6 +1742,7 @@ eu: scheduled_statuses: over_daily_limit: 'Egun horretarako programatutako bidalketa kopuruaren muga gainditu duzu: %{limit}' over_total_limit: 'Programatutako bidalketa kopuruaren muga gainditu duzu: %{limit}' + too_soon: datak etorkizunekoa izan behar du self_destruct: lead_html: Zoritxarrez, %{domain} betirako itxiko da. Kontu bat baduzu bertan, ezin izango duzu erabiltzen jarraitu, baina, oraindik zure datuen babeskopia bat eska dezakezu. title: Zerbitzari hau ixtear dago @@ -1742,6 +1841,9 @@ eu: other: "%{count} bideo" boosted_from_html: "%{acct_link}(e)tik bultzatua" content_warning: 'Edukiaren abisua: %{warning}' + content_warnings: + hide: Tuta ezkutatu + show: Erakutsi gehiago default_language: Interfazearen hizkuntzaren berdina disallowed_hashtags: one: 'debekatutako traola bat zuen: %{tags}' @@ -1749,15 +1851,31 @@ eu: edited_at_html: Editatua %{date} errors: in_reply_not_found: Erantzuten saiatu zaren bidalketa antza ez da existitzen. + quoted_status_not_found: Aipua egiten saiatu zaren bidalketa antza ez da existitzen. + quoted_user_not_mentioned: Ezin da aipatu ez den erabiltzaile baten aipamenik egin Aipamen pribatu batean. over_character_limit: "%{max}eko karaktere muga gaindituta" pin_errors: direct: Aipatutako erabiltzaileentzat soilik ikusgai dauden bidalketak ezin dira finkatu limit: Gehienez finkatu daitekeen bidalketa kopurua finkatu duzu jada ownership: Ezin duzu beste norbaiten bidalketa bat finkatu reblog: Bultzada bat ezin da finkatu + quote_error: + not_available: Bidalketa ez dago eskuragarri + pending_approval: Bidalketa zain dago + revoked: Egileak bidalketa kendu du + quote_policies: + followers: Jarraitzaileentzat soilik + nobody: Nik bakarrik + public: Edonork + quote_post_author: "%{acct}-(r)en bidalketan aipatua" title: '%{name}: "%{quote}"' visibilities: + direct: Aipu pribatua + private: Jarraitzaileentzat soilik public: Publikoa + public_long: Mastodonen dagoen edo ez dagoen edonor + unlisted: Ikusgarritasun mugatua + unlisted_long: Ezkutatuta Mastodon bilaketen emaitzetatik, joeretatik, eta denbora-lerro publikoetatik statuses_cleanup: enabled: Ezabatu bidalketa zaharrak automatikoki enabled_hint: Zure bidalketa zaharrak automatikoki ezabatzen ditu zehazturiko denbora mugara iristean, beheko baldintza bat betetzen ez bada @@ -1804,6 +1922,8 @@ eu: title: Erabilera baldintzak terms_of_service_interstitial: future_preamble_html: Gure zerbitzu-baldintzetan aldaketa batzuk egiten ari gara, eta %{date}-tik aurrera jarriko dira indarrean. Eguneratutako baldintzak berrikustea gomendatzen dizugu. + past_preamble_html: Zerbitzu-baldintzak aldatu ditugu zure azken bisitatik. Baldintza eguneratuak berrikustera animatzen zaitugu. + review_link: Berrikusi zerbitzu-baldintzak themes: contrast: Mastodon (Kontraste altua) default: Mastodon (Iluna) @@ -1836,6 +1956,7 @@ eu: webauthn: Segurtasun gakoak user_mailer: announcement_published: + subject: Zerbitzuaren iragarpena title: "%{domain} zerbitzuaren iragarpena" appeal_approved: action: Kontuaren ezarpenak @@ -1866,6 +1987,12 @@ eu: further_actions_html: Ez bazara zu izan, lehenbailehen %{action} gomendatzen dizugu eta bi faktoreko autentifikazioa gaitzea zure kontua seguru mantentzeko. subject: Zure kontura sarbidea egon da IP helbide berri batetik title: Saio hasiera berria + terms_of_service_changed: + changelog: 'Laburbilduz, hau da eguneratze honek zuretzat esan nahi duena:' + sign_off: "%{domain} taldea" + subject: Zerbitzu-baldintzen eguneratzeak + subtitle: "%{domain}(e)ko zerbitzu-baldintzak aldatu egingo dira" + title: Eguneraketa garrantzitsua warning: appeal: Bidali apelazioa appeal_description: Hau errore bat dela uste baduzu, apelazio bat bidali diezaiekezu %{instance} instantziako arduradunei. @@ -1943,6 +2070,7 @@ eu: invalid_otp_token: Bi faktoreetako kode baliogabea otp_lost_help_html: 'Bietara sarbidea galdu baduzu, jarri kontaktuan hemen: %{email}' rate_limited: Autentifikazio saiakera gehiegi, saiatu berriro geroago. + seamless_external_login: Kanpo zerbitzu baten bidez hasi duzu saioa, beraz pasahitza eta e-mail ezarpenak ez daude eskuragarri. signed_in_as: 'Saioa honela hasita:' verification: extra_instructions_html: Aholkua: webguneko esteka ikusezina izan daiteke. Muina rel="me" da, erabiltzaileak sortutako edukia duten webguneetan beste inor zure burutzat aurkeztea eragozten duena. a beharrean esteka motako etiketa bat ere erabil dezakezu orriaren goiburuan, baina HTMLak erabilgarri egon behar du JavaScript exekutatu gabe. @@ -1969,3 +2097,6 @@ eu: not_supported: Nabigatzaile honek ez ditu segurtasun gakoak onartzen otp_required: Segurtasun gakoak erabili aurretik bi faktoreko autentifikazioa gaitu behar duzu. registered_on: "%{date}(e)an erregistratua" + wrapstodon: + description: Begira nola erabili duen Mastodon %{name}(e)k urte honetan! + title: "%{year}(e)ko Wrapstodona, %{name}(e)rentzat" diff --git a/config/locales/fi.yml b/config/locales/fi.yml index c2cf09a6354dbf..eee902e812ff5c 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -848,6 +848,7 @@ fi: publish_statistics: Julkaise tilastot title: Löydettävyys trends: Trendit + wrapstodon: Wrapstodon domain_blocks: all: Kaikille disabled: Ei kenellekään diff --git a/config/locales/fr-CA.yml b/config/locales/fr-CA.yml index 555e8a5aaa2e81..6590c544d9fa4f 100644 --- a/config/locales/fr-CA.yml +++ b/config/locales/fr-CA.yml @@ -851,6 +851,7 @@ fr-CA: publish_statistics: Publier les statistiques title: Découverte trends: Tendances + wrapstodon: Wrapstodon domain_blocks: all: À tout le monde disabled: À personne diff --git a/config/locales/fr.yml b/config/locales/fr.yml index c54aa068052fa7..3ce00ca9f97a7e 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -851,6 +851,7 @@ fr: publish_statistics: Publier les statistiques title: Découverte trends: Tendances + wrapstodon: Wrapstodon domain_blocks: all: À tout le monde disabled: À personne diff --git a/config/locales/ga.yml b/config/locales/ga.yml index 72d9262cca6433..acba6eab84944c 100644 --- a/config/locales/ga.yml +++ b/config/locales/ga.yml @@ -890,6 +890,7 @@ ga: publish_statistics: Staitisticí a fhoilsiú title: Fionnachtain trends: Treochtaí + wrapstodon: Wrapstodon domain_blocks: all: Do chách disabled: Do dhuine ar bith diff --git a/config/locales/gl.yml b/config/locales/gl.yml index 615f15f0daece7..c465f3fd87d2c8 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -848,6 +848,7 @@ gl: publish_statistics: Publicar estatísticas title: Descubrir trends: Tendencias + wrapstodon: Wrapstodon domain_blocks: all: Para todos disabled: Para ninguén diff --git a/config/locales/hu.yml b/config/locales/hu.yml index d89078d8fdafaf..3a5172e05cc2a9 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -848,6 +848,7 @@ hu: publish_statistics: Statisztikák közzététele title: Felfedezés trends: Trendek + wrapstodon: Wrapstodon domain_blocks: all: Mindenkinek disabled: Senkinek diff --git a/config/locales/is.yml b/config/locales/is.yml index 72c8607e9d7851..d03b74391f7135 100644 --- a/config/locales/is.yml +++ b/config/locales/is.yml @@ -850,6 +850,7 @@ is: publish_statistics: Birta tölfræði title: Uppgötvun trends: Vinsælt + wrapstodon: Ársuppgjörið domain_blocks: all: Til allra disabled: Til engra @@ -2193,4 +2194,4 @@ is: registered_on: Skráði sig %{date} wrapstodon: description: Sjáðu hvernig %{name} notaði Mastodon á árinu! - title: Wrapstodon %{year} fyrir %{name} + title: Ársuppgjörið %{year} fyrir %{name} diff --git a/config/locales/it.yml b/config/locales/it.yml index 77072e7a374840..37b131c4b99684 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -848,6 +848,7 @@ it: publish_statistics: Pubblica le statistiche title: Scopri trends: Tendenze + wrapstodon: Wrapstodon domain_blocks: all: A tutti disabled: A nessuno diff --git a/config/locales/pt-PT.yml b/config/locales/pt-PT.yml index bb1919e69c3b1d..b9175395f0ccda 100644 --- a/config/locales/pt-PT.yml +++ b/config/locales/pt-PT.yml @@ -848,6 +848,7 @@ pt-PT: publish_statistics: Publicar estatísticas title: Descobrir trends: Tendências + wrapstodon: Wrapstodon domain_blocks: all: Para toda a gente disabled: Para ninguém diff --git a/config/locales/simple_form.be.yml b/config/locales/simple_form.be.yml index dbc556bf85efa3..7f899b5139b481 100644 --- a/config/locales/simple_form.be.yml +++ b/config/locales/simple_form.be.yml @@ -111,6 +111,7 @@ be: thumbnail: Выява памерамі прыкладна 2:1, якая паказваецца побач з інфармацыяй пра ваш сервер. trendable_by_default: Прапусціць ручны агляд трэндавага змесціва. Асобныя элементы ўсё яшчэ можна будзе выдаліць з трэндаў пастфактум. trends: Трэнды паказваюць, якія допісы, хэштэгі і навіны набываюць папулярнасць на вашым серверы. + wrapstodon: Прапанаваць мясцовым карыстальнікам інтэрактыўную зводку іх выкарыстання Mastodon на працягу года. Гэта функцыя даступная паміж 10-ым і 31-ым снежня кожнага года і прапаноўваецца карыстальнікам, якія зрабілі хаця б адзін публічны або ціхі публічны допіс, а таксама выкарысталі хаця б адзін хэштэг на працягу года. form_challenge: current_password: Вы ўваходзіце ў бяспечную зону imports: @@ -314,6 +315,7 @@ be: thumbnail: Мініяцюра сервера trendable_by_default: Дазваляць трэнды без папярэдняй праверкі trends: Уключыць трэнды + wrapstodon: Уключыць Вынікадон interactions: must_be_follower: Заблакіраваць апавяшчэнні ад непадпісаных людзей must_be_following: Заблакіраваць апавяшчэнні ад людзей на якіх вы не падпісаны diff --git a/config/locales/simple_form.da.yml b/config/locales/simple_form.da.yml index 68f114e7fe2bd3..4df4e34eedee1f 100644 --- a/config/locales/simple_form.da.yml +++ b/config/locales/simple_form.da.yml @@ -111,6 +111,7 @@ da: thumbnail: Et ca. 2:1 billede vist sammen med serveroplysningerne. trendable_by_default: Spring manuel gennemgang af trendindhold over. Individuelle elementer kan stadig fjernes fra trends efter kendsgerningen. trends: Tendenser viser, hvilke indlæg, hashtags og nyheder opnår momentum på serveren. + wrapstodon: Tilbyd lokale brugere at generere en sjov oversigt over deres brug af Mastodon i løbet af året. Denne funktion er tilgængelig mellem den 10. og 31. december hvert år og tilbydes til brugere, der har lavet mindst ét offentligt eller stille offentligt indlæg og brugt mindst ét hashtag i løbet af året. form_challenge: current_password: Du bevæger dig ind på et sikkert område imports: @@ -312,6 +313,7 @@ da: thumbnail: Serverminiaturebillede trendable_by_default: Tillad ikke-reviderede trends trends: Aktivér trends + wrapstodon: Aktivér Wrapstodon interactions: must_be_follower: Blokér notifikationer fra bruger, der ikke følger dig must_be_following: Blokér notifikationer fra brugere, du ikke følger diff --git a/config/locales/simple_form.de.yml b/config/locales/simple_form.de.yml index e085ccd2eedb9f..a8755d69010e37 100644 --- a/config/locales/simple_form.de.yml +++ b/config/locales/simple_form.de.yml @@ -111,6 +111,7 @@ de: thumbnail: Ein Bild ungefähr im 2:1-Format, das neben den Server-Informationen angezeigt wird. trendable_by_default: Manuelles Überprüfen angesagter Inhalte überspringen. Einzelne Elemente können später noch aus den Trends entfernt werden. trends: Trends zeigen, welche Beiträge, Hashtags und Nachrichten auf deinem Server immer beliebter werden. + wrapstodon: Ermöglicht Nutzer*innen dieses Servers einen spielerischen Jahresrückblick ihrer Mastodon-Aktivität zu erstellen. Diese Funktion ist jedes Jahr zwischen dem 10. und 31. Dezember verfügbar und wird Nutzer*innen angeboten, die innerhalb des Jahres mindestens einen öffentlichen oder stillen Beitrag verfasst und mindestens einen Hashtag verwendet haben. form_challenge: current_password: Du betrittst einen sicheren Bereich imports: @@ -312,6 +313,7 @@ de: thumbnail: Vorschaubild des Servers trendable_by_default: Trends ohne vorherige Überprüfung erlauben trends: Trends aktivieren + wrapstodon: Wrapstodon aktivieren interactions: must_be_follower: Benachrichtigungen von Profilen, die mir nicht folgen, ausblenden must_be_following: Benachrichtigungen von Profilen, denen ich nicht folge, ausblenden diff --git a/config/locales/simple_form.el.yml b/config/locales/simple_form.el.yml index 5d1885a1553bbf..a579cafbceb9bc 100644 --- a/config/locales/simple_form.el.yml +++ b/config/locales/simple_form.el.yml @@ -111,6 +111,7 @@ el: thumbnail: Μια εικόνα περίπου 2:1 που εμφανίζεται παράλληλα με τις πληροφορίες του διακομιστή σου. trendable_by_default: Παράλειψη χειροκίνητης αξιολόγησης του περιεχομένου σε τάση. Μεμονωμένα στοιχεία μπορούν ακόμη να αφαιρεθούν από τις τάσεις μετέπειτα. trends: Τάσεις δείχνουν ποιες δημοσιεύσεις, ετικέτες και ειδήσεις προκαλούν έλξη στο διακομιστή σας. + wrapstodon: Πρόσφερε στους τοπικούς χρήστες τη δυνατότητα να δημιουργήσουν μια παιχνιδιάρικη σύνοψη της χρήσης τους Mastodon κατά τη διάρκεια του έτους. Αυτό το χαρακτηριστικό είναι διαθέσιμο μεταξύ της 10ης και της 31ης Δεκεμβρίου κάθε έτους, και προσφέρεται σε χρήστες που έκαναν τουλάχιστον μία δημόσια ή ήσυχη δημόσια θέση και χρησιμοποίησαν τουλάχιστον μία ετικέτα εντός του έτους. form_challenge: current_password: Μπαίνεις σε ασφαλή περιοχή imports: @@ -312,6 +313,7 @@ el: thumbnail: Μικρογραφία διακομιστή trendable_by_default: Επίτρεψε τις τάσεις χωρίς προηγούμενη αξιολόγηση trends: Ενεργοποίηση τάσεων + wrapstodon: Ενεργοποίηση Wrapstodon interactions: must_be_follower: Μπλόκαρε τις ειδοποιήσεις από όσους δεν σε ακολουθούν must_be_following: Μπλόκαρε τις ειδοποιήσεις από όσους δεν ακολουθείς diff --git a/config/locales/simple_form.en-GB.yml b/config/locales/simple_form.en-GB.yml index 39889086b1cc1f..db4080c11bbfb2 100644 --- a/config/locales/simple_form.en-GB.yml +++ b/config/locales/simple_form.en-GB.yml @@ -111,6 +111,7 @@ en-GB: thumbnail: A roughly 2:1 image displayed alongside your server information. trendable_by_default: Skip manual review of trending content. Individual items can still be removed from trends after the fact. trends: Trends show which posts, hashtags, and news stories are gaining traction on your server. + wrapstodon: Offer local users to generate a playful summary of their Mastodon use during the year. This feature is available between the 10th and 31st of December of each year, and is offered to users who made at least one Public or Quiet Public post and used at least one hashtag within the year. form_challenge: current_password: You are entering a secure area imports: @@ -312,6 +313,7 @@ en-GB: thumbnail: Server thumbnail trendable_by_default: Allow trends without prior review trends: Enable trends + wrapstodon: Enable Wrapstodon interactions: must_be_follower: Block notifications from non-followers must_be_following: Block notifications from people you don't follow diff --git a/config/locales/simple_form.es-AR.yml b/config/locales/simple_form.es-AR.yml index 4689dd0d79b09b..971ff038c48dc9 100644 --- a/config/locales/simple_form.es-AR.yml +++ b/config/locales/simple_form.es-AR.yml @@ -111,6 +111,7 @@ es-AR: thumbnail: Una imagen de aproximadamente 2:1 se muestra junto a la información de tu servidor. trendable_by_default: Omití la revisión manual del contenido en tendencia. Los elementos individuales aún podrán eliminarse de las tendencias. trends: Las tendencias muestran qué mensajes, etiquetas y noticias están ganando tracción en tu servidor. + wrapstodon: Ofrecer a los usuarios locales un resumen lúdico de su uso en Mastodon durante el año. Esta función está disponible entre los días 10 y 31 de diciembre de cada año, y se ofrece a los usuarios que enviaron a Mastodon, al menos, un mensaje público o un mensaje público pero silencioso, y que utilizaron, al menos, una etiqueta durante el año. form_challenge: current_password: Estás ingresando en un área segura imports: @@ -312,6 +313,7 @@ es-AR: thumbnail: Miniatura del servidor trendable_by_default: Permitir tendencias sin revisión previa trends: Habilitar tendencias + wrapstodon: Habilitar MastodonAnual interactions: must_be_follower: Bloquear notificaciones de cuentas que no te siguen must_be_following: Bloquear notificaciones de cuentas que no seguís diff --git a/config/locales/simple_form.es-MX.yml b/config/locales/simple_form.es-MX.yml index ae46605da65200..cfcbc77f3c4938 100644 --- a/config/locales/simple_form.es-MX.yml +++ b/config/locales/simple_form.es-MX.yml @@ -111,6 +111,7 @@ es-MX: thumbnail: Una imagen de aproximadamente 2:1 se muestra junto a la información de tu servidor. trendable_by_default: Omitir la revisión manual del contenido en tendencia. Los elementos individuales aún podrán eliminarse de las tendencias. trends: Las tendencias muestran qué mensajes, etiquetas y noticias están ganando tracción en tu servidor. + wrapstodon: Ofrece a los usuarios locales la posibilidad de generar un resumen divertido de su uso de Mastodon durante el año. Esta función está disponible entre el 10 y el 31 de diciembre de cada año, y se ofrece a los usuarios que hayan publicado al menos una publicación pública o pública silenciosa y hayan utilizado al menos una etiqueta durante el año. form_challenge: current_password: Estás entrando en un área segura imports: @@ -312,6 +313,7 @@ es-MX: thumbnail: Miniatura del servidor trendable_by_default: Permitir tendencias sin revisión previa trends: Habilitar tendencias + wrapstodon: Habilitar Wrapstodon interactions: must_be_follower: Bloquear notificaciones de personas que no te siguen must_be_following: Bloquear notificaciones de personas que no sigues diff --git a/config/locales/simple_form.eu.yml b/config/locales/simple_form.eu.yml index 26888fd24f2693..0e36f83c341dc3 100644 --- a/config/locales/simple_form.eu.yml +++ b/config/locales/simple_form.eu.yml @@ -54,8 +54,12 @@ eu: password: Erabili 8 karaktere gutxienez phrase: Bat egingo du Maiuskula/minuskula kontuan hartu gabe eta edukiaren abisua kontuan hartu gabe scopes: Zeintzuk API atzitu ditzakeen aplikazioak. Goi mailako arloa aukeratzen baduzu, ez dituzu azpikoak aukeratu behar. + setting_advanced_layout: Erakutsi Mastodon hainbat zutaberen ikuspegiarekin, zure kronologia, jakinarazpenak eta zuk aukeratutako hirugarren zutabe bat ikusteko aukera emanez. Ez da gomendagarria pantaila txikietarako. setting_aggregate_reblogs: Ez erakutsi bultzada berriak berriki bultzada jaso duten tootentzat (berriki jasotako bultzadei eragiten die bakarrik) setting_always_send_emails: Normalean eposta jakinarazpenak ez dira bidaliko Mastodon aktiboki erabiltzen ari zaren bitartean + setting_boost_modal: Gaituta dagoenean, bultzada emateak berrespen-leiho bat irekiko du lehenik; bertan, bultzadaren ikusgaitasuna aldatu ahal izango duzu. + setting_default_quote_policy_private: Jarraitzaileentzat soilik sortutako bidalketak Mastodonen ezin dituzte beste batzuek aipatu. + setting_default_quote_policy_unlisted: Jendeak aipatzen zaituenean, bere bidalketa ere joeren denbora-lerro publikoetatik ezkutatuko da. setting_default_sensitive: Multimedia hunkigarria lehenetsita ezkutatzen da, eta sakatuz ikusi daiteke setting_display_media_default: Ezkutatu hunkigarri gisa markatutako multimedia setting_display_media_hide_all: Ezkutatu multimedia guztia beti @@ -74,6 +78,7 @@ eu: featured_tag: name: 'Hemen dituzu azkenaldian gehien erabili dituzun traoletako batzuk:' filters: + action: Aukeratu ze ekintza burutu behar den bidalketa bat iragazkiarekin bat datorrenean actions: blur: Ezkutatu edukia ohar baten atzean, testua bera ezkutatu gabe hide: Ezkutatu erabat iragazitako edukia, existituko ez balitz bezala @@ -82,6 +87,7 @@ eu: activity_api_enabled: Lokalki argitaratutako bidalketak, erabiltzaile aktiboak, eta izen-emateen kopuruak astero zenbatzen ditu app_icon: WEBP, PNG, GIF edo JPG. Aplikazioaren ikono lehenetsia gainidazten du ikono pertsonalizatu batekin gailu mugikorretan. backups_retention_period: Erabiltzaileek geroago deskarga dezaketen beren argitalpenen artxiboak sor ditzakete. Balio positibo bat ezartzean, artxibo hauek biltegiratzetik automatikoki ezabatuko dira zehazturiko egunen buruan. + bootstrap_timeline_accounts: Erabiltzaile berrien jarraipenerako gomendioen goiko aldean agertuko dira kontu horiek. Eman komaz bereizitako kontuen zerrenda. closed_registrations_message: Izen-ematea itxia dagoenean bistaratua content_cache_retention_period: Beste zerbitzarietako argitalpen guztiak (bultzadak eta erantzunak barne) ezabatuko dira zehazturiko egunen buruan, argitalpen horiek izan ditzaketen erabiltzaile lokalaren interakzioa kontuan izanik gabe. Instantzia desberdinetako erabiltzaileen arteko aipamen pribatuak ere galdu egingo dira eta ezin izango dira berreskuratu. Ezarpen honen erabilera xede berezia duten instantziei zuzendua dago eta erabiltzaileen itxaropena hausten da orotariko erabilerarako inplementatzean. custom_css: Estilo pertsonalizatuak aplikatu ditzakezu Mastodonen web bertsioan. @@ -103,6 +109,7 @@ eu: thumbnail: Zerbitzariaren informazioaren ondoan erakusten den 2:1 inguruko irudia. trendable_by_default: Saltatu joeretako edukiaren eskuzko berrikuspena. Ondoren elementuak banan-bana kendu daitezke joeretatik. trends: Joeretan zure zerbitzarian bogan dauden bidalketa, traola eta albisteak erakusten dira. + wrapstodon: Bertako erabiltzaileei Mastodonen urteko erabileraren laburpen ludiko bat sortzea eskaini. Ezaugarri hori urte bakoitzeko abenduaren 10etik 31ra bitartean dago eskuragarri, eta urtean gutxienez hashtag bat erabili duten erabiltzaileei eskaintzen zaie. form_challenge: current_password: Zonalde seguruan sartzen ari zara imports: @@ -137,14 +144,23 @@ eu: admin_email: Legezko abisuak, kontraindikazioak, agindu judizialak, erretiratzeko eskaerak eta legea betetzeko eskaerak barne. arbitration_address: Goiko helbide fisikoa edo "N/A" bera izan daiteke posta elektronikoa erabiliz gero. arbitration_website: Web formularioa izan daiteke, edo "N/A" posta elektronikoa erabiliz gero. + choice_of_law: Edozein gatazka juridiko gobernatuko duten epaitegien hiria, eskualdea, lurraldea edo estatua. + dmca_email: Goiko "Lege-oharretarako helbide elektronikoa" atalean erabilitako helbide elektroniko bera izan daiteke. + domain: Ematen ari zaren lineako zerbitzuaren identifikazio bakarra. + jurisdiction: Zerrendatu fakturak ordaintzen dituen pertsona bizi den herrialdea. Enpresa edo bestelako erakunde bat bada, adierazi egoitza duen herrialdea eta, kasuan kasu, hiria, eskualdea, lurraldea edo estatua. + min_age: Ez luke izan behar zure jurisdikzioko legeek eskatzen duten gutxieneko adinetik beherakoa. user: chosen_languages: Markatzean, hautatutako hizkuntzetan dauden tutak besterik ez dira erakutsiko. + role: Rolak erabiltzaileak dituen baimenak zeintzuk diren kontrolatzen du. user_role: color: Rolarentzat erabiltzaile interfazean erabiliko den kolorea, formatu hamaseitarreko RGB bezala highlighted: Honek rola publikoki ikusgai jartzen du name: Rolaren izen publikoa, rola bereizgarri bezala bistaratzeko ezarrita badago permissions_as_keys: Rol hau duten erabiltzaileek sarbidea izango dute... position: Maila goreneko rolak erabakitzen du gatazkaren konponbidea kasu batzuetan. Ekintza batzuk maila baxuagoko rolen gain bakarrik gauzatu daitezke + username_block: + allow_with_approval: Izena ematea zuzenean eragotzi beharrean, bat datozen erregistroek zure onarpena beharko dute + comparison: Kontuan izan 'Scunthorpe arazoa' hitz-zatiak blokeatzean webhook: events: Hautatu gertaerak bidaltzeko template: Osatu zure JSON karga interpolazio aldakorra erabiliz. Utzi hutsik JSON lehenetsiarentzat. @@ -215,17 +231,26 @@ eu: setting_aggregate_reblogs: Taldekatu bultzadak denbora-lerroetan setting_always_send_emails: Bidali beti eposta jakinarazpenak setting_auto_play_gif: Erreproduzitu GIF animatuak automatikoki + setting_boost_modal: Bultzaden ikusgaitasun-kontrola setting_default_language: Argitalpenen hizkuntza + setting_default_privacy: Bidalketarako ikusgarritasuna + setting_default_quote_policy: Nork aipa dezake setting_default_sensitive: Beti markatu edukiak hunkigarri gisa + setting_delete_modal: Eman abisua argitalpen bat ezabatu aurretik + setting_disable_hover_cards: Desgaitu profilaren aurrebista gainetik igarotzean setting_disable_swiping: Desgaitu hatza pasatzeko mugimenduak setting_display_media: Multimedia bistaratzea setting_display_media_default: Lehenetsia setting_display_media_hide_all: Ezkutatu guztia setting_display_media_show_all: Erakutsi guztia + setting_emoji_style: Emojien estiloa setting_expand_spoilers: Zabaldu beti edukiaren abisuak dituzten argitalpenak setting_hide_network: Ezkutatu zure sarea + setting_missing_alt_text_modal: Eman abisua testu alternatiborik gabeko multimedia-edukia argitaratu aurretik + setting_quick_boosting: Gaitu bultzada azkarra setting_reduce_motion: Murriztu animazioen mugimenduak setting_system_font_ui: Erabili sistemako tipografia lehenetsia + setting_system_scrollbars_ui: Erabili sistemako desplazamendu-barra lehenetsia setting_theme: Gunearen azala setting_trends: Erakutsi gaurko joerak setting_unfollow_modal: Erakutsi baieztapen elkarrizketa-koadroa inor jarraitzeari utzi aurretik @@ -244,6 +269,7 @@ eu: name: Traola filters: actions: + blur: Ezkutatu multimedia-edukia ohar batekin hide: Ezkutatu guztiz warn: Ezkutatu ohar batekin form_admin_settings: @@ -255,12 +281,17 @@ eu: content_cache_retention_period: Urruneko edukiaren atxikipen-aldia custom_css: CSS pertsonalizatua favicon: Gune-ikurra + landing_page: Bisitari berrientzako harrera-orria + local_live_feed_access: Tokiko argitalpenak nabarmentzen dituzten zuzeneko jarioetara sarbidea + local_topic_feed_access: Tokiko argitalpenak nabarmentzen dituzten traola eta esteketara sarbidea mascot: Maskota pertsonalizatua (zaharkitua) media_cache_retention_period: Multimediaren cachea atxikitzeko epea min_age: Gutxieneko adin-eskakizuna peers_api_enabled: Argitaratu aurkitutako zerbitzarien zerrenda APIan profile_directory: Gaitu profil-direktorioa registrations_mode: Nork eman dezake izena + remote_live_feed_access: Urruneko argitalpenak nabarmentzen dituzten zuzeneko jarioetara sarbidea + remote_topic_feed_access: Urruneko argitalpenak nabarmentzen dituzten traola eta esteketara sarbidea require_invite_text: Eskatu arrazoi bat batzeko show_domain_blocks: Erakutsi domeinu-blokeoak show_domain_blocks_rationale: Erakutsi domeinuak zergatik blokeatu ziren @@ -275,6 +306,7 @@ eu: thumbnail: Zerbitzariaren koadro txikia trendable_by_default: Onartu joerak aurrez berrikusi gabe trends: Gaitu joerak + wrapstodon: Gaitu Wrapstodon interactions: must_be_follower: Blokeatu jarraitzaile ez direnen jakinarazpenak must_be_following: Blokeatu zuk jarraitzen ez dituzu horien jakinarazpenak @@ -299,6 +331,7 @@ eu: follow_request: Bidali e-mail bat norbaitek zu jarraitzea eskatzen duenean mention: Bidali e-mail bat norbaitek zu aipatzean pending_account: Bidali e-mail bat kontu bat berrikusi behar denean + quote: Norbaitek aipatu zaitu reblog: Bidali e-mail bat norbaitek zure mezuari bultzada ematen badio report: Salaketa berria bidali da software_updates: @@ -321,11 +354,22 @@ eu: usable: Baimendu bidalketek traola lokal hau erabiltzea terms_of_service: changelog: Zer aldatu da? + effective_date: Indarrean sartzeko data text: Zerbitzuaren baldintzak terms_of_service_generator: + admin_email: Lege-oharretarako helbide elektronikoa + arbitration_address: Arbitraje-jakinarazpenak bidaltzeko helbide fisikoa + arbitration_website: Arbitraje-jakinarazpenak bidaltzeko webgunea + choice_of_law: Aplikatu beharreko legedia + dmca_address: DMCA/egile-eskubideen jakinarazpenetarako helbide fisikoa + dmca_email: DMCA/egile-eskubideen jakinarazpenetarako helbide elektronikoa domain: Domeinua + jurisdiction: Jurisdikzio legala + min_age: Gutxieneko adina user: + date_of_birth_1i: Urtea date_of_birth_2i: Hilabetea + date_of_birth_3i: Eguna role: Rola time_zone: Ordu zona user_role: @@ -334,6 +378,10 @@ eu: name: Izena permissions_as_keys: Baimenak position: Lehentasuna + username_block: + allow_with_approval: Baimendu izen-emateak onarpen bidez + comparison: Konparazio-metodoa + username: Bat etorri beharreko hitza webhook: events: Gertaerak gaituta template: Karga txantiloia diff --git a/config/locales/simple_form.fi.yml b/config/locales/simple_form.fi.yml index a89f4a86aaad9c..a57a5305d88b7d 100644 --- a/config/locales/simple_form.fi.yml +++ b/config/locales/simple_form.fi.yml @@ -312,6 +312,7 @@ fi: thumbnail: Palvelimen pienoiskuva trendable_by_default: Salli trendit ilman ennakkotarkastusta trends: Ota trendit käyttöön + wrapstodon: Ota Wrapstodon käyttöön interactions: must_be_follower: Estä ilmoitukset käyttäjiltä, jotka eivät seuraa sinua must_be_following: Estä ilmoitukset käyttäjiltä, joita et seuraa diff --git a/config/locales/simple_form.fr-CA.yml b/config/locales/simple_form.fr-CA.yml index 265782086c92f8..aec2a254a1ff6a 100644 --- a/config/locales/simple_form.fr-CA.yml +++ b/config/locales/simple_form.fr-CA.yml @@ -111,6 +111,7 @@ fr-CA: thumbnail: Une image d'environ 2:1 affichée à côté des informations de votre serveur. trendable_by_default: Ignorer l'examen manuel du contenu tendance. Des éléments individuels peuvent toujours être supprimés des tendances après coup. trends: Les tendances montrent quelles publications, hashtags et actualités sont en train de gagner en traction sur votre serveur. + wrapstodon: Offrez aux comptes locaux de générer un récapitulatif annuel de leur utilisation de Mastodon. Cette fonctionnalité est disponible chaque année du 10 au 31 décembre, et est accessible pour les comptes ayant publié au moins un message Public ou Public discret et utilisé au moins un hashtag dans l'année. form_challenge: current_password: Vous entrez une zone sécurisée imports: @@ -312,6 +313,7 @@ fr-CA: thumbnail: Miniature du serveur trendable_by_default: Autoriser les tendances sans révision préalable trends: Activer les tendances + wrapstodon: Activer Wrapstodon interactions: must_be_follower: Bloquer les notifications des personnes qui ne vous suivent pas must_be_following: Bloquer les notifications des personnes que vous ne suivez pas diff --git a/config/locales/simple_form.fr.yml b/config/locales/simple_form.fr.yml index a40211f36d657a..77f0917fd8ec4e 100644 --- a/config/locales/simple_form.fr.yml +++ b/config/locales/simple_form.fr.yml @@ -111,6 +111,7 @@ fr: thumbnail: Une image d'environ 2:1 affichée à côté des informations de votre serveur. trendable_by_default: Ignorer l'examen manuel du contenu tendance. Des éléments individuels peuvent toujours être supprimés des tendances après coup. trends: Les tendances montrent quels messages, hashtags et actualités gagnent en popularité sur votre serveur. + wrapstodon: Offrez aux comptes locaux de générer un récapitulatif annuel de leur utilisation de Mastodon. Cette fonctionnalité est disponible chaque année du 10 au 31 décembre, et est accessible pour les comptes ayant publié au moins un message Public ou Public discret et utilisé au moins un hashtag dans l'année. form_challenge: current_password: Vous entrez une zone sécurisée imports: @@ -312,6 +313,7 @@ fr: thumbnail: Miniature du serveur trendable_by_default: Autoriser les tendances sans révision préalable trends: Activer les tendances + wrapstodon: Activer Wrapstodon interactions: must_be_follower: Bloquer les notifications des personnes qui ne vous suivent pas must_be_following: Bloquer les notifications des personnes que vous ne suivez pas diff --git a/config/locales/simple_form.ga.yml b/config/locales/simple_form.ga.yml index b3d6081ffd762b..f8f8b09000c944 100644 --- a/config/locales/simple_form.ga.yml +++ b/config/locales/simple_form.ga.yml @@ -111,6 +111,7 @@ ga: thumbnail: Íomhá thart ar 2:1 ar taispeáint taobh le faisnéis do fhreastalaí. trendable_by_default: Léim ar athbhreithniú láimhe ar ábhar treochta. Is féidir míreanna aonair a bhaint as treochtaí fós tar éis an fhíric. trends: Léiríonn treochtaí cé na postálacha, hashtags agus scéalta nuachta atá ag tarraingt ar do fhreastalaí. + wrapstodon: Iarr ar úsáideoirí áitiúla achoimre spraíúil a ghiniúint ar a n-úsáid Mastodon i rith na bliana. Bíonn an ghné seo ar fáil idir an 10ú agus an 31ú Nollaig gach bliain, agus tairgtear é d’úsáideoirí a rinne post Poiblí nó Ciúin Poiblí amháin ar a laghad agus a d’úsáid hais clib amháin ar a laghad laistigh den bhliain. form_challenge: current_password: Tá tú ag dul isteach i limistéar slán imports: @@ -315,6 +316,7 @@ ga: thumbnail: Mionsamhail freastalaí trendable_by_default: Ceadaigh treochtaí gan athbhreithniú roimh ré trends: Cumasaigh treochtaí + wrapstodon: Cumasaigh Wrapstodon interactions: must_be_follower: Cuir bac ar fhógraí ó dhaoine nach leantóirí iad must_be_following: Cuir bac ar fhógraí ó dhaoine nach leanann tú diff --git a/config/locales/simple_form.gl.yml b/config/locales/simple_form.gl.yml index b89696805718c6..f9d896a2fdca96 100644 --- a/config/locales/simple_form.gl.yml +++ b/config/locales/simple_form.gl.yml @@ -111,6 +111,7 @@ gl: thumbnail: Imaxe con proporcións 2:1 mostrada xunto á información sobre o servidor. trendable_by_default: Omitir a revisión manual dos contidos populares. Poderás igualmente eliminar manualmente os elementos que vaian aparecendo. trends: As tendencias mostran publicacións, cancelos e novas historias que teñen popularidade no teu servidor. + wrapstodon: Ofrecerlle ás usuarias locais crear un divertido resumo do seu uso de Mastodon durante o ano. Esta ferramenta está dispoñible entre o 10 e o 31 de Decembro de cada ano, e ofréceselle ás usuarias que publicaron polo menos unha mensaxe Pública ou Pública Limitada e utilizaron polo menos un cancelo durante o ano. form_challenge: current_password: Estás entrando nun área segura imports: @@ -312,6 +313,7 @@ gl: thumbnail: Icona do servidor trendable_by_default: Permitir tendencias sen aprobación previa trends: Activar tendencias + wrapstodon: Activar Wrapstodon interactions: must_be_follower: Bloquea as notificacións de persoas que non te seguen must_be_following: Bloquea as notificacións de persoas que non segues diff --git a/config/locales/simple_form.hu.yml b/config/locales/simple_form.hu.yml index aa118bf5d6cc70..6021d66f6506f9 100644 --- a/config/locales/simple_form.hu.yml +++ b/config/locales/simple_form.hu.yml @@ -111,6 +111,7 @@ hu: thumbnail: Egy durván 2:1 arányú kép, amely a kiszolgálóinformációk mellett jelenik meg. trendable_by_default: Kézi felülvizsgálat kihagyása a felkapott tartalmaknál. Az egyes elemek utólag távolíthatók el a trendek közül. trends: A trendek azt mondják meg, hogy mely bejegyzések, hashtagek és hírbejegyzések felkapottak a kiszolgálódon. + wrapstodon: Kínáld fel a lehetőséget a helyi felhasználóknak, hogy egy vidám összefoglalóban összesíthessék a Mastodon használatukat az év folyamán. Ez a lehetőség minden évben december 10. és 31. között érhető el, azoknak, aki létrehoztak legalább egy nyilvános vagy csendes nyilvános bejegyzést és használtak legalább egy hashtaget az év folyamán. form_challenge: current_password: Beléptél egy biztonsági térben imports: @@ -312,6 +313,7 @@ hu: thumbnail: Kiszolgáló bélyegképe trendable_by_default: Trendek engedélyezése előzetes ellenőrzés nélkül trends: Trendek engedélyezése + wrapstodon: Wrapstodon engedélyezése interactions: must_be_follower: Nem követőidtől érkező értesítések tiltása must_be_following: Nem követettjeidtől érkező értesítések tiltása diff --git a/config/locales/simple_form.is.yml b/config/locales/simple_form.is.yml index b4f034bda4b39c..cffa7449d35731 100644 --- a/config/locales/simple_form.is.yml +++ b/config/locales/simple_form.is.yml @@ -111,6 +111,7 @@ is: thumbnail: Mynd um það bil 2:1 sem birtist samhliða upplýsingum um netþjóninn þinn. trendable_by_default: Sleppa handvirkri yfirferð á vinsælu efni. Áfram verður hægt að fjarlægja stök atriði úr vinsældarlistum. trends: Vinsældir sýna hvaða færslur, myllumerki og fréttasögur séu í umræðunni á netþjóninum þínum. + wrapstodon: Býður notendum á netþjóninum upp á skemmtilega samantekt um notkun þeirra á Mastodon á árinu sem er að líða. Þessi eiginleiki er í boði á milli 10. og 31. desember ár hvert og býðst þeim notendum sem hafa gert að minnsta kosti eina opinbera eða hljóðlega opinbera færslu og notað a. m. k. eitt myllumerki á árinu. form_challenge: current_password: Þú ert að fara inn á öryggissvæði imports: @@ -312,6 +313,7 @@ is: thumbnail: Smámynd vefþjóns trendable_by_default: Leyfa vinsælt efni án undanfarandi yfirferðar trends: Virkja vinsælt + wrapstodon: Virkja Ársuppgjörið interactions: must_be_follower: Loka á tilkynningar frá þeim sem ekki eru fylgjendur must_be_following: Loka á tilkynningar frá þeim sem þú fylgist ekki með diff --git a/config/locales/simple_form.it.yml b/config/locales/simple_form.it.yml index 9dd05272b7366b..98772991814ba7 100644 --- a/config/locales/simple_form.it.yml +++ b/config/locales/simple_form.it.yml @@ -111,6 +111,7 @@ it: thumbnail: Un'immagine approssimativamente 2:1 visualizzata insieme alle informazioni del tuo server. trendable_by_default: Salta la revisione manuale dei contenuti di tendenza. I singoli elementi possono ancora essere rimossi dalle tendenze dopo il fatto. trends: Le tendenze mostrano quali post, hashtag e notizie stanno guadagnando popolarità sul tuo server. + wrapstodon: Offri agli utenti locali la possibilità di generare un riassunto giocoso del loro utilizzo di Mastodon durante l’anno. Questa funzione è disponibile dal 10 al 31 dicembre di ogni anno ed è offerta agli utenti che hanno pubblicato almeno un post pubblico o pubblico silenzioso e utilizzato almeno un hashtag nell’arco dell’anno. form_challenge: current_password: Stai entrando in un'area sicura imports: @@ -312,6 +313,7 @@ it: thumbnail: Miniatura del server trendable_by_default: Consenti le tendenze senza revisione preventiva trends: Abilita le tendenze + wrapstodon: Abilita Wrapstodon interactions: must_be_follower: Blocca notifiche da chi non ti segue must_be_following: Blocca notifiche dalle persone che non segui diff --git a/config/locales/simple_form.pt-PT.yml b/config/locales/simple_form.pt-PT.yml index 608e27a90fbe71..339c48edea8294 100644 --- a/config/locales/simple_form.pt-PT.yml +++ b/config/locales/simple_form.pt-PT.yml @@ -111,6 +111,7 @@ pt-PT: thumbnail: Uma imagem de cerca de 2:1, apresentada ao lado da informação do seu servidor. trendable_by_default: Ignorar a revisão manual do conteúdo em destaque. Os itens individuais poderão ainda assim ser posteriormente removidos das tendências. trends: As tendências mostram quais as publicações, etiquetas e notícias que estão a ganhar destaque no seu servidor. + wrapstodon: Ofereça aos utilizadores locais a possibilidade de gerar um resumo divertido da sua utilização do Mastodon durante o ano. Esta funcionalidade está disponível entre 10 e 31 de Dezembro de cada ano e é oferecida aos utilizadores que fizeram pelo menos uma publicação Pública ou Não listada e utilizaram pelo menos uma etiqueta durante o ano. form_challenge: current_password: Está a entrar numa área segura imports: @@ -312,6 +313,7 @@ pt-PT: thumbnail: Miniatura do servidor trendable_by_default: Permitir tendências sem revisão prévia trends: Ativar destaques + wrapstodon: Ativar Wrapstodon interactions: must_be_follower: Bloquear notificações de não-seguidores must_be_following: Bloquear notificações de pessoas que não segues diff --git a/config/locales/simple_form.sq.yml b/config/locales/simple_form.sq.yml index 346044f7313bf1..acdb944ea3987c 100644 --- a/config/locales/simple_form.sq.yml +++ b/config/locales/simple_form.sq.yml @@ -110,6 +110,7 @@ sq: thumbnail: Një figurë afërsisht 2:1 e shfaqur tok me hollësi mbi shërbyesin tuaj. trendable_by_default: Anashkalo shqyrtim dorazi lënde në modë. Gjëra individuale prapë mund të hiqen nga lëndë në modë pas publikimi. trends: Gjërat në modë shfaqin cilat postime, hashtagë dhe histori të reja po tërheqin vëmendjen në shërbyesin tuaj. + wrapstodon: Jepuni përdoruesve vendorë mundësinë të prodhojnë një përmbledhje lojcake të përdorimit të Mastodon-it prej tyre përgjatë vitit. Kjo veçori është e përdorshme mes 10 dhe 31 dhjetorit të çdo viti dhe u ofrohet përdoruesve që kanë për të paktën një postim Publik, ose Publik të Heshtur dhe që kanë përdorur të paktën një hashtag brenda vitit. form_challenge: current_password: Po hyni në një zonë të sigurt imports: @@ -311,6 +312,7 @@ sq: thumbnail: Miniaturë shërbyesi trendable_by_default: Lejoni gjëra në modë pa shqyrtim paraprak trends: Aktivizo gjëra në modë + wrapstodon: Aktivizo Përmbledhjedon-in interactions: must_be_follower: Blloko njoftime nga jo-ndjekës must_be_following: Blloko njoftime nga persona që s’i ndiqni diff --git a/config/locales/simple_form.sv.yml b/config/locales/simple_form.sv.yml index b7089ede18fd68..7699224561f2a3 100644 --- a/config/locales/simple_form.sv.yml +++ b/config/locales/simple_form.sv.yml @@ -305,6 +305,7 @@ sv: thumbnail: Serverns tumnagelbild trendable_by_default: Tillåt trender utan föregående granskning trends: Aktivera trender + wrapstodon: Aktivera Wrapstodon interactions: must_be_follower: Blockera notiser från icke-följare must_be_following: Blockera notiser från personer du inte följer diff --git a/config/locales/simple_form.vi.yml b/config/locales/simple_form.vi.yml index 2c84279da2ed64..027f00bf8b6887 100644 --- a/config/locales/simple_form.vi.yml +++ b/config/locales/simple_form.vi.yml @@ -111,6 +111,7 @@ vi: thumbnail: 'Một hình ảnh tỉ lệ 2: 1 được hiển thị cùng với thông tin máy chủ của bạn.' trendable_by_default: Bỏ qua việc duyệt thủ công nội dung xu hướng. Các mục riêng lẻ vẫn có thể bị xóa khỏi xu hướng sau này. trends: Hiển thị những tút, hashtag và tin tức đang được thảo luận nhiều trên máy chủ của bạn. + wrapstodon: Cho phép người dùng máy chủ tạo bản tóm tắt vui nhộn về việc sử dụng Mastodon của họ trong năm. Tính năng này có sẵn từ ngày 10 đến ngày 31 tháng 12 hàng năm, và được cung cấp cho người dùng đã đăng ít nhất một tút Công khai hoặc Riêng tư và sử dụng ít nhất một hashtag trong năm. form_challenge: current_password: Biểu mẫu này an toàn imports: @@ -311,6 +312,7 @@ vi: thumbnail: Hình thu nhỏ của máy chủ trendable_by_default: Cho phép lên xu hướng mà không cần duyệt trước trends: Bật xu hướng + wrapstodon: Bật Wrapstodon interactions: must_be_follower: Những người không theo dõi bạn must_be_following: Những người bạn không theo dõi diff --git a/config/locales/simple_form.zh-TW.yml b/config/locales/simple_form.zh-TW.yml index e114ee0d237b7d..f01c2741d3b5a6 100644 --- a/config/locales/simple_form.zh-TW.yml +++ b/config/locales/simple_form.zh-TW.yml @@ -111,6 +111,7 @@ zh-TW: thumbnail: 大約 2:1 圖片會顯示於您伺服器資訊之旁。 trendable_by_default: 跳過手動審核熱門內容。您仍能於登上熱門趨勢後移除個別內容。 trends: 熱門趨勢將顯示於您伺服器上正在吸引大量注意力之嘟文、主題標籤、或新聞。 + wrapstodon: 提供替本站使用者產生他們過去一年使用 Mastodon 的趣味總結。此功能於每年十二月十號至三十一號提供至於年中發過至少一則公開嘟文(無論顯示於時間軸與否)及至少使用一則主題標籤之使用者。 form_challenge: current_password: 您正要進入安全區域 imports: @@ -311,6 +312,7 @@ zh-TW: thumbnail: 伺服器縮圖 trendable_by_default: 允許熱門趨勢直接顯示,不需經過審核 trends: 啟用熱門趨勢 + wrapstodon: 啟用 Mastodon 年度回顧 interactions: must_be_follower: 封鎖非跟隨者的通知 must_be_following: 封鎖您未跟隨之使用者的通知 diff --git a/config/locales/sq.yml b/config/locales/sq.yml index 89eeac7c547b81..6c64d4dec53a5f 100644 --- a/config/locales/sq.yml +++ b/config/locales/sq.yml @@ -840,6 +840,7 @@ sq: publish_statistics: Publiko statistika title: Zbulim trends: Në modë + wrapstodon: Përmbledhjedon domain_blocks: all: Për këdo disabled: Për askënd diff --git a/config/locales/sv.yml b/config/locales/sv.yml index 58fc19951850d7..1f6d68750cb5bc 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -846,6 +846,7 @@ sv: publish_statistics: Publicera statistik title: Upptäck trends: Trender + wrapstodon: Wrapstodon domain_blocks: all: Till alla disabled: För ingen diff --git a/config/locales/vi.yml b/config/locales/vi.yml index 4e4c8c762498ae..035ef775ff0d36 100644 --- a/config/locales/vi.yml +++ b/config/locales/vi.yml @@ -834,6 +834,7 @@ vi: publish_statistics: Công khai số liệu thống kê title: Khám phá trends: Xu hướng + wrapstodon: Wrapstodon domain_blocks: all: Tới mọi người disabled: Không ai diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index 07edf91c9aaaca..7c71c2487adfe5 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -836,6 +836,7 @@ zh-TW: publish_statistics: 公開統計資料 title: 探索 trends: 熱門趨勢 + wrapstodon: Mastodon 年度回顧 domain_blocks: all: 至任何人 disabled: 至沒有人 From 38bc7d2864f1bbd007e8814c82d467c08fb116f1 Mon Sep 17 00:00:00 2001 From: Joshua Rogers Date: Thu, 18 Dec 2025 18:11:54 +0800 Subject: [PATCH 835/853] Use HTTPS when downloading unicode.org's emoji-test.txt (#37290) --- lib/tasks/emojis.rake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tasks/emojis.rake b/lib/tasks/emojis.rake index bf43aee439b708..053dfd83bd0063 100644 --- a/lib/tasks/emojis.rake +++ b/lib/tasks/emojis.rake @@ -60,7 +60,7 @@ end namespace :emojis do desc 'Generate a unicode to filename mapping' task :generate do - source = 'http://www.unicode.org/Public/emoji/16.0/emoji-test.txt' + source = 'https://www.unicode.org/Public/emoji/16.0/emoji-test.txt' codes = [] dest = Rails.root.join('app', 'javascript', 'mastodon', 'features', 'emoji', 'emoji_map.json') From ffdf56b1e673e7e7653d9d343f4edf923e7e56f5 Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 18 Dec 2025 15:26:31 +0100 Subject: [PATCH 836/853] Fix default `Admin` role not including `view_feeds` permission (#37301) --- config/roles.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/config/roles.yml b/config/roles.yml index 33d2635f4d40d1..9729cdcdc7f76e 100644 --- a/config/roles.yml +++ b/config/roles.yml @@ -14,6 +14,7 @@ admin: permissions: - view_dashboard - view_audit_log + - view_feeds - manage_users - manage_user_access - delete_user_data From 787b00813eec44feaa61d5786cfe3747b91e94b4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Dec 2025 15:41:35 +0100 Subject: [PATCH 837/853] Update dependency ruby to v3.4.8 (#37278) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .ruby-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ruby-version b/.ruby-version index 2aa51319921198..7921bd0c892723 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.4.7 +3.4.8 From 8bc0170c02477157998abcc1d588e97c7739ef13 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Dec 2025 14:42:07 +0000 Subject: [PATCH 838/853] Update docker.io/ruby Docker tag to v3.4.8 (#37297) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index c64d529918d0b0..865d14402cd88e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,7 +13,7 @@ ARG BASE_REGISTRY="docker.io" # Ruby image to use for base image, change with [--build-arg RUBY_VERSION="3.4.x"] # renovate: datasource=docker depName=docker.io/ruby -ARG RUBY_VERSION="3.4.7" +ARG RUBY_VERSION="3.4.8" # # Node.js version to use in base image, change with [--build-arg NODE_MAJOR_VERSION="22"] # renovate: datasource=node-version depName=node ARG NODE_MAJOR_VERSION="24" From 2a7e5fb3f742b27a08b5d5de4814cd4f6c7cd44a Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 18 Dec 2025 15:42:47 +0100 Subject: [PATCH 839/853] Skip followers synchronization for accounts with 25k followers or more (#37302) --- app/workers/activitypub/distribution_worker.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/workers/activitypub/distribution_worker.rb b/app/workers/activitypub/distribution_worker.rb index 575e110257a577..125278fa51b5ec 100644 --- a/app/workers/activitypub/distribution_worker.rb +++ b/app/workers/activitypub/distribution_worker.rb @@ -1,6 +1,11 @@ # frozen_string_literal: true class ActivityPub::DistributionWorker < ActivityPub::RawDistributionWorker + # Skip followers synchronization for accounts with a large number of followers, + # as this is expensive and people with very large amounts of followers + # necessarily have less control over them to begin with + MAX_FOLLOWERS_FOR_SYNCHRONIZATION = 25_000 + # Distribute a new status or an edit of a status to all the places # where the status is supposed to go or where it was interacted with def perform(status_id) @@ -27,6 +32,6 @@ def activity end def options - { 'synchronize_followers' => @status.private_visibility? } + { 'synchronize_followers' => @status.private_visibility? && @account.followers_count < MAX_FOLLOWERS_FOR_SYNCHRONIZATION } end end From a8109e50fc313b8124a3e471d41b490df59a68b8 Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 18 Dec 2025 17:49:03 +0100 Subject: [PATCH 840/853] Fix custom emojis not displaying in CWs and fav/boost notifications (#37306) --- app/javascript/mastodon/components/content_warning.tsx | 2 +- .../notifications_v2/components/embedded_status_content.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/javascript/mastodon/components/content_warning.tsx b/app/javascript/mastodon/components/content_warning.tsx index a407ec146e3e12..2d3222f479a50c 100644 --- a/app/javascript/mastodon/components/content_warning.tsx +++ b/app/javascript/mastodon/components/content_warning.tsx @@ -31,7 +31,7 @@ export const ContentWarning: React.FC<{ } + extraEmojis={status.get('emojis') as List} /> ); diff --git a/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx b/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx index 845a6902a29dd9..7312a94a302b1d 100644 --- a/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx +++ b/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx @@ -34,7 +34,7 @@ export const EmbeddedStatusContent: React.FC<{ className={className} lang={status.get('language') as string} htmlString={status.get('contentHtml') as string} - extraEmojis={status.get('emoji') as List} + extraEmojis={status.get('emojis') as List} /> ); }; From ba4710debe65e204f28ffd4d105433b26cd6721c Mon Sep 17 00:00:00 2001 From: Echo Date: Thu, 18 Dec 2025 17:58:44 +0100 Subject: [PATCH 841/853] Emoji loading fixes (#37300) --- .../mastodon/features/emoji/database.ts | 13 +- .../mastodon/features/emoji/index.ts | 28 +-- .../mastodon/features/emoji/loader.ts | 162 ++++++++---------- .../mastodon/features/emoji/locale.ts | 32 +++- .../mastodon/features/emoji/render.ts | 13 +- .../mastodon/features/emoji/types.ts | 6 + .../mastodon/features/emoji/worker.ts | 15 +- app/javascript/mastodon/main.tsx | 2 +- 8 files changed, 137 insertions(+), 134 deletions(-) diff --git a/app/javascript/mastodon/features/emoji/database.ts b/app/javascript/mastodon/features/emoji/database.ts index 9e03b53d3c6ad8..fe4010a861d994 100644 --- a/app/javascript/mastodon/features/emoji/database.ts +++ b/app/javascript/mastodon/features/emoji/database.ts @@ -5,11 +5,7 @@ import { openDB } from 'idb'; import { EMOJI_DB_SHORTCODE_TEST } from './constants'; import { toSupportedLocale, toSupportedLocaleOrCustom } from './locale'; -import type { - CustomEmojiData, - UnicodeEmojiData, - LocaleOrCustom, -} from './types'; +import type { CustomEmojiData, UnicodeEmojiData, EtagTypes } from './types'; import { emojiLogger } from './utils'; interface EmojiDB extends LocaleTables, DBSchema { @@ -32,7 +28,7 @@ interface EmojiDB extends LocaleTables, DBSchema { }; }; etags: { - key: LocaleOrCustom; + key: EtagTypes; value: string; }; } @@ -197,10 +193,9 @@ export async function putLegacyShortcodes(shortcodes: ShortcodesDataset) { await trx.done; } -export async function putLatestEtag(etag: string, localeString: string) { - const locale = toSupportedLocaleOrCustom(localeString); +export async function putLatestEtag(etag: string, name: EtagTypes) { const db = await loadDB(); - await db.put('etags', etag, locale); + await db.put('etags', etag, name); } export async function clearEtag(localeString: string) { diff --git a/app/javascript/mastodon/features/emoji/index.ts b/app/javascript/mastodon/features/emoji/index.ts index b0b0fb49b22abb..b134d884415e03 100644 --- a/app/javascript/mastodon/features/emoji/index.ts +++ b/app/javascript/mastodon/features/emoji/index.ts @@ -1,13 +1,9 @@ -import type { Locale } from 'emojibase'; - import { initialState } from '@/mastodon/initial_state'; -import type { EMOJI_DB_NAME_SHORTCODES, EMOJI_TYPE_CUSTOM } from './constants'; +import type { EMOJI_DB_NAME_SHORTCODES } from './constants'; import { toSupportedLocale } from './locale'; import type { LocaleOrCustom } from './types'; import { emojiLogger } from './utils'; -// eslint-disable-next-line import/default -- Importing via worker loader. -import EmojiWorker from './worker?worker&inline'; const userLocale = toSupportedLocale(initialState?.meta.locale ?? 'en'); @@ -18,13 +14,14 @@ const log = emojiLogger('index'); // This is too short, but better to fallback quickly than wait. const WORKER_TIMEOUT = 1_000; -export function initializeEmoji() { +export async function initializeEmoji() { log('initializing emojis'); // Create a temp worker, and assign it to the module-level worker once we know it's ready. let tempWorker: Worker | null = null; if (!worker && 'Worker' in window) { try { + const { default: EmojiWorker } = await import('./worker?worker&inline'); tempWorker = new EmojiWorker(); } catch (err) { console.warn('Error creating web worker:', err); @@ -64,7 +61,7 @@ async function fallbackLoad() { await loadCustomEmoji(); const { importLegacyShortcodes } = await import('./loader'); const shortcodes = await importLegacyShortcodes(); - if (shortcodes.length) { + if (shortcodes?.length) { log('loaded %d legacy shortcodes', shortcodes.length); } await loadEmojiLocale(userLocale); @@ -72,14 +69,11 @@ async function fallbackLoad() { async function loadEmojiLocale(localeString: string) { const locale = toSupportedLocale(localeString); - const { importEmojiData, localeToEmojiPath, localeToShortcodesPath } = - await import('./loader'); + const { importEmojiData } = await import('./loader'); if (worker) { - const path = await localeToEmojiPath(locale); - const shortcodesPath = await localeToShortcodesPath(locale); - log('asking worker to load locale %s from %s', locale, path); - messageWorker(locale, path, shortcodesPath); + log('asking worker to load locale %s', locale); + messageWorker(locale); } else { const emojis = await importEmojiData(locale); if (emojis) { @@ -100,17 +94,11 @@ export async function loadCustomEmoji() { } } -function messageWorker( - locale: typeof EMOJI_TYPE_CUSTOM | typeof EMOJI_DB_NAME_SHORTCODES, -): void; -function messageWorker(locale: Locale, path: string, shortcodes?: string): void; function messageWorker( locale: LocaleOrCustom | typeof EMOJI_DB_NAME_SHORTCODES, - path?: string, - shortcodes?: string, ) { if (!worker) { return; } - worker.postMessage({ locale, path, shortcodes }); + worker.postMessage({ locale }); } diff --git a/app/javascript/mastodon/features/emoji/loader.ts b/app/javascript/mastodon/features/emoji/loader.ts index 0dfa22b99d08d1..c6b64fe29c0d4d 100644 --- a/app/javascript/mastodon/features/emoji/loader.ts +++ b/app/javascript/mastodon/features/emoji/loader.ts @@ -13,46 +13,35 @@ import { putLatestEtag, putLegacyShortcodes, } from './database'; -import { toSupportedLocale, toSupportedLocaleOrCustom } from './locale'; +import { toSupportedLocale, toValidEtagName } from './locale'; import type { CustomEmojiData } from './types'; +import { emojiLogger } from './utils'; -export async function importEmojiData( - localeString: string, - path?: string, - shortcodes: boolean | string = true, -) { +const log = emojiLogger('loader'); + +export async function importEmojiData(localeString: string, shortcodes = true) { const locale = toSupportedLocale(localeString); - // Validate the provided path. - if (path && !/^[/a-z]*\/packs\/assets\/compact-\w+\.json$/.test(path)) { - throw new Error('Invalid path for emoji data'); - } else { - // Otherwise get the path if not provided. - path ??= await localeToEmojiPath(locale); - } + log( + 'importing emoji data for locale %s%s', + locale, + shortcodes ? ' and shortcodes' : '', + ); - const emojis = await fetchAndCheckEtag(locale, path); + const emojis = await fetchAndCheckEtag({ + etagString: locale, + path: localeToEmojiPath(locale), + }); if (!emojis) { return; } const shortcodesData: ShortcodesDataset[] = []; if (shortcodes) { - if ( - typeof shortcodes === 'string' && - !/^[/a-z]*\/packs\/assets\/shortcodes\/cldr\.json$/.test(shortcodes) - ) { - throw new Error('Invalid path for shortcodes data'); - } - const shortcodesPath = - typeof shortcodes === 'string' - ? shortcodes - : await localeToShortcodesPath(locale); - const shortcodesResponse = await fetchAndCheckEtag( - locale, - shortcodesPath, - false, - ); + const shortcodesResponse = await fetchAndCheckEtag({ + etagString: `${locale}-shortcodes`, + path: localeToShortcodesPath(locale), + }); if (shortcodesResponse) { shortcodesData.push(shortcodesResponse); } else { @@ -69,10 +58,10 @@ export async function importEmojiData( } export async function importCustomEmojiData() { - const emojis = await fetchAndCheckEtag( - 'custom', - '/api/v1/custom_emojis', - ); + const emojis = await fetchAndCheckEtag({ + etagString: 'custom', + path: '/api/v1/custom_emojis', + }); if (!emojis) { return; } @@ -81,76 +70,76 @@ export async function importCustomEmojiData() { } export async function importLegacyShortcodes() { - const { default: shortcodesPath } = - await import('emojibase-data/en/shortcodes/iamcal.json?url'); - const response = await fetch(shortcodesPath); - if (!response.ok) { - throw new Error( - `Failed to fetch legacy shortcodes data: ${response.statusText}`, - ); + const globPaths = import.meta.glob( + // We use import.meta.glob to eagerly load the URL, as the regular import() doesn't work inside the Web Worker. + '../../../../../node_modules/emojibase-data/en/shortcodes/iamcal.json', + { eager: true, import: 'default', query: '?url' }, + ); + const path = Object.values(globPaths)[0]; + if (!path) { + throw new Error('IAMCAL shortcodes path not found'); + } + const shortcodesData = await fetchAndCheckEtag({ + checkEtag: true, + etagString: 'shortcodes', + path, + }); + if (!shortcodesData) { + return; } - const shortcodesData = (await response.json()) as ShortcodesDataset; await putLegacyShortcodes(shortcodesData); return Object.keys(shortcodesData); } -const emojiModules = new Map( - Object.entries( - import.meta.glob( - '../../../../../node_modules/emojibase-data/**/compact.json', - { - query: '?url', - import: 'default', - }, - ), - ).map(([key, loader]) => { - const match = /emojibase-data\/([^/]+)\/compact\.json$/.exec(key); - return [match?.at(1) ?? key, loader]; - }), -); - -export function localeToEmojiPath(locale: Locale) { - const path = emojiModules.get(locale); +function localeToEmojiPath(locale: Locale) { + const key = `../../../../../node_modules/emojibase-data/${locale}/compact.json`; + const emojiModules = import.meta.glob( + '../../../../../node_modules/emojibase-data/**/compact.json', + { + query: '?url', + import: 'default', + eager: true, + }, + ); + const path = emojiModules[key]; if (!path) { throw new Error(`Unsupported locale: ${locale}`); } - return path(); + return path; } -const shortcodesModules = new Map( - Object.entries( - import.meta.glob( - '../../../../../node_modules/emojibase-data/**/shortcodes/cldr.json', - { - query: '?url', - import: 'default', - }, - ), - ).map(([key, loader]) => { - const match = /emojibase-data\/([^/]+)\/shortcodes\/cldr\.json$/.exec(key); - return [match?.at(1) ?? key, loader]; - }), -); - -export function localeToShortcodesPath(locale: Locale) { - const path = shortcodesModules.get(locale); +function localeToShortcodesPath(locale: Locale) { + const key = `../../../../../node_modules/emojibase-data/${locale}/shortcodes/cldr.json`; + const shortcodesModules = import.meta.glob( + '../../../../../node_modules/emojibase-data/**/shortcodes/cldr.json', + { + query: '?url', + import: 'default', + eager: true, + }, + ); + const path = shortcodesModules[key]; if (!path) { throw new Error(`Unsupported locale for shortcodes: ${locale}`); } - return path(); + return path; } -export async function fetchAndCheckEtag( - localeString: string, - path: string, - checkEtag = true, -): Promise { - const locale = toSupportedLocaleOrCustom(localeString); +async function fetchAndCheckEtag({ + etagString, + path, + checkEtag = false, +}: { + etagString: string; + path: string; + checkEtag?: boolean; +}): Promise { + const etagName = toValidEtagName(etagString); // Use location.origin as this script may be loaded from a CDN domain. const url = new URL(path, location.origin); - const oldEtag = checkEtag ? await loadLatestEtag(locale) : null; + const oldEtag = checkEtag ? await loadLatestEtag(etagName) : null; const response = await fetch(url, { headers: { 'Content-Type': 'application/json', @@ -163,7 +152,7 @@ export async function fetchAndCheckEtag( } if (!response.ok) { throw new Error( - `Failed to fetch emoji data for ${locale}: ${response.statusText}`, + `Failed to fetch emoji data for ${etagName}: ${response.statusText}`, ); } @@ -172,7 +161,8 @@ export async function fetchAndCheckEtag( // Store the ETag for future requests const etag = response.headers.get('ETag'); if (etag && checkEtag) { - await putLatestEtag(etag, localeString); + log(`storing new etag for ${etagName}: ${etag}`); + await putLatestEtag(etag, etagName); } return data; diff --git a/app/javascript/mastodon/features/emoji/locale.ts b/app/javascript/mastodon/features/emoji/locale.ts index 8ff23f5161a1a4..f39b56d47c22a6 100644 --- a/app/javascript/mastodon/features/emoji/locale.ts +++ b/app/javascript/mastodon/features/emoji/locale.ts @@ -1,7 +1,8 @@ import type { Locale } from 'emojibase'; import { SUPPORTED_LOCALES } from 'emojibase'; -import type { LocaleOrCustom } from './types'; +import { EMOJI_DB_NAME_SHORTCODES, EMOJI_TYPE_CUSTOM } from './constants'; +import type { EtagTypes, LocaleOrCustom, LocaleWithShortcodes } from './types'; export function toSupportedLocale(localeBase: string): Locale { const locale = localeBase.toLowerCase(); @@ -12,12 +13,35 @@ export function toSupportedLocale(localeBase: string): Locale { } export function toSupportedLocaleOrCustom(locale: string): LocaleOrCustom { - if (locale.toLowerCase() === 'custom') { - return 'custom'; + if (locale.toLowerCase() === EMOJI_TYPE_CUSTOM) { + return EMOJI_TYPE_CUSTOM; } return toSupportedLocale(locale); } +export function toValidEtagName(input: string): EtagTypes { + const lower = input.toLowerCase(); + if (lower === EMOJI_TYPE_CUSTOM || lower === EMOJI_DB_NAME_SHORTCODES) { + return lower; + } + + if (isLocaleWithShortcodes(lower)) { + return lower; + } + + return toSupportedLocale(lower); +} + function isSupportedLocale(locale: string): locale is Locale { - return SUPPORTED_LOCALES.includes(locale.toLowerCase() as Locale); + return SUPPORTED_LOCALES.includes(locale as Locale); +} + +function isLocaleWithShortcodes(input: string): input is LocaleWithShortcodes { + const [baseLocale, shortcodes] = input.split('-'); + return ( + !!baseLocale && + !!shortcodes && + isSupportedLocale(baseLocale) && + shortcodes === EMOJI_DB_NAME_SHORTCODES + ); } diff --git a/app/javascript/mastodon/features/emoji/render.ts b/app/javascript/mastodon/features/emoji/render.ts index 38bc7fd7e52129..8fe311014a95c7 100644 --- a/app/javascript/mastodon/features/emoji/render.ts +++ b/app/javascript/mastodon/features/emoji/render.ts @@ -4,12 +4,6 @@ import { EMOJI_TYPE_UNICODE, EMOJI_TYPE_CUSTOM, } from './constants'; -import { - loadEmojiByHexcode, - loadLegacyShortcodesByShortcode, - LocaleNotLoadedError, -} from './database'; -import { importEmojiData } from './loader'; import { emojiToUnicodeHex } from './normalize'; import type { EmojiLoadedState, @@ -121,6 +115,12 @@ export async function loadEmojiDataToState( return null; } + const { + loadLegacyShortcodesByShortcode, + loadEmojiByHexcode, + LocaleNotLoadedError, + } = await import('./database'); + // First, try to load the data from IndexedDB. try { const legacyCode = await loadLegacyShortcodesByShortcode(state.code); @@ -155,6 +155,7 @@ export async function loadEmojiDataToState( state.code, locale, ); + const { importEmojiData } = await import('./loader'); await importEmojiData(locale); // Use this from the loader file as it can be awaited. return loadEmojiDataToState(state, locale, true); } diff --git a/app/javascript/mastodon/features/emoji/types.ts b/app/javascript/mastodon/features/emoji/types.ts index 541fc428e646ec..03002dda6453a4 100644 --- a/app/javascript/mastodon/features/emoji/types.ts +++ b/app/javascript/mastodon/features/emoji/types.ts @@ -7,6 +7,7 @@ import type { CustomEmoji } from '@/mastodon/models/custom_emoji'; import type { RequiredExcept } from '@/mastodon/utils/types'; import type { + EMOJI_DB_NAME_SHORTCODES, EMOJI_MODE_NATIVE, EMOJI_MODE_NATIVE_WITH_FLAGS, EMOJI_MODE_TWEMOJI, @@ -20,6 +21,11 @@ export type EmojiMode = | typeof EMOJI_MODE_TWEMOJI; export type LocaleOrCustom = Locale | typeof EMOJI_TYPE_CUSTOM; +export type LocaleWithShortcodes = `${Locale}-shortcodes`; +export type EtagTypes = + | LocaleOrCustom + | typeof EMOJI_DB_NAME_SHORTCODES + | LocaleWithShortcodes; export interface EmojiAppState { locales: Locale[]; diff --git a/app/javascript/mastodon/features/emoji/worker.ts b/app/javascript/mastodon/features/emoji/worker.ts index 2243678276a58d..5602577dbe9ace 100644 --- a/app/javascript/mastodon/features/emoji/worker.ts +++ b/app/javascript/mastodon/features/emoji/worker.ts @@ -8,24 +8,23 @@ import { addEventListener('message', handleMessage); self.postMessage('ready'); // After the worker is ready, notify the main thread -function handleMessage(event: MessageEvent<{ locale: string; path?: string }>) { +function handleMessage(event: MessageEvent<{ locale: string }>) { const { - data: { locale, path }, + data: { locale }, } = event; - void loadData(locale, path); + void loadData(locale); } -async function loadData(locale: string, path?: string) { +async function loadData(locale: string) { let importCount: number | undefined; if (locale === EMOJI_TYPE_CUSTOM) { importCount = (await importCustomEmojiData())?.length; } else if (locale === EMOJI_DB_NAME_SHORTCODES) { - importCount = (await importLegacyShortcodes()).length; - } else if (path) { - importCount = (await importEmojiData(locale, path))?.length; + importCount = (await importLegacyShortcodes())?.length; } else { - throw new Error('Path is required for loading locale emoji data'); + importCount = (await importEmojiData(locale))?.length; } + if (importCount) { self.postMessage(`loaded ${importCount} emojis into ${locale}`); } diff --git a/app/javascript/mastodon/main.tsx b/app/javascript/mastodon/main.tsx index 5d1d0aa5136ddb..965645f9e69d5e 100644 --- a/app/javascript/mastodon/main.tsx +++ b/app/javascript/mastodon/main.tsx @@ -30,7 +30,7 @@ function main() { } const { initializeEmoji } = await import('./features/emoji/index'); - initializeEmoji(); + await initializeEmoji(); const root = createRoot(mountNode); root.render(); From 4bfd92310fcf2be53e3157de29b01218f00eb594 Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 18 Dec 2025 17:49:03 +0100 Subject: [PATCH 842/853] [Glitch] Fix custom emojis not displaying in CWs and fav/boost notifications Port a8109e50fc313b8124a3e471d41b490df59a68b8 to glitch-soc Signed-off-by: Claire --- app/javascript/flavours/glitch/components/content_warning.tsx | 2 +- .../notifications_v2/components/embedded_status_content.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/javascript/flavours/glitch/components/content_warning.tsx b/app/javascript/flavours/glitch/components/content_warning.tsx index f3535b9fb584e6..a2a27849b16929 100644 --- a/app/javascript/flavours/glitch/components/content_warning.tsx +++ b/app/javascript/flavours/glitch/components/content_warning.tsx @@ -41,7 +41,7 @@ export const ContentWarning: React.FC<{ } + extraEmojis={status.get('emojis') as List} /> ); diff --git a/app/javascript/flavours/glitch/features/notifications_v2/components/embedded_status_content.tsx b/app/javascript/flavours/glitch/features/notifications_v2/components/embedded_status_content.tsx index 0c9a96fccaa2fe..52e719ec63bae3 100644 --- a/app/javascript/flavours/glitch/features/notifications_v2/components/embedded_status_content.tsx +++ b/app/javascript/flavours/glitch/features/notifications_v2/components/embedded_status_content.tsx @@ -34,7 +34,7 @@ export const EmbeddedStatusContent: React.FC<{ className={className} lang={status.get('language') as string} htmlString={status.get('contentHtml') as string} - extraEmojis={status.get('emoji') as List} + extraEmojis={status.get('emojis') as List} /> ); }; From ff20ab7510a189bee75bdd5460f6c2ae38e7009a Mon Sep 17 00:00:00 2001 From: Echo Date: Thu, 18 Dec 2025 18:41:21 +0100 Subject: [PATCH 843/853] Fixes CDN domain loading (#37310) --- vite.config.mts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/vite.config.mts b/vite.config.mts index f27941e5a4fdd5..0a10b30a5b32ef 100644 --- a/vite.config.mts +++ b/vite.config.mts @@ -156,6 +156,14 @@ export const config: UserConfigFnPromise = async ({ mode, command }) => { }, }, }, + experimental: { + /** + * Setting this causes Vite to not rely on the base config for import URLs, + * and instead uses import.meta.url, which is what we want for proper CDN support. + * @see https://github.com/mastodon/mastodon/pull/37310 + */ + renderBuiltUrl: () => undefined, + }, worker: { format: 'es', }, From 9ce81baff95bce646af976e1f9b4b452d936929e Mon Sep 17 00:00:00 2001 From: Echo Date: Thu, 18 Dec 2025 17:58:44 +0100 Subject: [PATCH 844/853] [Glitch] Emoji loading fixes Port ba4710debe65e204f28ffd4d105433b26cd6721c to glitch-soc Signed-off-by: Claire --- .../glitch/features/emoji/database.ts | 13 +- .../flavours/glitch/features/emoji/index.ts | 28 +-- .../flavours/glitch/features/emoji/loader.ts | 162 ++++++++---------- .../flavours/glitch/features/emoji/locale.ts | 32 +++- .../flavours/glitch/features/emoji/render.ts | 13 +- .../flavours/glitch/features/emoji/types.ts | 6 + .../flavours/glitch/features/emoji/worker.ts | 15 +- app/javascript/flavours/glitch/main.tsx | 2 +- 8 files changed, 137 insertions(+), 134 deletions(-) diff --git a/app/javascript/flavours/glitch/features/emoji/database.ts b/app/javascript/flavours/glitch/features/emoji/database.ts index 9e03b53d3c6ad8..fe4010a861d994 100644 --- a/app/javascript/flavours/glitch/features/emoji/database.ts +++ b/app/javascript/flavours/glitch/features/emoji/database.ts @@ -5,11 +5,7 @@ import { openDB } from 'idb'; import { EMOJI_DB_SHORTCODE_TEST } from './constants'; import { toSupportedLocale, toSupportedLocaleOrCustom } from './locale'; -import type { - CustomEmojiData, - UnicodeEmojiData, - LocaleOrCustom, -} from './types'; +import type { CustomEmojiData, UnicodeEmojiData, EtagTypes } from './types'; import { emojiLogger } from './utils'; interface EmojiDB extends LocaleTables, DBSchema { @@ -32,7 +28,7 @@ interface EmojiDB extends LocaleTables, DBSchema { }; }; etags: { - key: LocaleOrCustom; + key: EtagTypes; value: string; }; } @@ -197,10 +193,9 @@ export async function putLegacyShortcodes(shortcodes: ShortcodesDataset) { await trx.done; } -export async function putLatestEtag(etag: string, localeString: string) { - const locale = toSupportedLocaleOrCustom(localeString); +export async function putLatestEtag(etag: string, name: EtagTypes) { const db = await loadDB(); - await db.put('etags', etag, locale); + await db.put('etags', etag, name); } export async function clearEtag(localeString: string) { diff --git a/app/javascript/flavours/glitch/features/emoji/index.ts b/app/javascript/flavours/glitch/features/emoji/index.ts index 44c84db3218561..77142326059639 100644 --- a/app/javascript/flavours/glitch/features/emoji/index.ts +++ b/app/javascript/flavours/glitch/features/emoji/index.ts @@ -1,13 +1,9 @@ -import type { Locale } from 'emojibase'; - import { initialState } from '@/flavours/glitch/initial_state'; -import type { EMOJI_DB_NAME_SHORTCODES, EMOJI_TYPE_CUSTOM } from './constants'; +import type { EMOJI_DB_NAME_SHORTCODES } from './constants'; import { toSupportedLocale } from './locale'; import type { LocaleOrCustom } from './types'; import { emojiLogger } from './utils'; -// eslint-disable-next-line import/default -- Importing via worker loader. -import EmojiWorker from './worker?worker&inline'; const userLocale = toSupportedLocale(initialState?.meta.locale ?? 'en'); @@ -18,13 +14,14 @@ const log = emojiLogger('index'); // This is too short, but better to fallback quickly than wait. const WORKER_TIMEOUT = 1_000; -export function initializeEmoji() { +export async function initializeEmoji() { log('initializing emojis'); // Create a temp worker, and assign it to the module-level worker once we know it's ready. let tempWorker: Worker | null = null; if (!worker && 'Worker' in window) { try { + const { default: EmojiWorker } = await import('./worker?worker&inline'); tempWorker = new EmojiWorker(); } catch (err) { console.warn('Error creating web worker:', err); @@ -64,7 +61,7 @@ async function fallbackLoad() { await loadCustomEmoji(); const { importLegacyShortcodes } = await import('./loader'); const shortcodes = await importLegacyShortcodes(); - if (shortcodes.length) { + if (shortcodes?.length) { log('loaded %d legacy shortcodes', shortcodes.length); } await loadEmojiLocale(userLocale); @@ -72,14 +69,11 @@ async function fallbackLoad() { async function loadEmojiLocale(localeString: string) { const locale = toSupportedLocale(localeString); - const { importEmojiData, localeToEmojiPath, localeToShortcodesPath } = - await import('./loader'); + const { importEmojiData } = await import('./loader'); if (worker) { - const path = await localeToEmojiPath(locale); - const shortcodesPath = await localeToShortcodesPath(locale); - log('asking worker to load locale %s from %s', locale, path); - messageWorker(locale, path, shortcodesPath); + log('asking worker to load locale %s', locale); + messageWorker(locale); } else { const emojis = await importEmojiData(locale); if (emojis) { @@ -100,17 +94,11 @@ export async function loadCustomEmoji() { } } -function messageWorker( - locale: typeof EMOJI_TYPE_CUSTOM | typeof EMOJI_DB_NAME_SHORTCODES, -): void; -function messageWorker(locale: Locale, path: string, shortcodes?: string): void; function messageWorker( locale: LocaleOrCustom | typeof EMOJI_DB_NAME_SHORTCODES, - path?: string, - shortcodes?: string, ) { if (!worker) { return; } - worker.postMessage({ locale, path, shortcodes }); + worker.postMessage({ locale }); } diff --git a/app/javascript/flavours/glitch/features/emoji/loader.ts b/app/javascript/flavours/glitch/features/emoji/loader.ts index 51fd2eafaf0fe1..014355d884ffbc 100644 --- a/app/javascript/flavours/glitch/features/emoji/loader.ts +++ b/app/javascript/flavours/glitch/features/emoji/loader.ts @@ -13,46 +13,35 @@ import { putLatestEtag, putLegacyShortcodes, } from './database'; -import { toSupportedLocale, toSupportedLocaleOrCustom } from './locale'; +import { toSupportedLocale, toValidEtagName } from './locale'; import type { CustomEmojiData } from './types'; +import { emojiLogger } from './utils'; -export async function importEmojiData( - localeString: string, - path?: string, - shortcodes: boolean | string = true, -) { +const log = emojiLogger('loader'); + +export async function importEmojiData(localeString: string, shortcodes = true) { const locale = toSupportedLocale(localeString); - // Validate the provided path. - if (path && !/^[/a-z]*\/packs\/assets\/compact-\w+\.json$/.test(path)) { - throw new Error('Invalid path for emoji data'); - } else { - // Otherwise get the path if not provided. - path ??= await localeToEmojiPath(locale); - } + log( + 'importing emoji data for locale %s%s', + locale, + shortcodes ? ' and shortcodes' : '', + ); - const emojis = await fetchAndCheckEtag(locale, path); + const emojis = await fetchAndCheckEtag({ + etagString: locale, + path: localeToEmojiPath(locale), + }); if (!emojis) { return; } const shortcodesData: ShortcodesDataset[] = []; if (shortcodes) { - if ( - typeof shortcodes === 'string' && - !/^[/a-z]*\/packs\/assets\/shortcodes\/cldr\.json$/.test(shortcodes) - ) { - throw new Error('Invalid path for shortcodes data'); - } - const shortcodesPath = - typeof shortcodes === 'string' - ? shortcodes - : await localeToShortcodesPath(locale); - const shortcodesResponse = await fetchAndCheckEtag( - locale, - shortcodesPath, - false, - ); + const shortcodesResponse = await fetchAndCheckEtag({ + etagString: `${locale}-shortcodes`, + path: localeToShortcodesPath(locale), + }); if (shortcodesResponse) { shortcodesData.push(shortcodesResponse); } else { @@ -69,10 +58,10 @@ export async function importEmojiData( } export async function importCustomEmojiData() { - const emojis = await fetchAndCheckEtag( - 'custom', - '/api/v1/custom_emojis', - ); + const emojis = await fetchAndCheckEtag({ + etagString: 'custom', + path: '/api/v1/custom_emojis', + }); if (!emojis) { return; } @@ -81,76 +70,76 @@ export async function importCustomEmojiData() { } export async function importLegacyShortcodes() { - const { default: shortcodesPath } = - await import('emojibase-data/en/shortcodes/iamcal.json?url'); - const response = await fetch(shortcodesPath); - if (!response.ok) { - throw new Error( - `Failed to fetch legacy shortcodes data: ${response.statusText}`, - ); + const globPaths = import.meta.glob( + // We use import.meta.glob to eagerly load the URL, as the regular import() doesn't work inside the Web Worker. + '../../../../../../node_modules/emojibase-data/en/shortcodes/iamcal.json', + { eager: true, import: 'default', query: '?url' }, + ); + const path = Object.values(globPaths)[0]; + if (!path) { + throw new Error('IAMCAL shortcodes path not found'); + } + const shortcodesData = await fetchAndCheckEtag({ + checkEtag: true, + etagString: 'shortcodes', + path, + }); + if (!shortcodesData) { + return; } - const shortcodesData = (await response.json()) as ShortcodesDataset; await putLegacyShortcodes(shortcodesData); return Object.keys(shortcodesData); } -const emojiModules = new Map( - Object.entries( - import.meta.glob( - '../../../../../../node_modules/emojibase-data/**/compact.json', - { - query: '?url', - import: 'default', - }, - ), - ).map(([key, loader]) => { - const match = /emojibase-data\/([^/]+)\/compact\.json$/.exec(key); - return [match?.at(1) ?? key, loader]; - }), -); - -export function localeToEmojiPath(locale: Locale) { - const path = emojiModules.get(locale); +function localeToEmojiPath(locale: Locale) { + const key = `../../../../../../node_modules/emojibase-data/${locale}/compact.json`; + const emojiModules = import.meta.glob( + '../../../../../../node_modules/emojibase-data/**/compact.json', + { + query: '?url', + import: 'default', + eager: true, + }, + ); + const path = emojiModules[key]; if (!path) { throw new Error(`Unsupported locale: ${locale}`); } - return path(); + return path; } -const shortcodesModules = new Map( - Object.entries( - import.meta.glob( - '../../../../../../node_modules/emojibase-data/**/shortcodes/cldr.json', - { - query: '?url', - import: 'default', - }, - ), - ).map(([key, loader]) => { - const match = /emojibase-data\/([^/]+)\/shortcodes\/cldr\.json$/.exec(key); - return [match?.at(1) ?? key, loader]; - }), -); - -export function localeToShortcodesPath(locale: Locale) { - const path = shortcodesModules.get(locale); +function localeToShortcodesPath(locale: Locale) { + const key = `../../../../../../node_modules/emojibase-data/${locale}/shortcodes/cldr.json`; + const shortcodesModules = import.meta.glob( + '../../../../../../node_modules/emojibase-data/**/shortcodes/cldr.json', + { + query: '?url', + import: 'default', + eager: true, + }, + ); + const path = shortcodesModules[key]; if (!path) { throw new Error(`Unsupported locale for shortcodes: ${locale}`); } - return path(); + return path; } -export async function fetchAndCheckEtag( - localeString: string, - path: string, - checkEtag = true, -): Promise { - const locale = toSupportedLocaleOrCustom(localeString); +async function fetchAndCheckEtag({ + etagString, + path, + checkEtag = false, +}: { + etagString: string; + path: string; + checkEtag?: boolean; +}): Promise { + const etagName = toValidEtagName(etagString); // Use location.origin as this script may be loaded from a CDN domain. const url = new URL(path, location.origin); - const oldEtag = checkEtag ? await loadLatestEtag(locale) : null; + const oldEtag = checkEtag ? await loadLatestEtag(etagName) : null; const response = await fetch(url, { headers: { 'Content-Type': 'application/json', @@ -163,7 +152,7 @@ export async function fetchAndCheckEtag( } if (!response.ok) { throw new Error( - `Failed to fetch emoji data for ${locale}: ${response.statusText}`, + `Failed to fetch emoji data for ${etagName}: ${response.statusText}`, ); } @@ -172,7 +161,8 @@ export async function fetchAndCheckEtag( // Store the ETag for future requests const etag = response.headers.get('ETag'); if (etag && checkEtag) { - await putLatestEtag(etag, localeString); + log(`storing new etag for ${etagName}: ${etag}`); + await putLatestEtag(etag, etagName); } return data; diff --git a/app/javascript/flavours/glitch/features/emoji/locale.ts b/app/javascript/flavours/glitch/features/emoji/locale.ts index 8ff23f5161a1a4..f39b56d47c22a6 100644 --- a/app/javascript/flavours/glitch/features/emoji/locale.ts +++ b/app/javascript/flavours/glitch/features/emoji/locale.ts @@ -1,7 +1,8 @@ import type { Locale } from 'emojibase'; import { SUPPORTED_LOCALES } from 'emojibase'; -import type { LocaleOrCustom } from './types'; +import { EMOJI_DB_NAME_SHORTCODES, EMOJI_TYPE_CUSTOM } from './constants'; +import type { EtagTypes, LocaleOrCustom, LocaleWithShortcodes } from './types'; export function toSupportedLocale(localeBase: string): Locale { const locale = localeBase.toLowerCase(); @@ -12,12 +13,35 @@ export function toSupportedLocale(localeBase: string): Locale { } export function toSupportedLocaleOrCustom(locale: string): LocaleOrCustom { - if (locale.toLowerCase() === 'custom') { - return 'custom'; + if (locale.toLowerCase() === EMOJI_TYPE_CUSTOM) { + return EMOJI_TYPE_CUSTOM; } return toSupportedLocale(locale); } +export function toValidEtagName(input: string): EtagTypes { + const lower = input.toLowerCase(); + if (lower === EMOJI_TYPE_CUSTOM || lower === EMOJI_DB_NAME_SHORTCODES) { + return lower; + } + + if (isLocaleWithShortcodes(lower)) { + return lower; + } + + return toSupportedLocale(lower); +} + function isSupportedLocale(locale: string): locale is Locale { - return SUPPORTED_LOCALES.includes(locale.toLowerCase() as Locale); + return SUPPORTED_LOCALES.includes(locale as Locale); +} + +function isLocaleWithShortcodes(input: string): input is LocaleWithShortcodes { + const [baseLocale, shortcodes] = input.split('-'); + return ( + !!baseLocale && + !!shortcodes && + isSupportedLocale(baseLocale) && + shortcodes === EMOJI_DB_NAME_SHORTCODES + ); } diff --git a/app/javascript/flavours/glitch/features/emoji/render.ts b/app/javascript/flavours/glitch/features/emoji/render.ts index 38bc7fd7e52129..8fe311014a95c7 100644 --- a/app/javascript/flavours/glitch/features/emoji/render.ts +++ b/app/javascript/flavours/glitch/features/emoji/render.ts @@ -4,12 +4,6 @@ import { EMOJI_TYPE_UNICODE, EMOJI_TYPE_CUSTOM, } from './constants'; -import { - loadEmojiByHexcode, - loadLegacyShortcodesByShortcode, - LocaleNotLoadedError, -} from './database'; -import { importEmojiData } from './loader'; import { emojiToUnicodeHex } from './normalize'; import type { EmojiLoadedState, @@ -121,6 +115,12 @@ export async function loadEmojiDataToState( return null; } + const { + loadLegacyShortcodesByShortcode, + loadEmojiByHexcode, + LocaleNotLoadedError, + } = await import('./database'); + // First, try to load the data from IndexedDB. try { const legacyCode = await loadLegacyShortcodesByShortcode(state.code); @@ -155,6 +155,7 @@ export async function loadEmojiDataToState( state.code, locale, ); + const { importEmojiData } = await import('./loader'); await importEmojiData(locale); // Use this from the loader file as it can be awaited. return loadEmojiDataToState(state, locale, true); } diff --git a/app/javascript/flavours/glitch/features/emoji/types.ts b/app/javascript/flavours/glitch/features/emoji/types.ts index da4b87c23ebe28..d2133ac1db061b 100644 --- a/app/javascript/flavours/glitch/features/emoji/types.ts +++ b/app/javascript/flavours/glitch/features/emoji/types.ts @@ -7,6 +7,7 @@ import type { CustomEmoji } from '@/flavours/glitch/models/custom_emoji'; import type { RequiredExcept } from '@/flavours/glitch/utils/types'; import type { + EMOJI_DB_NAME_SHORTCODES, EMOJI_MODE_NATIVE, EMOJI_MODE_NATIVE_WITH_FLAGS, EMOJI_MODE_TWEMOJI, @@ -20,6 +21,11 @@ export type EmojiMode = | typeof EMOJI_MODE_TWEMOJI; export type LocaleOrCustom = Locale | typeof EMOJI_TYPE_CUSTOM; +export type LocaleWithShortcodes = `${Locale}-shortcodes`; +export type EtagTypes = + | LocaleOrCustom + | typeof EMOJI_DB_NAME_SHORTCODES + | LocaleWithShortcodes; export interface EmojiAppState { locales: Locale[]; diff --git a/app/javascript/flavours/glitch/features/emoji/worker.ts b/app/javascript/flavours/glitch/features/emoji/worker.ts index 2243678276a58d..5602577dbe9ace 100644 --- a/app/javascript/flavours/glitch/features/emoji/worker.ts +++ b/app/javascript/flavours/glitch/features/emoji/worker.ts @@ -8,24 +8,23 @@ import { addEventListener('message', handleMessage); self.postMessage('ready'); // After the worker is ready, notify the main thread -function handleMessage(event: MessageEvent<{ locale: string; path?: string }>) { +function handleMessage(event: MessageEvent<{ locale: string }>) { const { - data: { locale, path }, + data: { locale }, } = event; - void loadData(locale, path); + void loadData(locale); } -async function loadData(locale: string, path?: string) { +async function loadData(locale: string) { let importCount: number | undefined; if (locale === EMOJI_TYPE_CUSTOM) { importCount = (await importCustomEmojiData())?.length; } else if (locale === EMOJI_DB_NAME_SHORTCODES) { - importCount = (await importLegacyShortcodes()).length; - } else if (path) { - importCount = (await importEmojiData(locale, path))?.length; + importCount = (await importLegacyShortcodes())?.length; } else { - throw new Error('Path is required for loading locale emoji data'); + importCount = (await importEmojiData(locale))?.length; } + if (importCount) { self.postMessage(`loaded ${importCount} emojis into ${locale}`); } diff --git a/app/javascript/flavours/glitch/main.tsx b/app/javascript/flavours/glitch/main.tsx index d91cd2bcff633e..144f8501518deb 100644 --- a/app/javascript/flavours/glitch/main.tsx +++ b/app/javascript/flavours/glitch/main.tsx @@ -30,7 +30,7 @@ function main() { } const { initializeEmoji } = await import('./features/emoji/index'); - initializeEmoji(); + await initializeEmoji(); const root = createRoot(mountNode); root.render(); From 6480e16c17d66065596a367977f380a6f2b27313 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Dec 2025 09:13:07 +0100 Subject: [PATCH 845/853] Update dependency sass to v1.97.0 (#37266) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index eeb029e59fb4cf..35963136e20297 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12193,8 +12193,8 @@ __metadata: linkType: hard "sass@npm:^1.62.1, sass@npm:^1.70.0": - version: 1.96.0 - resolution: "sass@npm:1.96.0" + version: 1.97.0 + resolution: "sass@npm:1.97.0" dependencies: "@parcel/watcher": "npm:^2.4.1" chokidar: "npm:^4.0.0" @@ -12205,7 +12205,7 @@ __metadata: optional: true bin: sass: sass.js - checksum: 10c0/a932054bcee6935757417af6072d31b65ce3557798a53351b3e1369d7f06e24b0ec211e1617bdaaee998b429a44bf0f52acd240fd47f88422d5bc241eeb71672 + checksum: 10c0/4c0e2596131054089beeeb6e98f7318beb909c4775187690656cbb85a45153d04eecd970e6a4431fe47dc94f9749cf8d58c9c5e59055d2cae39f4887a4bb6104 languageName: node linkType: hard From a505c2efd8fd60e581dd8344eaff64a4b5809f2c Mon Sep 17 00:00:00 2001 From: diondiondion Date: Fri, 19 Dec 2025 09:39:25 +0100 Subject: [PATCH 846/853] Fix mobile admin sidebar displaying under batch table toolbar (#37307) --- app/javascript/styles/mastodon/admin.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss index eaa91936b106c8..7cb5406f098034 100644 --- a/app/javascript/styles/mastodon/admin.scss +++ b/app/javascript/styles/mastodon/admin.scss @@ -164,6 +164,7 @@ $content-width: 840px; width: 100%; max-width: $content-width; flex: 1 1 auto; + isolation: isolate; } @media screen and (max-width: ($content-width + $sidebar-width)) { From 77b685e749610642cbc6a521f6689cdbadae223c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Dec 2025 11:07:44 +0100 Subject: [PATCH 847/853] Update dependency vite-tsconfig-paths to v6.0.3 (#37303) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 35963136e20297..5ff0db112b4616 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14069,8 +14069,8 @@ __metadata: linkType: hard "vite-tsconfig-paths@npm:^6.0.0": - version: 6.0.2 - resolution: "vite-tsconfig-paths@npm:6.0.2" + version: 6.0.3 + resolution: "vite-tsconfig-paths@npm:6.0.3" dependencies: debug: "npm:^4.1.1" globrex: "npm:^0.1.2" @@ -14080,7 +14080,7 @@ __metadata: peerDependenciesMeta: vite: optional: true - checksum: 10c0/878189e38a253b699998f94706b15718a03d59467b091e064f33090240f9ccfa4bf273c3b30b5f9711822c56a58b786c3e6c6cebb8859e56ec5ab49e360ff8c0 + checksum: 10c0/75cfe470f1ec0e776b2aec1d2e71316d5e1214f485fce7daaed4e4789d6f667881fb85d98129b6463a5b70c7524ef258b401c4871ed8b6318ac45cc892ee778a languageName: node linkType: hard From ff005bae0b97960998700c532a70e813f7d6c7fd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 19 Dec 2025 11:40:07 +0100 Subject: [PATCH 848/853] New Crowdin Translations (automated) (#37312) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/et.json | 27 ++++++++++++++++++++++ app/javascript/mastodon/locales/he.json | 3 +++ app/javascript/mastodon/locales/zh-CN.json | 3 +++ config/locales/he.yml | 1 + config/locales/simple_form.he.yml | 2 ++ config/locales/simple_form.tr.yml | 2 ++ config/locales/simple_form.zh-CN.yml | 2 ++ config/locales/tr.yml | 1 + config/locales/zh-CN.yml | 1 + 9 files changed, 42 insertions(+) diff --git a/app/javascript/mastodon/locales/et.json b/app/javascript/mastodon/locales/et.json index 3ba4bd96572945..d69b7235d2148c 100644 --- a/app/javascript/mastodon/locales/et.json +++ b/app/javascript/mastodon/locales/et.json @@ -114,9 +114,36 @@ "alt_text_modal.done": "Valmis", "announcement.announcement": "Teadaanne", "annual_report.announcement.action_build": "Koosta kokkuvõte minu tegevusest Mastodonis", + "annual_report.announcement.action_dismiss": "Tänan, ei", "annual_report.announcement.action_view": "Vaata kokkuvõtet minu tegevusest Mastodonis", "annual_report.announcement.description": "Vaata teavet oma suhestumise kohta Mastodonis eelmisel aastal.", "annual_report.announcement.title": "{year}. aasta Mastodoni kokkuvõte on valmis", + "annual_report.nav_item.badge": "Uus", + "annual_report.shared_page.donate": "Anneta", + "annual_report.shared_page.footer": "Loodud {heart} Mastodoni meeskonna poolt", + "annual_report.shared_page.footer_server_info": "{username} kasutab {domain}-i, üht paljudest kogukondadest, mis toimivad Mastodonil.", + "annual_report.summary.archetype.booster.desc_public": "{name} jätkas postituste otsimist, et neid edendada, tugevdades teisi loojaid täiusliku täpsusega.", + "annual_report.summary.archetype.booster.desc_self": "Sa jätkasid postituste otsimist, et neid edendada, tugevdades teisi loojaid täiusliku täpsusega.", + "annual_report.summary.archetype.booster.name": "Vibukütt", + "annual_report.summary.archetype.die_drei_fragezeichen": "???", + "annual_report.summary.archetype.lurker.desc_public": "Me teame, et {name} oli kusagil seal väljas ja nautis Mastodoni oma vaiksel moel.", + "annual_report.summary.archetype.lurker.desc_self": "Me teame, et sa olid kusagil seal väljas ja nautisid Mastodoni oma vaiksel moel.", + "annual_report.summary.archetype.lurker.name": "Stoiline", + "annual_report.summary.archetype.oracle.desc_public": "{name} lõi rohkem uusi postitusi kui vastuseid, hoides Mastodoni värskena ja tulevikku suunatuna.", + "annual_report.summary.archetype.oracle.desc_self": "Sa lõid rohkem uusi postitusi kui vastuseid, hoides Mastodoni värskena ja tulevikku suunatuna.", + "annual_report.summary.archetype.oracle.name": "Oraakel", + "annual_report.summary.archetype.pollster.desc_public": "{name} lõi rohkem küsitlusi kui teisi postituse tüüpe, äratades Mastodonis uudishimu.", + "annual_report.summary.archetype.pollster.desc_self": "Sa lõid rohkem küsitlusi kui teisi postituse tüüpe, äratades Mastodonis uudishimu.", + "annual_report.summary.archetype.pollster.name": "Uudishimulik", + "annual_report.summary.archetype.replier.desc_public": "{name} vastas sageli teiste inimeste postitustele, pakkudes Mastodonile uusi aruteluteemasid.", + "annual_report.summary.archetype.replier.desc_self": "Sa vastasid sageli teiste inimeste postitustele, pakkudes Mastodonile uusi aruteluteemasid.", + "annual_report.summary.archetype.replier.name": "Liblikas", + "annual_report.summary.archetype.reveal": "Näita mu põhitüüpi", + "annual_report.summary.archetype.reveal_description": "Täname, et oled Mastodoni liige! Aeg on välja selgitada, millist põhitüüpi sa {year}. kehastasid.", + "annual_report.summary.archetype.title_public": "Kasutaja {name} põhitüüp", + "annual_report.summary.archetype.title_self": "Sinu põhitüüp", + "annual_report.summary.close": "Sule", + "annual_report.summary.copy_link": "Kopeeri link", "annual_report.summary.highlighted_post.title": "Kõige populaarsemad postitused", "annual_report.summary.most_used_app.most_used_app": "enim kasutatud äpp", "annual_report.summary.most_used_hashtag.most_used_hashtag": "enim kasutatud teemaviide", diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json index b2abc99d029bc3..3cee7adc5e12e7 100644 --- a/app/javascript/mastodon/locales/he.json +++ b/app/javascript/mastodon/locales/he.json @@ -121,6 +121,7 @@ "annual_report.nav_item.badge": "חדש", "annual_report.shared_page.donate": "לתרומה", "annual_report.shared_page.footer": "נוצר עם כל ה-{heart} על ידי צוות מסטודון", + "annual_report.shared_page.footer_server_info": "{username} משתמש.ת ב־{domain}, שרת אחד מבין קהילות רבות שבנויות על מסטודון.", "annual_report.summary.archetype.booster.desc_public": "{name} צדו הודעות מעניינות להדהד, והגבירו קולותיהם של יוצרים אחרים בדיוק של חתול המזנק על הטרף.", "annual_report.summary.archetype.booster.desc_self": "צדת הודעות מעניינות להדהד, והגברת קולותיהם של יוצרים אחרים בדיוק של חתול המזנק על הטרף.", "annual_report.summary.archetype.booster.name": "החתול הצייד", @@ -440,6 +441,8 @@ "follow_suggestions.who_to_follow": "אחרי מי לעקוב", "followed_tags": "התגיות שהחשבון שלך עוקב אחריהן", "footer.about": "אודות", + "footer.about_mastodon": "אודות מסטודון", + "footer.about_server": "‮אודות ‭{domain}", "footer.about_this_server": "אודות", "footer.directory": "ספריית פרופילים", "footer.get_app": "להתקנת היישומון", diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json index cb63df5e99c714..232d8ec6774902 100644 --- a/app/javascript/mastodon/locales/zh-CN.json +++ b/app/javascript/mastodon/locales/zh-CN.json @@ -121,6 +121,7 @@ "annual_report.nav_item.badge": "新", "annual_report.shared_page.donate": "捐助", "annual_report.shared_page.footer": "由 Mastodon 团队用 {heart} 生成", + "annual_report.shared_page.footer_server_info": "{username} 使用 {domain},运行 Mastodon 的众多社区之一。", "annual_report.summary.archetype.booster.desc_public": "{name}持续寻找值得转嘟的嘟文,以精准眼光放大其他创作者的影响力。", "annual_report.summary.archetype.booster.desc_self": "你持续寻找值得转嘟的嘟文,以精准眼光放大其他创作者的影响力。", "annual_report.summary.archetype.booster.name": "转发游侠", @@ -440,6 +441,8 @@ "follow_suggestions.who_to_follow": "推荐关注", "followed_tags": "已关注话题", "footer.about": "关于", + "footer.about_mastodon": "关于 Mastodon", + "footer.about_server": "关于 {domain}", "footer.about_this_server": "关于本站", "footer.directory": "用户列表", "footer.get_app": "获取应用", diff --git a/config/locales/he.yml b/config/locales/he.yml index 98baeb601c3cee..f22d5d96074430 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -876,6 +876,7 @@ he: publish_statistics: פרסום הסטטיסטיקות בפומבי title: תגליות trends: נושאים חמים + wrapstodon: סיכומודון domain_blocks: all: לכולם disabled: לאף אחד diff --git a/config/locales/simple_form.he.yml b/config/locales/simple_form.he.yml index cdf1300a4fb9d1..5fcaeb4421ad42 100644 --- a/config/locales/simple_form.he.yml +++ b/config/locales/simple_form.he.yml @@ -111,6 +111,7 @@ he: thumbnail: תמונה ביחס 2:1 בערך שתוצג ליד המידע על השרת שלך. trendable_by_default: לדלג על בדיקה ידנית של התכנים החמים. פריטים ספציפיים עדיין ניתנים להסרה לאחר מעשה. trends: נושאים חמים יציגו אילו הודעות, תגיות וידיעות חדשות צוברות חשיפה על השרת שלך. + wrapstodon: אפשר למשתמשיך המקומיים.ות ליצור סיכום חביב של פעילותם במסטודון בשנה האחרונה. התכונה מאופשרת בין 10 ועד 31 בדצמבר כל שנה, ומצעת למשתמשים שיצרו לפחות הודעה ציבורית אחת והשתמשו לפחות בתגית אחת במשך השנה. form_challenge: current_password: את.ה נכנס. ת לאזור מאובטח imports: @@ -314,6 +315,7 @@ he: thumbnail: תמונה ממוזערת מהשרת trendable_by_default: הרשאה לפריטים להופיע בנושאים החמים ללא אישור מוקדם trends: אפשר פריטים חמים (טרנדים) + wrapstodon: הפעלת סיכומודון interactions: must_be_follower: חסימת התראות משאינם עוקבים must_be_following: חסימת התראות משאינם נעקבים diff --git a/config/locales/simple_form.tr.yml b/config/locales/simple_form.tr.yml index 0e79c05766611b..35df26dc6e57a9 100644 --- a/config/locales/simple_form.tr.yml +++ b/config/locales/simple_form.tr.yml @@ -111,6 +111,7 @@ tr: thumbnail: Sunucu bilginizin yanında gösterilen yaklaşık 2:1'lik görüntü. trendable_by_default: Öne çıkan içeriğin elle incelenmesini atla. Tekil öğeler sonrada öne çıkanlardan kaldırılabilir. trends: Öne çıkanlar, sunucunuzda ilgi toplayan gönderileri, etiketleri ve haber yazılarını gösterir. + wrapstodon: Yerel kullanıcılara, yıl boyunca Mastodon kullanımlarının eğlenceli bir özetini oluşturma imkanı sunun. Bu özellik, her yıl 10 Aralık ile 31 Aralık tarihleri arasında kullanılabilir ve yıl içinde en az bir adet Halka Açık veya Sessiz Halka Açık gönderi paylaşan ve en az bir hashtag kullanan kullanıcılara sunulur. form_challenge: current_password: Güvenli bir bölgeye giriyorsunuz imports: @@ -312,6 +313,7 @@ tr: thumbnail: Sunucu küçük resmi trendable_by_default: Ön incelemesiz öne çıkanlara izin ver trends: Öne çıkanları etkinleştir + wrapstodon: Wrapstodonu Etkinleştir interactions: must_be_follower: Takipçim olmayan kişilerden gelen bildirimleri engelle must_be_following: Takip etmediğim kişilerden gelen bildirimleri engelle diff --git a/config/locales/simple_form.zh-CN.yml b/config/locales/simple_form.zh-CN.yml index d5c4525233a49b..0bc0ffa4135bb3 100644 --- a/config/locales/simple_form.zh-CN.yml +++ b/config/locales/simple_form.zh-CN.yml @@ -111,6 +111,7 @@ zh-CN: thumbnail: 与服务器信息一并展示的约 2:1 比例的图像。 trendable_by_default: 跳过对热门内容的手工审核。个别项目仍可在之后从趋势中删除。 trends: 热门页中会显示正在你服务器上受到关注的嘟文、标签和新闻故事。 + wrapstodon: 为本站用户提供生成他们过去一年使用 Mastodon 情况的趣味总结的功能。此功能在每年12月10日至12月31日提供给这一年发布过至少1条公开嘟文(无论是否设置为在时间线上显示)及至少使用过1个话题标签的用户。 form_challenge: current_password: 你正在进入安全区域 imports: @@ -311,6 +312,7 @@ zh-CN: thumbnail: 本站缩略图 trendable_by_default: 允许在未审核的情况下将话题置为热门 trends: 启用热门 + wrapstodon: 启用 Wrapstodon 年度回顾 interactions: must_be_follower: 屏蔽来自未关注我的用户的通知 must_be_following: 屏蔽来自我未关注的用户的通知 diff --git a/config/locales/tr.yml b/config/locales/tr.yml index 13f1e6a62f7d07..0eb31119e8e8a1 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -848,6 +848,7 @@ tr: publish_statistics: İstatistikleri yayınla title: Keşfet trends: Öne çıkanlar + wrapstodon: Wrapstodon domain_blocks: all: Herkes için disabled: Hiç kimseye diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index 9dffdcd2495e00..87356403d2bc3b 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -834,6 +834,7 @@ zh-CN: publish_statistics: 发布统计数据 title: 发现 trends: 热门 + wrapstodon: Wrapstodon 年度回顾 domain_blocks: all: 对每个人 disabled: 不对任何人 From 06a5199c44c31a920c1ab4d282480e55a4298446 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Dec 2025 14:41:58 +0100 Subject: [PATCH 849/853] Update dependency storybook to v10.1.10 [SECURITY] (#37314) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 413 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 383 insertions(+), 30 deletions(-) diff --git a/yarn.lock b/yarn.lock index 5ff0db112b4616..3fe0024c21aba5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2079,6 +2079,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/aix-ppc64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/aix-ppc64@npm:0.27.2" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/android-arm64@npm:0.25.5": version: 0.25.5 resolution: "@esbuild/android-arm64@npm:0.25.5" @@ -2086,6 +2093,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/android-arm64@npm:0.27.2" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/android-arm@npm:0.25.5": version: 0.25.5 resolution: "@esbuild/android-arm@npm:0.25.5" @@ -2093,6 +2107,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/android-arm@npm:0.27.2" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + "@esbuild/android-x64@npm:0.25.5": version: 0.25.5 resolution: "@esbuild/android-x64@npm:0.25.5" @@ -2100,6 +2121,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-x64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/android-x64@npm:0.27.2" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + "@esbuild/darwin-arm64@npm:0.25.5": version: 0.25.5 resolution: "@esbuild/darwin-arm64@npm:0.25.5" @@ -2107,6 +2135,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-arm64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/darwin-arm64@npm:0.27.2" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/darwin-x64@npm:0.25.5": version: 0.25.5 resolution: "@esbuild/darwin-x64@npm:0.25.5" @@ -2114,6 +2149,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-x64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/darwin-x64@npm:0.27.2" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "@esbuild/freebsd-arm64@npm:0.25.5": version: 0.25.5 resolution: "@esbuild/freebsd-arm64@npm:0.25.5" @@ -2121,6 +2163,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-arm64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/freebsd-arm64@npm:0.27.2" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/freebsd-x64@npm:0.25.5": version: 0.25.5 resolution: "@esbuild/freebsd-x64@npm:0.25.5" @@ -2128,6 +2177,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-x64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/freebsd-x64@npm:0.27.2" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/linux-arm64@npm:0.25.5": version: 0.25.5 resolution: "@esbuild/linux-arm64@npm:0.25.5" @@ -2135,6 +2191,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/linux-arm64@npm:0.27.2" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/linux-arm@npm:0.25.5": version: 0.25.5 resolution: "@esbuild/linux-arm@npm:0.25.5" @@ -2142,6 +2205,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/linux-arm@npm:0.27.2" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + "@esbuild/linux-ia32@npm:0.25.5": version: 0.25.5 resolution: "@esbuild/linux-ia32@npm:0.25.5" @@ -2149,6 +2219,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ia32@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/linux-ia32@npm:0.27.2" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/linux-loong64@npm:0.25.5": version: 0.25.5 resolution: "@esbuild/linux-loong64@npm:0.25.5" @@ -2156,6 +2233,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-loong64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/linux-loong64@npm:0.27.2" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + "@esbuild/linux-mips64el@npm:0.25.5": version: 0.25.5 resolution: "@esbuild/linux-mips64el@npm:0.25.5" @@ -2163,6 +2247,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-mips64el@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/linux-mips64el@npm:0.27.2" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + "@esbuild/linux-ppc64@npm:0.25.5": version: 0.25.5 resolution: "@esbuild/linux-ppc64@npm:0.25.5" @@ -2170,6 +2261,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ppc64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/linux-ppc64@npm:0.27.2" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/linux-riscv64@npm:0.25.5": version: 0.25.5 resolution: "@esbuild/linux-riscv64@npm:0.25.5" @@ -2177,6 +2275,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-riscv64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/linux-riscv64@npm:0.27.2" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + "@esbuild/linux-s390x@npm:0.25.5": version: 0.25.5 resolution: "@esbuild/linux-s390x@npm:0.25.5" @@ -2184,6 +2289,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-s390x@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/linux-s390x@npm:0.27.2" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + "@esbuild/linux-x64@npm:0.25.5": version: 0.25.5 resolution: "@esbuild/linux-x64@npm:0.25.5" @@ -2191,6 +2303,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-x64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/linux-x64@npm:0.27.2" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + "@esbuild/netbsd-arm64@npm:0.25.5": version: 0.25.5 resolution: "@esbuild/netbsd-arm64@npm:0.25.5" @@ -2198,6 +2317,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/netbsd-arm64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/netbsd-arm64@npm:0.27.2" + conditions: os=netbsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/netbsd-x64@npm:0.25.5": version: 0.25.5 resolution: "@esbuild/netbsd-x64@npm:0.25.5" @@ -2205,6 +2331,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/netbsd-x64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/netbsd-x64@npm:0.27.2" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/openbsd-arm64@npm:0.25.5": version: 0.25.5 resolution: "@esbuild/openbsd-arm64@npm:0.25.5" @@ -2212,6 +2345,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/openbsd-arm64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/openbsd-arm64@npm:0.27.2" + conditions: os=openbsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/openbsd-x64@npm:0.25.5": version: 0.25.5 resolution: "@esbuild/openbsd-x64@npm:0.25.5" @@ -2219,6 +2359,20 @@ __metadata: languageName: node linkType: hard +"@esbuild/openbsd-x64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/openbsd-x64@npm:0.27.2" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openharmony-arm64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/openharmony-arm64@npm:0.27.2" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/sunos-x64@npm:0.25.5": version: 0.25.5 resolution: "@esbuild/sunos-x64@npm:0.25.5" @@ -2226,6 +2380,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/sunos-x64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/sunos-x64@npm:0.27.2" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + "@esbuild/win32-arm64@npm:0.25.5": version: 0.25.5 resolution: "@esbuild/win32-arm64@npm:0.25.5" @@ -2233,6 +2394,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-arm64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/win32-arm64@npm:0.27.2" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/win32-ia32@npm:0.25.5": version: 0.25.5 resolution: "@esbuild/win32-ia32@npm:0.25.5" @@ -2240,6 +2408,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-ia32@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/win32-ia32@npm:0.27.2" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/win32-x64@npm:0.25.5": version: 0.25.5 resolution: "@esbuild/win32-x64@npm:0.25.5" @@ -2247,6 +2422,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-x64@npm:0.27.2": + version: 0.27.2 + resolution: "@esbuild/win32-x64@npm:0.27.2" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@eslint-community/eslint-utils@npm:^4.4.0, @eslint-community/eslint-utils@npm:^4.7.0, @eslint-community/eslint-utils@npm:^4.8.0": version: 4.9.0 resolution: "@eslint-community/eslint-utils@npm:4.9.0" @@ -3723,6 +3905,16 @@ __metadata: languageName: node linkType: hard +"@storybook/icons@npm:^2.0.0": + version: 2.0.1 + resolution: "@storybook/icons@npm:2.0.1" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + checksum: 10c0/df2bbf1a5b50f12ab1bf78cae6de4dbf7c49df0e3a5f845553b51b20adbe8386a09fd172ea60342379f9284bb528cba2d0e2659cae6eb8d015cf92c8b32f1222 + languageName: node + linkType: hard + "@storybook/react-dom-shim@npm:10.0.6": version: 10.0.6 resolution: "@storybook/react-dom-shim@npm:10.0.6" @@ -4937,25 +5129,6 @@ __metadata: languageName: node linkType: hard -"@vitest/mocker@npm:3.2.4": - version: 3.2.4 - resolution: "@vitest/mocker@npm:3.2.4" - dependencies: - "@vitest/spy": "npm:3.2.4" - estree-walker: "npm:^3.0.3" - magic-string: "npm:^0.30.17" - peerDependencies: - msw: ^2.4.9 - vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 - peerDependenciesMeta: - msw: - optional: true - vite: - optional: true - checksum: 10c0/f7a4aea19bbbf8f15905847ee9143b6298b2c110f8b64789224cb0ffdc2e96f9802876aa2ca83f1ec1b6e1ff45e822abb34f0054c24d57b29ab18add06536ccd - languageName: node - linkType: hard - "@vitest/mocker@npm:4.0.15": version: 4.0.15 resolution: "@vitest/mocker@npm:4.0.15" @@ -5686,6 +5859,15 @@ __metadata: languageName: node linkType: hard +"bundle-name@npm:^4.1.0": + version: 4.1.0 + resolution: "bundle-name@npm:4.1.0" + dependencies: + run-applescript: "npm:^7.0.0" + checksum: 10c0/8e575981e79c2bcf14d8b1c027a3775c095d362d1382312f444a7c861b0e21513c0bd8db5bd2b16e50ba0709fa622d4eab6b53192d222120305e68359daece29 + languageName: node + linkType: hard + "bytes@npm:^3.1.2, bytes@npm:~3.1.2": version: 3.1.2 resolution: "bytes@npm:3.1.2" @@ -6375,6 +6557,23 @@ __metadata: languageName: node linkType: hard +"default-browser-id@npm:^5.0.0": + version: 5.0.1 + resolution: "default-browser-id@npm:5.0.1" + checksum: 10c0/5288b3094c740ef3a86df9b999b04ff5ba4dee6b64e7b355c0fff5217752c8c86908d67f32f6cba9bb4f9b7b61a1b640c0a4f9e34c57e0ff3493559a625245ee + languageName: node + linkType: hard + +"default-browser@npm:^5.2.1": + version: 5.4.0 + resolution: "default-browser@npm:5.4.0" + dependencies: + bundle-name: "npm:^4.1.0" + default-browser-id: "npm:^5.0.0" + checksum: 10c0/a49ddd0c7b1a319163f64a5fc68ebb45a98548ea23a3155e04518f026173d85cfa2f451b646366c36c8f70b01e4cb773e23d1d22d2c61d8b84e5fbf151b4b609 + languageName: node + linkType: hard + "define-data-property@npm:^1.0.1, define-data-property@npm:^1.1.4": version: 1.1.4 resolution: "define-data-property@npm:1.1.4" @@ -6393,6 +6592,13 @@ __metadata: languageName: node linkType: hard +"define-lazy-prop@npm:^3.0.0": + version: 3.0.0 + resolution: "define-lazy-prop@npm:3.0.0" + checksum: 10c0/5ab0b2bf3fa58b3a443140bbd4cd3db1f91b985cc8a246d330b9ac3fc0b6a325a6d82bddc0b055123d745b3f9931afeea74a5ec545439a1630b9c8512b0eeb49 + languageName: node + linkType: hard + "define-properties@npm:^1.1.3, define-properties@npm:^1.2.1": version: 1.2.1 resolution: "define-properties@npm:1.2.1" @@ -6878,7 +7084,96 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0, esbuild@npm:^0.25.0": +"esbuild@npm:^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0 || ^0.26.0 || ^0.27.0": + version: 0.27.2 + resolution: "esbuild@npm:0.27.2" + dependencies: + "@esbuild/aix-ppc64": "npm:0.27.2" + "@esbuild/android-arm": "npm:0.27.2" + "@esbuild/android-arm64": "npm:0.27.2" + "@esbuild/android-x64": "npm:0.27.2" + "@esbuild/darwin-arm64": "npm:0.27.2" + "@esbuild/darwin-x64": "npm:0.27.2" + "@esbuild/freebsd-arm64": "npm:0.27.2" + "@esbuild/freebsd-x64": "npm:0.27.2" + "@esbuild/linux-arm": "npm:0.27.2" + "@esbuild/linux-arm64": "npm:0.27.2" + "@esbuild/linux-ia32": "npm:0.27.2" + "@esbuild/linux-loong64": "npm:0.27.2" + "@esbuild/linux-mips64el": "npm:0.27.2" + "@esbuild/linux-ppc64": "npm:0.27.2" + "@esbuild/linux-riscv64": "npm:0.27.2" + "@esbuild/linux-s390x": "npm:0.27.2" + "@esbuild/linux-x64": "npm:0.27.2" + "@esbuild/netbsd-arm64": "npm:0.27.2" + "@esbuild/netbsd-x64": "npm:0.27.2" + "@esbuild/openbsd-arm64": "npm:0.27.2" + "@esbuild/openbsd-x64": "npm:0.27.2" + "@esbuild/openharmony-arm64": "npm:0.27.2" + "@esbuild/sunos-x64": "npm:0.27.2" + "@esbuild/win32-arm64": "npm:0.27.2" + "@esbuild/win32-ia32": "npm:0.27.2" + "@esbuild/win32-x64": "npm:0.27.2" + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-arm64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-arm64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/openharmony-arm64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 10c0/cf83f626f55500f521d5fe7f4bc5871bec240d3deb2a01fbd379edc43b3664d1167428738a5aad8794b35d1cca985c44c375b1cd38a2ca613c77ced2c83aafcd + languageName: node + linkType: hard + +"esbuild@npm:^0.25.0": version: 0.25.5 resolution: "esbuild@npm:0.25.5" dependencies: @@ -8549,6 +8844,15 @@ __metadata: languageName: node linkType: hard +"is-docker@npm:^3.0.0": + version: 3.0.0 + resolution: "is-docker@npm:3.0.0" + bin: + is-docker: cli.js + checksum: 10c0/d2c4f8e6d3e34df75a5defd44991b6068afad4835bb783b902fa12d13ebdb8f41b2a199dcb0b5ed2cb78bfee9e4c0bbdb69c2d9646f4106464674d3e697a5856 + languageName: node + linkType: hard + "is-extglob@npm:^2.1.1": version: 2.1.1 resolution: "is-extglob@npm:2.1.1" @@ -8599,6 +8903,17 @@ __metadata: languageName: node linkType: hard +"is-inside-container@npm:^1.0.0": + version: 1.0.0 + resolution: "is-inside-container@npm:1.0.0" + dependencies: + is-docker: "npm:^3.0.0" + bin: + is-inside-container: cli.js + checksum: 10c0/a8efb0e84f6197e6ff5c64c52890fa9acb49b7b74fed4da7c95383965da6f0fa592b4dbd5e38a79f87fc108196937acdbcd758fcefc9b140e479b39ce1fcd1cd + languageName: node + linkType: hard + "is-map@npm:^2.0.3": version: 2.0.3 resolution: "is-map@npm:2.0.3" @@ -8793,6 +9108,15 @@ __metadata: languageName: node linkType: hard +"is-wsl@npm:^3.1.0": + version: 3.1.0 + resolution: "is-wsl@npm:3.1.0" + dependencies: + is-inside-container: "npm:^1.0.0" + checksum: 10c0/d3317c11995690a32c362100225e22ba793678fe8732660c6de511ae71a0ff05b06980cf21f98a6bf40d7be0e9e9506f859abe00a1118287d63e53d0a3d06947 + languageName: node + linkType: hard + "isarray@npm:0.0.1": version: 0.0.1 resolution: "isarray@npm:0.0.1" @@ -10082,6 +10406,18 @@ __metadata: languageName: node linkType: hard +"open@npm:^10.2.0": + version: 10.2.0 + resolution: "open@npm:10.2.0" + dependencies: + default-browser: "npm:^5.2.1" + define-lazy-prop: "npm:^3.0.0" + is-inside-container: "npm:^1.0.0" + wsl-utils: "npm:^0.1.0" + checksum: 10c0/5a36d0c1fd2f74ce553beb427ca8b8494b623fc22c6132d0c1688f246a375e24584ea0b44c67133d9ab774fa69be8e12fbe1ff12504b1142bd960fb09671948f + languageName: node + linkType: hard + "open@npm:^8.0.0": version: 8.4.2 resolution: "open@npm:8.4.2" @@ -12128,6 +12464,13 @@ __metadata: languageName: node linkType: hard +"run-applescript@npm:^7.0.0": + version: 7.1.0 + resolution: "run-applescript@npm:7.1.0" + checksum: 10c0/ab826c57c20f244b2ee807704b1ef4ba7f566aa766481ae5922aac785e2570809e297c69afcccc3593095b538a8a77d26f2b2e9a1d9dffee24e0e039502d1a03 + languageName: node + linkType: hard + "run-parallel@npm:^1.1.9": version: 1.2.0 resolution: "run-parallel@npm:1.2.0" @@ -12746,19 +13089,20 @@ __metadata: linkType: hard "storybook@npm:^10.0.5": - version: 10.0.5 - resolution: "storybook@npm:10.0.5" + version: 10.1.10 + resolution: "storybook@npm:10.1.10" dependencies: "@storybook/global": "npm:^5.0.0" - "@storybook/icons": "npm:^1.6.0" + "@storybook/icons": "npm:^2.0.0" "@testing-library/jest-dom": "npm:^6.6.3" "@testing-library/user-event": "npm:^14.6.1" "@vitest/expect": "npm:3.2.4" - "@vitest/mocker": "npm:3.2.4" "@vitest/spy": "npm:3.2.4" - esbuild: "npm:^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0" + esbuild: "npm:^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0 || ^0.26.0 || ^0.27.0" + open: "npm:^10.2.0" recast: "npm:^0.23.5" semver: "npm:^7.6.2" + use-sync-external-store: "npm:^1.5.0" ws: "npm:^8.18.0" peerDependencies: prettier: ^2 || ^3 @@ -12767,7 +13111,7 @@ __metadata: optional: true bin: storybook: ./dist/bin/dispatcher.js - checksum: 10c0/ea4bcdbc8d793f53970fe2e72de805bfd5b0872d3640f7526bdf42fbe0114f225c09f3683ab011ac08b5240450fd7726f17c5210d929c6f261dadc851ee09eec + checksum: 10c0/beff5472ee86a995cbde2789b2aabd941f823e31ca6957bb4434cb8ee3d3703cf1248e44f4b4d402416a52bfee94677e74f233cc906487901e831e8ab610defa languageName: node linkType: hard @@ -13978,12 +14322,12 @@ __metadata: languageName: node linkType: hard -"use-sync-external-store@npm:^1.4.0": - version: 1.4.0 - resolution: "use-sync-external-store@npm:1.4.0" +"use-sync-external-store@npm:^1.4.0, use-sync-external-store@npm:^1.5.0": + version: 1.6.0 + resolution: "use-sync-external-store@npm:1.6.0" peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - checksum: 10c0/ec011a5055962c0f6b509d6e78c0b143f8cd069890ae370528753053c55e3b360d3648e76cfaa854faa7a59eb08d6c5fb1015e60ffde9046d32f5b2a295acea5 + checksum: 10c0/35e1179f872a53227bdf8a827f7911da4c37c0f4091c29b76b1e32473d1670ebe7bcd880b808b7549ba9a5605c233350f800ffab963ee4a4ee346ee983b6019b languageName: node linkType: hard @@ -14677,6 +15021,15 @@ __metadata: languageName: node linkType: hard +"wsl-utils@npm:^0.1.0": + version: 0.1.0 + resolution: "wsl-utils@npm:0.1.0" + dependencies: + is-wsl: "npm:^3.1.0" + checksum: 10c0/44318f3585eb97be994fc21a20ddab2649feaf1fbe893f1f866d936eea3d5f8c743bec6dc02e49fbdd3c0e69e9b36f449d90a0b165a4f47dd089747af4cf2377 + languageName: node + linkType: hard + "xml-name-validator@npm:^5.0.0": version: 5.0.0 resolution: "xml-name-validator@npm:5.0.0" From f254b4706731fd5921047c7c95f64f71d560d494 Mon Sep 17 00:00:00 2001 From: Echo Date: Fri, 19 Dec 2025 14:43:27 +0100 Subject: [PATCH 850/853] Remove trailing variation selector code for legacy emojis (#37320) --- app/javascript/mastodon/features/emoji/normalize.test.ts | 1 + app/javascript/mastodon/features/emoji/normalize.ts | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/app/javascript/mastodon/features/emoji/normalize.test.ts b/app/javascript/mastodon/features/emoji/normalize.test.ts index b4c766996112c3..8222ab81e588eb 100644 --- a/app/javascript/mastodon/features/emoji/normalize.test.ts +++ b/app/javascript/mastodon/features/emoji/normalize.test.ts @@ -33,6 +33,7 @@ describe('emojiToUnicodeHex', () => { ['⚫', '26AB'], ['🖤', '1F5A4'], ['💀', '1F480'], + ['❤️', '2764'], // Checks for trailing variation selector removal. ['💂‍♂️', '1F482-200D-2642-FE0F'], ] as const)( 'emojiToUnicodeHex converts %s to %s', diff --git a/app/javascript/mastodon/features/emoji/normalize.ts b/app/javascript/mastodon/features/emoji/normalize.ts index 38b01d6905349d..24df808ae1fd6a 100644 --- a/app/javascript/mastodon/features/emoji/normalize.ts +++ b/app/javascript/mastodon/features/emoji/normalize.ts @@ -32,6 +32,12 @@ export function emojiToUnicodeHex(emoji: string): string { codes.push(code); } } + + // Handles how Emojibase removes the variation selector for single code emojis. + // See: https://emojibase.dev/docs/spec/#merged-variation-selectors + if (codes.at(1) === VARIATION_SELECTOR_CODE && codes.length === 2) { + codes.pop(); + } return hexNumbersToString(codes); } From 4e6395891482f88de078d9c0766bd6736d07ca27 Mon Sep 17 00:00:00 2001 From: David Roetzel Date: Fri, 19 Dec 2025 14:44:27 +0100 Subject: [PATCH 851/853] Federated "featureable in collections" preference (#37298) --- .../parser/interaction_policy_parser.rb | 41 +++++++ app/models/account.rb | 71 ++++++------ .../activitypub/actor_serializer.rb | 14 +++ .../activitypub/process_account_service.rb | 5 + ...add_feature_approval_policy_to_accounts.rb | 7 ++ db/schema.rb | 3 +- .../parser/interaction_policy_parser_spec.rb | 102 ++++++++++++++++++ .../activitypub/actor_serializer_spec.rb | 37 ++++++- .../process_account_service_spec.rb | 43 ++++++++ 9 files changed, 286 insertions(+), 37 deletions(-) create mode 100644 app/lib/activitypub/parser/interaction_policy_parser.rb create mode 100644 db/migrate/20251217091936_add_feature_approval_policy_to_accounts.rb create mode 100644 spec/lib/activitypub/parser/interaction_policy_parser_spec.rb diff --git a/app/lib/activitypub/parser/interaction_policy_parser.rb b/app/lib/activitypub/parser/interaction_policy_parser.rb new file mode 100644 index 00000000000000..6587b245eeac85 --- /dev/null +++ b/app/lib/activitypub/parser/interaction_policy_parser.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +class ActivityPub::Parser::InteractionPolicyParser + def initialize(json, account) + @json = json + @account = account + end + + def bitmap + flags = 0 + return flags if @json.blank? + + flags |= subpolicy(@json['automaticApproval']) + flags <<= 16 + flags |= subpolicy(@json['manualApproval']) + + flags + end + + private + + def subpolicy(partial_json) + flags = 0 + + allowed_actors = Array(partial_json).dup + allowed_actors.uniq! + + flags |= InteractionPolicy::POLICY_FLAGS[:public] if allowed_actors.delete('as:Public') || allowed_actors.delete('Public') || allowed_actors.delete('https://www.w3.org/ns/activitystreams#Public') + flags |= InteractionPolicy::POLICY_FLAGS[:followers] if allowed_actors.delete(@account.followers_url) + flags |= InteractionPolicy::POLICY_FLAGS[:following] if allowed_actors.delete(@account.following_url) + + includes_target_actor = allowed_actors.delete(ActivityPub::TagManager.instance.uri_for(@account)).present? + + # Any unrecognized actor is marked as unsupported + flags |= InteractionPolicy::POLICY_FLAGS[:unsupported_policy] unless allowed_actors.empty? + + flags |= InteractionPolicy::POLICY_FLAGS[:disabled] if flags.zero? && includes_target_actor + + flags + end +end diff --git a/app/models/account.rb b/app/models/account.rb index 562d33508dd3f5..22c87557d23db2 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -5,54 +5,55 @@ # Table name: accounts # # id :bigint(8) not null, primary key -# username :string default(""), not null -# domain :string -# private_key :text -# public_key :text default(""), not null -# created_at :datetime not null -# updated_at :datetime not null -# note :text default(""), not null -# display_name :string default(""), not null -# uri :string default(""), not null -# url :string -# avatar_file_name :string +# actor_type :string +# also_known_as :string is an Array +# attribution_domains :string default([]), is an Array # avatar_content_type :string +# avatar_file_name :string # avatar_file_size :integer +# avatar_remote_url :string +# avatar_storage_schema_version :integer # avatar_updated_at :datetime -# header_file_name :string +# discoverable :boolean +# display_name :string default(""), not null +# domain :string +# feature_approval_policy :integer default(0), not null +# featured_collection_url :string +# fields :jsonb +# followers_url :string default(""), not null +# following_url :string default(""), not null # header_content_type :string +# header_file_name :string # header_file_size :integer -# header_updated_at :datetime -# avatar_remote_url :string -# locked :boolean default(FALSE), not null # header_remote_url :string default(""), not null -# last_webfingered_at :datetime +# header_storage_schema_version :integer +# header_updated_at :datetime +# hide_collections :boolean +# id_scheme :integer default("numeric_ap_id") # inbox_url :string default(""), not null +# indexable :boolean default(FALSE), not null +# last_webfingered_at :datetime +# locked :boolean default(FALSE), not null +# memorial :boolean default(FALSE), not null +# note :text default(""), not null # outbox_url :string default(""), not null -# shared_inbox_url :string default(""), not null -# followers_url :string default(""), not null -# following_url :string default(""), not null +# private_key :text # protocol :integer default("ostatus"), not null -# memorial :boolean default(FALSE), not null -# moved_to_account_id :bigint(8) -# featured_collection_url :string -# fields :jsonb -# actor_type :string -# discoverable :boolean -# also_known_as :string is an Array +# public_key :text default(""), not null +# requested_review_at :datetime +# reviewed_at :datetime +# sensitized_at :datetime +# shared_inbox_url :string default(""), not null # silenced_at :datetime # suspended_at :datetime -# hide_collections :boolean -# avatar_storage_schema_version :integer -# header_storage_schema_version :integer # suspension_origin :integer -# sensitized_at :datetime # trendable :boolean -# reviewed_at :datetime -# requested_review_at :datetime -# indexable :boolean default(FALSE), not null -# attribution_domains :string default([]), is an Array -# id_scheme :integer default("numeric_ap_id") +# uri :string default(""), not null +# url :string +# username :string default(""), not null +# created_at :datetime not null +# updated_at :datetime not null +# moved_to_account_id :bigint(8) # class Account < ApplicationRecord diff --git a/app/serializers/activitypub/actor_serializer.rb b/app/serializers/activitypub/actor_serializer.rb index ed90fa428f9668..c19d42bfb430cb 100644 --- a/app/serializers/activitypub/actor_serializer.rb +++ b/app/serializers/activitypub/actor_serializer.rb @@ -10,12 +10,16 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer :moved_to, :property_value, :discoverable, :suspended, :memorial, :indexable, :attribution_domains + context_extensions :interaction_policies if Mastodon::Feature.collections_enabled? + attributes :id, :type, :following, :followers, :inbox, :outbox, :featured, :featured_tags, :preferred_username, :name, :summary, :url, :manually_approves_followers, :discoverable, :indexable, :published, :memorial + attribute :interaction_policy, if: -> { Mastodon::Feature.collections_enabled? } + has_one :public_key, serializer: ActivityPub::PublicKeySerializer has_many :virtual_tags, key: :tag @@ -163,6 +167,16 @@ def published object.created_at.midnight.iso8601 end + def interaction_policy + uri = object.discoverable? ? ActivityPub::TagManager::COLLECTIONS[:public] : ActivityPub::TagManager.instance.uri_for(object) + + { + canFeature: { + automaticApproval: [uri], + }, + } + end + class CustomEmojiSerializer < ActivityPub::EmojiSerializer end diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb index eb67daf7e8f24a..f133fbc84aee05 100644 --- a/app/services/activitypub/process_account_service.rb +++ b/app/services/activitypub/process_account_service.rb @@ -107,6 +107,7 @@ def set_immediate_protocol_attributes! @account.uri = @uri @account.actor_type = actor_type @account.created_at = @json['published'] if @json['published'].present? + @account.feature_approval_policy = feature_approval_policy if Mastodon::Feature.collections_enabled? end def valid_collection_uri(uri) @@ -360,4 +361,8 @@ def process_emoji(tag) emoji.image_remote_url = image_url emoji.save end + + def feature_approval_policy + ActivityPub::Parser::InteractionPolicyParser.new(@json.dig('interactionPolicy', 'canFeature'), @account).bitmap + end end diff --git a/db/migrate/20251217091936_add_feature_approval_policy_to_accounts.rb b/db/migrate/20251217091936_add_feature_approval_policy_to_accounts.rb new file mode 100644 index 00000000000000..6d6e6e820568e1 --- /dev/null +++ b/db/migrate/20251217091936_add_feature_approval_policy_to_accounts.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class AddFeatureApprovalPolicyToAccounts < ActiveRecord::Migration[8.0] + def change + add_column :accounts, :feature_approval_policy, :integer, null: false, default: 0 + end +end diff --git a/db/schema.rb b/db/schema.rb index 51595381f5a1b3..78d7ef682610fe 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[8.0].define(version: 2025_12_09_093813) do +ActiveRecord::Schema[8.0].define(version: 2025_12_17_091936) do # These are extensions that must be enabled in order to support this database enable_extension "pg_catalog.plpgsql" @@ -200,6 +200,7 @@ t.string "attribution_domains", default: [], array: true t.string "following_url", default: "", null: false t.integer "id_scheme", default: 1 + t.integer "feature_approval_policy", default: 0, null: false t.index "(((setweight(to_tsvector('simple'::regconfig, (display_name)::text), 'A'::\"char\") || setweight(to_tsvector('simple'::regconfig, (username)::text), 'B'::\"char\")) || setweight(to_tsvector('simple'::regconfig, (COALESCE(domain, ''::character varying))::text), 'C'::\"char\")))", name: "search_index", using: :gin t.index "lower((username)::text), COALESCE(lower((domain)::text), ''::text)", name: "index_accounts_on_username_and_domain_lower", unique: true t.index ["domain", "id"], name: "index_accounts_on_domain_and_id" diff --git a/spec/lib/activitypub/parser/interaction_policy_parser_spec.rb b/spec/lib/activitypub/parser/interaction_policy_parser_spec.rb new file mode 100644 index 00000000000000..0af445eab20522 --- /dev/null +++ b/spec/lib/activitypub/parser/interaction_policy_parser_spec.rb @@ -0,0 +1,102 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe ActivityPub::Parser::InteractionPolicyParser do + subject { described_class.new(json_policy, account) } + + let(:account) do + Fabricate(:account, + uri: 'https://foo.test', + domain: 'foo.test', + followers_url: 'https://foo.test/followers', + following_url: 'https://foo.test/following') + end + + describe '#bitmap' do + context 'when no policy is given' do + let(:json_policy) { nil } + + it 'returns zero' do + expect(subject.bitmap).to be_zero + end + end + + context 'with special public URI' do + let(:json_policy) do + { + 'manualApproval' => [public_uri], + } + end + + shared_examples 'setting the public bit' do + it 'sets the public bit' do + expect(subject.bitmap).to eq 0b10 + end + end + + context 'when public URI is given in full' do + let(:public_uri) { 'https://www.w3.org/ns/activitystreams#Public' } + + it_behaves_like 'setting the public bit' + end + + context 'when public URI is abbreviated using namespace' do + let(:public_uri) { 'as:Public' } + + it_behaves_like 'setting the public bit' + end + + context 'when public URI is abbreviated without namespace' do + let(:public_uri) { 'Public' } + + it_behaves_like 'setting the public bit' + end + end + + context 'when mixing array and scalar values' do + let(:json_policy) do + { + 'automaticApproval' => 'https://foo.test', + 'manualApproval' => [ + 'https://foo.test/followers', + 'https://foo.test/following', + ], + } + end + + it 'sets the correct flags' do + expect(subject.bitmap).to eq 0b100000000000000001100 + end + end + + context 'when including individual actor URIs' do + let(:json_policy) do + { + 'automaticApproval' => ['https://example.com/actor', 'https://masto.example.com/@user'], + 'manualApproval' => ['https://masto.example.com/@other'], + } + end + + it 'sets the unsupported bit' do + expect(subject.bitmap).to eq 0b10000000000000001 + end + end + + context "when giving the affected actor's URI in addition to other supported URIs" do + let(:json_policy) do + { + 'manualApproval' => [ + 'https://foo.test/followers', + 'https://foo.test/following', + 'https://foo.test', + ], + } + end + + it 'is being ignored' do + expect(subject.bitmap).to eq 0b1100 + end + end + end +end diff --git a/spec/serializers/activitypub/actor_serializer_spec.rb b/spec/serializers/activitypub/actor_serializer_spec.rb index ad2445595375ac..734da6673c0d3d 100644 --- a/spec/serializers/activitypub/actor_serializer_spec.rb +++ b/spec/serializers/activitypub/actor_serializer_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' RSpec.describe ActivityPub::ActorSerializer do - subject { serialized_record_json(record, described_class) } + subject { serialized_record_json(record, described_class, adapter: ActivityPub::Adapter) } describe '#type' do context 'with the instance actor' do @@ -36,4 +36,39 @@ it { is_expected.to include('type' => 'Person') } end end + + describe '#interactionPolicy' do + let(:record) { Fabricate(:account) } + + # TODO: Remove when feature flag is removed + context 'when collections feature is disabled?' do + it 'is not present' do + expect(subject).to_not have_key('interactionPolicy') + end + end + + context 'when collections feature is enabled', feature: :collections do + context 'when actor is discoverable' do + it 'includes an automatic policy allowing everyone' do + expect(subject).to include('interactionPolicy' => { + 'canFeature' => { + 'automaticApproval' => ['https://www.w3.org/ns/activitystreams#Public'], + }, + }) + end + end + + context 'when actor is not discoverable' do + let(:record) { Fabricate(:account, discoverable: false) } + + it 'includes an automatic policy limited to the actor itself' do + expect(subject).to include('interactionPolicy' => { + 'canFeature' => { + 'automaticApproval' => [ActivityPub::TagManager.instance.uri_for(record)], + }, + }) + end + end + end + end end diff --git a/spec/services/activitypub/process_account_service_spec.rb b/spec/services/activitypub/process_account_service_spec.rb index eb0ba3524a77ce..b2c6bc17b2228d 100644 --- a/spec/services/activitypub/process_account_service_spec.rb +++ b/spec/services/activitypub/process_account_service_spec.rb @@ -272,6 +272,49 @@ end end + context 'with interaction policy' do + let(:payload) do + { + id: 'https://foo.test', + type: 'Actor', + inbox: 'https://foo.test/inbox', + followers: 'https://foo.test/followers', + following: 'https://foo.test/following', + interactionPolicy: { + canFeature: { + automaticApproval: 'https://foo.test', + manualApproval: [ + 'https://foo.test/followers', + 'https://foo.test/following', + ], + }, + }, + }.with_indifferent_access + end + + before do + stub_request(:get, %r{^https://foo\.test/follow}) + .to_return(status: 200, body: '', headers: {}) + end + + # TODO: Remove when feature flag is removed + context 'when collections feature is disabled' do + it 'does not set the interaction policy' do + account = subject.call('user1', 'foo.test', payload) + + expect(account.feature_approval_policy).to be_zero + end + end + + context 'when collections feature is enabled', feature: :collections do + it 'sets the interaction policy to the correct value' do + account = subject.call('user1', 'foo.test', payload) + + expect(account.feature_approval_policy).to eq 0b100000000000000001100 + end + end + end + private def create_some_remote_accounts From 8d9192835d6cac6ae51918143b20876258305fbe Mon Sep 17 00:00:00 2001 From: diondiondion Date: Fri, 19 Dec 2025 16:18:10 +0100 Subject: [PATCH 852/853] Add stub story for `StatusQuoteManager` / `Status` component (#37321) --- .../components/status_quoted.stories.tsx | 35 +++++++++++++++++++ .../mastodon/components/status_quoted.tsx | 13 ++++--- app/javascript/testing/factories.ts | 2 +- 3 files changed, 42 insertions(+), 8 deletions(-) create mode 100644 app/javascript/mastodon/components/status_quoted.stories.tsx diff --git a/app/javascript/mastodon/components/status_quoted.stories.tsx b/app/javascript/mastodon/components/status_quoted.stories.tsx new file mode 100644 index 00000000000000..aa17a5422cc065 --- /dev/null +++ b/app/javascript/mastodon/components/status_quoted.stories.tsx @@ -0,0 +1,35 @@ +import type { Meta, StoryObj } from '@storybook/react-vite'; + +import { accountFactoryState, statusFactoryState } from '@/testing/factories'; + +import type { StatusQuoteManagerProps } from './status_quoted'; +import { StatusQuoteManager } from './status_quoted'; + +const meta = { + title: 'Components/Status/StatusQuoteManager', + render(args) { + return ; + }, + args: { + id: '1', + }, + parameters: { + state: { + accounts: { + '1': accountFactoryState({ id: '1', acct: 'hashtaguser' }), + }, + statuses: { + '1': statusFactoryState({ + id: '1', + text: 'Hello world!', + }), + }, + }, + }, +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = {}; diff --git a/app/javascript/mastodon/components/status_quoted.tsx b/app/javascript/mastodon/components/status_quoted.tsx index eac2167294f9e9..33e791a548bfa6 100644 --- a/app/javascript/mastodon/components/status_quoted.tsx +++ b/app/javascript/mastodon/components/status_quoted.tsx @@ -4,20 +4,19 @@ import { FormattedMessage } from 'react-intl'; import type { Map as ImmutableMap } from 'immutable'; +import { fetchRelationships } from 'mastodon/actions/accounts'; +import { revealAccount } from 'mastodon/actions/accounts_typed'; +import { fetchStatus } from 'mastodon/actions/statuses'; import { LearnMoreLink } from 'mastodon/components/learn_more_link'; import StatusContainer from 'mastodon/containers/status_container'; import { domain } from 'mastodon/initial_state'; import type { Account } from 'mastodon/models/account'; import type { Status } from 'mastodon/models/status'; +import { makeGetStatusWithExtraInfo } from 'mastodon/selectors'; +import { getAccountHidden } from 'mastodon/selectors/accounts'; import type { RootState } from 'mastodon/store'; import { useAppDispatch, useAppSelector } from 'mastodon/store'; -import { fetchRelationships } from '../actions/accounts'; -import { revealAccount } from '../actions/accounts_typed'; -import { fetchStatus } from '../actions/statuses'; -import { makeGetStatusWithExtraInfo } from '../selectors'; -import { getAccountHidden } from '../selectors/accounts'; - import { Button } from './button'; const MAX_QUOTE_POSTS_NESTING_LEVEL = 1; @@ -333,7 +332,7 @@ export const QuotedStatus: React.FC = ({ ); }; -interface StatusQuoteManagerProps { +export interface StatusQuoteManagerProps { id: string; contextType?: string; [key: string]: unknown; diff --git a/app/javascript/testing/factories.ts b/app/javascript/testing/factories.ts index 28c0eca809722f..26b020d8c26169 100644 --- a/app/javascript/testing/factories.ts +++ b/app/javascript/testing/factories.ts @@ -76,7 +76,7 @@ export const statusFactory: FactoryFunction = ({ mentions: [], tags: [], emojis: [], - contentHtml: '

This is a test status.

', + contentHtml: data.text ?? '

This is a test status.

', ...data, }); From 0231b6d350d6027fa822f286732405b573d634e8 Mon Sep 17 00:00:00 2001 From: David Roetzel Date: Fri, 19 Dec 2025 16:20:30 +0100 Subject: [PATCH 853/853] Expose feature policy in API (#37322) --- app/models/account.rb | 1 + .../account/interaction_policy_concern.rb | 69 +++++++++++++++ app/serializers/rest/account_serializer.rb | 10 +++ .../interaction_policy_concern_spec.rb | 84 +++++++++++++++++++ .../rest/account_serializer_spec.rb | 55 +++++++++++- 5 files changed, 218 insertions(+), 1 deletion(-) create mode 100644 app/models/concerns/account/interaction_policy_concern.rb create mode 100644 spec/models/concerns/account/interaction_policy_concern_spec.rb diff --git a/app/models/account.rb b/app/models/account.rb index 22c87557d23db2..deb1589a0906a1 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -91,6 +91,7 @@ class Account < ApplicationRecord include Account::FaspConcern include Account::FinderConcern include Account::Header + include Account::InteractionPolicyConcern include Account::Interactions include Account::Mappings include Account::Merging diff --git a/app/models/concerns/account/interaction_policy_concern.rb b/app/models/concerns/account/interaction_policy_concern.rb new file mode 100644 index 00000000000000..8fe9eda1baf252 --- /dev/null +++ b/app/models/concerns/account/interaction_policy_concern.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +module Account::InteractionPolicyConcern + extend ActiveSupport::Concern + + included do + composed_of :feature_interaction_policy, class_name: 'InteractionPolicy', mapping: { feature_approval_policy: :bitmap } + end + + def feature_policy_as_keys(kind) + raise ArgumentError unless kind.in?(%i(automatic manual)) + return local_feature_policy(kind) if local? + + sub_policy = feature_interaction_policy.send(kind) + sub_policy.as_keys + end + + # Returns `:automatic`, `:manual`, `:unknown`, ':missing` or `:denied` + def feature_policy_for_account(other_account) + return :denied if other_account.nil? || (local? && !discoverable?) + return :automatic if local? + # Post author is always allowed to feature themselves + return :automatic if self == other_account + return :missing if feature_approval_policy.zero? + + automatic_policy = feature_interaction_policy.automatic + following_self = nil + followed_by_self = nil + + return :automatic if automatic_policy.public? + + if automatic_policy.followers? + following_self = followed_by?(other_account) + return :automatic if following_self + end + + if automatic_policy.following? + followed_by_self = following?(other_account) + return :automatic if followed_by_self + end + + # We don't know we are allowed by the automatic policy, considering the manual one + manual_policy = feature_interaction_policy.manual + + return :manual if manual_policy.public? + + if manual_policy.followers? + following_self = followed_by?(other_account) if following_self.nil? + return :manual if following_self + end + + if manual_policy.following? + followed_by_self = following?(other_account) if followed_by_self.nil? + return :manual if followed_by_self + end + + return :unknown if [automatic_policy, manual_policy].any?(&:unsupported_policy?) + + :denied + end + + private + + def local_feature_policy(kind) + return [] if kind == :manual || !discoverable? + + [:public] + end +end diff --git a/app/serializers/rest/account_serializer.rb b/app/serializers/rest/account_serializer.rb index b102f79fdb9c12..26715dd1032f88 100644 --- a/app/serializers/rest/account_serializer.rb +++ b/app/serializers/rest/account_serializer.rb @@ -20,6 +20,8 @@ class REST::AccountSerializer < ActiveModel::Serializer attribute :memorial, if: :memorial? + attribute :feature_approval, if: -> { Mastodon::Feature.collections_enabled? } + class AccountDecorator < SimpleDelegator def self.model_name Account.model_name @@ -157,4 +159,12 @@ def noindex def moved_and_not_nested? object.moved? end + + def feature_approval + { + automatic: object.feature_policy_as_keys(:automatic), + manual: object.feature_policy_as_keys(:manual), + current_user: object.feature_policy_for_account(current_user&.account), + } + end end diff --git a/spec/models/concerns/account/interaction_policy_concern_spec.rb b/spec/models/concerns/account/interaction_policy_concern_spec.rb new file mode 100644 index 00000000000000..586a33b77f4ed4 --- /dev/null +++ b/spec/models/concerns/account/interaction_policy_concern_spec.rb @@ -0,0 +1,84 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Account::InteractionPolicyConcern do + describe '#feature_policy_as_keys' do + context 'when account is local' do + context 'when account is discoverable' do + let(:account) { Fabricate(:account) } + + it 'returns public for automtatic and nothing for manual' do + expect(account.feature_policy_as_keys(:automatic)).to eq [:public] + expect(account.feature_policy_as_keys(:manual)).to eq [] + end + end + + context 'when account is not discoverable' do + let(:account) { Fabricate(:account, discoverable: false) } + + it 'returns empty arrays for both inputs' do + expect(account.feature_policy_as_keys(:automatic)).to eq [] + expect(account.feature_policy_as_keys(:manual)).to eq [] + end + end + end + + context 'when account is remote' do + let(:account) { Fabricate(:account, domain: 'example.com', feature_approval_policy: (0b0101 << 16) | 0b0010) } + + it 'returns the expected values' do + expect(account.feature_policy_as_keys(:automatic)).to eq ['unsupported_policy', 'followers'] + expect(account.feature_policy_as_keys(:manual)).to eq ['public'] + end + end + end + + describe '#feature_policy_for_account' do + context 'when account is remote' do + let(:account) { Fabricate(:account, domain: 'example.com', feature_approval_policy:) } + let(:feature_approval_policy) { (0b0101 << 16) | 0b0010 } + let(:other_account) { Fabricate(:account) } + + context 'when no policy is available' do + let(:feature_approval_policy) { 0 } + + context 'when both accounts are the same' do + it 'returns :automatic' do + expect(account.feature_policy_for_account(account)).to eq :automatic + end + end + + context 'with two different accounts' do + it 'returns :missing' do + expect(account.feature_policy_for_account(other_account)).to eq :missing + end + end + end + + context 'when the other account is not following the account' do + it 'returns :manual because of the public entry in the manual policy' do + expect(account.feature_policy_for_account(other_account)).to eq :manual + end + end + + context 'when the other account is following the account' do + before do + other_account.follow!(account) + end + + it 'returns :automatic because of the followers entry in the automatic policy' do + expect(account.feature_policy_for_account(other_account)).to eq :automatic + end + end + + context 'when the account falls into the unknown bucket' do + let(:feature_approval_policy) { (0b0001 << 16) | 0b0100 } + + it 'returns :automatic because of the followers entry in the automatic policy' do + expect(account.feature_policy_for_account(other_account)).to eq :unknown + end + end + end + end +end diff --git a/spec/serializers/rest/account_serializer_spec.rb b/spec/serializers/rest/account_serializer_spec.rb index 5fd4f8d706d394..998de6b0fb990a 100644 --- a/spec/serializers/rest/account_serializer_spec.rb +++ b/spec/serializers/rest/account_serializer_spec.rb @@ -3,12 +3,18 @@ require 'rails_helper' RSpec.describe REST::AccountSerializer do - subject { serialized_record_json(account, described_class) } + subject do + serialized_record_json(account, described_class, options: { + scope: current_user, + scope_name: :current_user, + }) + end let(:default_datetime) { DateTime.new(2024, 11, 28, 16, 20, 0) } let(:role) { Fabricate(:user_role, name: 'Role', highlighted: true) } let(:user) { Fabricate(:user, role: role) } let(:account) { user.account } + let(:current_user) { Fabricate(:user) } context 'when the account is suspended' do before do @@ -68,4 +74,51 @@ expect(subject['last_status_at']).to eq('2024-11-28') end end + + describe '#feature_approval' do + # TODO: Remove when feature flag is removed + context 'when collections feature is disabled' do + it 'does not include the approval policy' do + expect(subject).to_not have_key('feature_approval') + end + end + + context 'when collections feature is enabled', feature: :collections do + context 'when account is local' do + context 'when account is discoverable' do + it 'includes a policy that allows featuring' do + expect(subject['feature_approval']).to include({ + 'automatic' => ['public'], + 'manual' => [], + 'current_user' => 'automatic', + }) + end + end + + context 'when account is not discoverable' do + let(:account) { Fabricate(:account, discoverable: false) } + + it 'includes a policy that disallows featuring' do + expect(subject['feature_approval']).to include({ + 'automatic' => [], + 'manual' => [], + 'current_user' => 'denied', + }) + end + end + end + + context 'when account is remote' do + let(:account) { Fabricate(:account, domain: 'example.com', feature_approval_policy: 0b11000000000000000010) } + + it 'includes the matching policy' do + expect(subject['feature_approval']).to include({ + 'automatic' => ['followers', 'following'], + 'manual' => ['public'], + 'current_user' => 'manual', + }) + end + end + end + end end