From 925c16adea49adefdb202c19e8a7eaf439e1dada Mon Sep 17 00:00:00 2001 From: Claire Date: Sat, 26 Aug 2023 17:34:36 +0200 Subject: [PATCH 01/65] Fix nightly build version (#26676) --- .github/workflows/build-container-image.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-container-image.yml b/.github/workflows/build-container-image.yml index 8e9c747664..897bb9caaa 100644 --- a/.github/workflows/build-container-image.yml +++ b/.github/workflows/build-container-image.yml @@ -85,7 +85,9 @@ jobs: - uses: docker/build-push-action@v4 with: context: . - build-args: MASTODON_VERSION_PRERELEASE=${{ inputs.version_prerelease }} MASTODON_VERSION_METADATA=${{ inputs.version_metadata }} + build-args: | + MASTODON_VERSION_PRERELEASE=${{ inputs.version_prerelease }} + MASTODON_VERSION_METADATA=${{ inputs.version_metadata }} platforms: ${{ inputs.platforms }} provenance: false builder: ${{ steps.buildx.outputs.name || steps.buildx-native.outputs.name }} From f8d2fea2e6f6eb38c62e9a484980fa5696dfa2a4 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 27 Aug 2023 18:58:20 +0200 Subject: [PATCH 02/65] Change queue of job when opting into search from `default` to `pull` (#26688) --- app/workers/add_to_public_statuses_index_worker.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/workers/add_to_public_statuses_index_worker.rb b/app/workers/add_to_public_statuses_index_worker.rb index 409e5e7086..33529a4c1d 100644 --- a/app/workers/add_to_public_statuses_index_worker.rb +++ b/app/workers/add_to_public_statuses_index_worker.rb @@ -3,6 +3,8 @@ class AddToPublicStatusesIndexWorker include Sidekiq::Worker + sidekiq_options queue: 'pull' + def perform(account_id) account = Account.find(account_id) From 5694e24bbf9afccbbf1b44d3a405a4e2bc0ff08d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 27 Aug 2023 22:37:35 +0200 Subject: [PATCH 03/65] Fix unnecessary condition causing seqscan when indexing (#26689) --- app/models/concerns/account_statuses_search.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/concerns/account_statuses_search.rb b/app/models/concerns/account_statuses_search.rb index 563a871051..626bf38900 100644 --- a/app/models/concerns/account_statuses_search.rb +++ b/app/models/concerns/account_statuses_search.rb @@ -31,7 +31,7 @@ module AccountStatusesSearch def add_to_public_statuses_index! return unless Chewy.enabled? - statuses.indexable.find_in_batches do |batch| + statuses.without_reblogs.where(visibility: :public).find_in_batches do |batch| PublicStatusesIndex.import(query: batch) end end From e263db276fdc05dab743400977606efe98f1e949 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 27 Aug 2023 22:38:01 +0200 Subject: [PATCH 04/65] Change indexing jobs to use database replica (#26692) --- app/workers/add_to_public_statuses_index_worker.rb | 11 ++++++++--- app/workers/scheduler/indexing_scheduler.rb | 6 +++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/app/workers/add_to_public_statuses_index_worker.rb b/app/workers/add_to_public_statuses_index_worker.rb index 33529a4c1d..80d921eab0 100644 --- a/app/workers/add_to_public_statuses_index_worker.rb +++ b/app/workers/add_to_public_statuses_index_worker.rb @@ -2,15 +2,20 @@ class AddToPublicStatusesIndexWorker include Sidekiq::Worker + include DatabaseHelper sidekiq_options queue: 'pull' def perform(account_id) - account = Account.find(account_id) + with_primary do + @account = Account.find(account_id) + end - return unless account.indexable? + return unless @account.indexable? - account.add_to_public_statuses_index! + with_read_replica do + @account.add_to_public_statuses_index! + end rescue ActiveRecord::RecordNotFound true end diff --git a/app/workers/scheduler/indexing_scheduler.rb b/app/workers/scheduler/indexing_scheduler.rb index 6c770d5a8f..1b09730c7d 100644 --- a/app/workers/scheduler/indexing_scheduler.rb +++ b/app/workers/scheduler/indexing_scheduler.rb @@ -3,6 +3,7 @@ class Scheduler::IndexingScheduler include Sidekiq::Worker include Redisable + include DatabaseHelper sidekiq_options retry: 0, lock: :until_executed, lock_ttl: 1.day.to_i @@ -15,7 +16,10 @@ class Scheduler::IndexingScheduler indexes.each do |type| with_redis do |redis| redis.sscan_each("chewy:queue:#{type.name}", count: SCAN_BATCH_SIZE).each_slice(IMPORT_BATCH_SIZE) do |ids| - type.import!(ids) + with_read_replica do + type.import!(ids) + end + redis.srem("chewy:queue:#{type.name}", ids) end end From fc14d1f3b02411510467928df56318554c62c11d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 28 Aug 2023 10:20:02 +0200 Subject: [PATCH 05/65] Update eslint (non-major) (#26694) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 142 +++++++++++++++++++++++++++++------------------------- 1 file changed, 77 insertions(+), 65 deletions(-) diff --git a/yarn.lock b/yarn.lock index a630a752e2..8804218290 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1287,9 +1287,9 @@ eslint-visitor-keys "^3.3.0" "@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.1": - version "4.6.2" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.6.2.tgz#1816b5f6948029c5eaacb0703b850ee0cb37d8f8" - integrity sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw== + version "4.8.0" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.8.0.tgz#11195513186f68d42fbf449f9a7136b2c0c92005" + integrity sha512-JylOEEzDiOryeUnFbQz+oViCXS0KsvR1mvHkoMiu5+UiBvy+RYX7tzlIIIEstF/gVa2tj9AQXk3dgnxv6KxhFg== "@eslint/eslintrc@^2.1.2": version "2.1.2" @@ -1306,10 +1306,10 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@^8.47.0": - version "8.47.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.47.0.tgz#5478fdf443ff8158f9de171c704ae45308696c7d" - integrity sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og== +"@eslint/js@8.48.0": + version "8.48.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.48.0.tgz#642633964e217905436033a2bd08bf322849b7fb" + integrity sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw== "@floating-ui/core@^1.3.1": version "1.3.1" @@ -2608,15 +2608,15 @@ "@types/yargs-parser" "*" "@typescript-eslint/eslint-plugin@^6.0.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.4.0.tgz#53428b616f7d80fe879f45a08f11cc0f0b62cf13" - integrity sha512-62o2Hmc7Gs3p8SLfbXcipjWAa6qk2wZGChXG2JbBtYpwSRmti/9KHLqfbLs9uDigOexG+3PaQ9G2g3201FWLKg== + version "6.4.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.4.1.tgz#bc0c6f000134b53c304ad0bec4ee4753cd3e89d2" + integrity sha512-3F5PtBzUW0dYlq77Lcqo13fv+58KDwUib3BddilE8ajPJT+faGgxmI9Sw+I8ZS22BYwoir9ZhNXcLi+S+I2bkw== dependencies: "@eslint-community/regexpp" "^4.5.1" - "@typescript-eslint/scope-manager" "6.4.0" - "@typescript-eslint/type-utils" "6.4.0" - "@typescript-eslint/utils" "6.4.0" - "@typescript-eslint/visitor-keys" "6.4.0" + "@typescript-eslint/scope-manager" "6.4.1" + "@typescript-eslint/type-utils" "6.4.1" + "@typescript-eslint/utils" "6.4.1" + "@typescript-eslint/visitor-keys" "6.4.1" debug "^4.3.4" graphemer "^1.4.0" ignore "^5.2.4" @@ -2625,31 +2625,31 @@ ts-api-utils "^1.0.1" "@typescript-eslint/parser@^6.0.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.4.0.tgz#47e7c6e22ff1248e8675d95f488890484de67600" - integrity sha512-I1Ah1irl033uxjxO9Xql7+biL3YD7w9IU8zF+xlzD/YxY6a4b7DYA08PXUUCbm2sEljwJF6ERFy2kTGAGcNilg== + version "6.4.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.4.1.tgz#85ad550bf4ac4aa227504f1becb828f8e46c44e3" + integrity sha512-610G6KHymg9V7EqOaNBMtD1GgpAmGROsmfHJPXNLCU9bfIuLrkdOygltK784F6Crboyd5tBFayPB7Sf0McrQwg== dependencies: - "@typescript-eslint/scope-manager" "6.4.0" - "@typescript-eslint/types" "6.4.0" - "@typescript-eslint/typescript-estree" "6.4.0" - "@typescript-eslint/visitor-keys" "6.4.0" + "@typescript-eslint/scope-manager" "6.4.1" + "@typescript-eslint/types" "6.4.1" + "@typescript-eslint/typescript-estree" "6.4.1" + "@typescript-eslint/visitor-keys" "6.4.1" debug "^4.3.4" -"@typescript-eslint/scope-manager@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.4.0.tgz#3048e4262ba3eafa4e2e69b08912d9037ec646ae" - integrity sha512-TUS7vaKkPWDVvl7GDNHFQMsMruD+zhkd3SdVW0d7b+7Zo+bd/hXJQ8nsiUZMi1jloWo6c9qt3B7Sqo+flC1nig== +"@typescript-eslint/scope-manager@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.4.1.tgz#4b073a30be2dbe603e44e9ae0cff7e1d3ed19278" + integrity sha512-p/OavqOQfm4/Hdrr7kvacOSFjwQ2rrDVJRPxt/o0TOWdFnjJptnjnZ+sYDR7fi4OimvIuKp+2LCkc+rt9fIW+A== dependencies: - "@typescript-eslint/types" "6.4.0" - "@typescript-eslint/visitor-keys" "6.4.0" + "@typescript-eslint/types" "6.4.1" + "@typescript-eslint/visitor-keys" "6.4.1" -"@typescript-eslint/type-utils@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.4.0.tgz#c8ac92716ed6a9d5443aa3e342910355b0796ba0" - integrity sha512-TvqrUFFyGY0cX3WgDHcdl2/mMCWCDv/0thTtx/ODMY1QhEiyFtv/OlLaNIiYLwRpAxAtOLOY9SUf1H3Q3dlwAg== +"@typescript-eslint/type-utils@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.4.1.tgz#fa21cb13016c8d6f352fe9b2d6c9ab6edc2d1857" + integrity sha512-7ON8M8NXh73SGZ5XvIqWHjgX2f+vvaOarNliGhjrJnv1vdjG0LVIz+ToYfPirOoBi56jxAKLfsLm40+RvxVVXA== dependencies: - "@typescript-eslint/typescript-estree" "6.4.0" - "@typescript-eslint/utils" "6.4.0" + "@typescript-eslint/typescript-estree" "6.4.1" + "@typescript-eslint/utils" "6.4.1" debug "^4.3.4" ts-api-utils "^1.0.1" @@ -2658,10 +2658,10 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.59.0.tgz#3fcdac7dbf923ec5251545acdd9f1d42d7c4fe32" integrity sha512-yR2h1NotF23xFFYKHZs17QJnB51J/s+ud4PYU4MqdZbzeNxpgUr05+dNeCN/bb6raslHvGdd6BFCkVhpPk/ZeA== -"@typescript-eslint/types@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.4.0.tgz#5b109a59a805f0d8d375895e42d9e5f0037f66ee" - integrity sha512-+FV9kVFrS7w78YtzkIsNSoYsnOtrYVnKWSTVXoL1761CsCRv5wpDOINgsXpxD67YCLZtVQekDDyaxfjVWUJmmg== +"@typescript-eslint/types@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.4.1.tgz#b2c61159f46dda210fed9f117f5d027f65bb5c3b" + integrity sha512-zAAopbNuYu++ijY1GV2ylCsQsi3B8QvfPHVqhGdDcbx/NK5lkqMnCGU53amAjccSpk+LfeONxwzUhDzArSfZJg== "@typescript-eslint/typescript-estree@5.59.0": version "5.59.0" @@ -2676,30 +2676,30 @@ semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/typescript-estree@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.4.0.tgz#3c58d20632db93fec3d6ab902acbedf593d37276" - integrity sha512-iDPJArf/K2sxvjOR6skeUCNgHR/tCQXBsa+ee1/clRKr3olZjZ/dSkXPZjG6YkPtnW6p5D1egeEPMCW6Gn4yLA== +"@typescript-eslint/typescript-estree@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.4.1.tgz#91ff88101c710adb0f70a317f2f65efa9441da45" + integrity sha512-xF6Y7SatVE/OyV93h1xGgfOkHr2iXuo8ip0gbfzaKeGGuKiAnzS+HtVhSPx8Www243bwlW8IF7X0/B62SzFftg== dependencies: - "@typescript-eslint/types" "6.4.0" - "@typescript-eslint/visitor-keys" "6.4.0" + "@typescript-eslint/types" "6.4.1" + "@typescript-eslint/visitor-keys" "6.4.1" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" semver "^7.5.4" ts-api-utils "^1.0.1" -"@typescript-eslint/utils@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.4.0.tgz#23e996b693603c5924b1fbb733cc73196256baa5" - integrity sha512-BvvwryBQpECPGo8PwF/y/q+yacg8Hn/2XS+DqL/oRsOPK+RPt29h5Ui5dqOKHDlbXrAeHUTnyG3wZA0KTDxRZw== +"@typescript-eslint/utils@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.4.1.tgz#81bf62ff0c3119a26c19fab683582e29450717bc" + integrity sha512-F/6r2RieNeorU0zhqZNv89s9bDZSovv3bZQpUNOmmQK1L80/cV4KEu95YUJWi75u5PhboFoKUJBnZ4FQcoqhDw== dependencies: "@eslint-community/eslint-utils" "^4.4.0" "@types/json-schema" "^7.0.12" "@types/semver" "^7.5.0" - "@typescript-eslint/scope-manager" "6.4.0" - "@typescript-eslint/types" "6.4.0" - "@typescript-eslint/typescript-estree" "6.4.0" + "@typescript-eslint/scope-manager" "6.4.1" + "@typescript-eslint/types" "6.4.1" + "@typescript-eslint/typescript-estree" "6.4.1" semver "^7.5.4" "@typescript-eslint/visitor-keys@5.59.0": @@ -2710,12 +2710,12 @@ "@typescript-eslint/types" "5.59.0" eslint-visitor-keys "^3.3.0" -"@typescript-eslint/visitor-keys@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.4.0.tgz#96a426cdb1add28274abd7a34aefe27f8b7d51ef" - integrity sha512-yJSfyT+uJm+JRDWYRYdCm2i+pmvXJSMtPR9Cq5/XQs4QIgNoLcoRtDdzsLbLsFM/c6um6ohQkg/MLxWvoIndJA== +"@typescript-eslint/visitor-keys@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.4.1.tgz#e3ccf7b8d42e625946ac5094ed92a405fb4115e0" + integrity sha512-y/TyRJsbZPkJIZQXrHfdnxVnxyKegnpEvnRGNam7s3TRR2ykGefEWOhaef00/UUN3IZxizS7BTO3svd3lCOJRQ== dependencies: - "@typescript-eslint/types" "6.4.0" + "@typescript-eslint/types" "6.4.1" eslint-visitor-keys "^3.4.1" "@webassemblyjs/ast@1.9.0": @@ -5528,14 +5528,14 @@ eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4 integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== eslint@^8.41.0: - version "8.47.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.47.0.tgz#c95f9b935463fb4fad7005e626c7621052e90806" - integrity sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q== + version "8.48.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.48.0.tgz#bf9998ba520063907ba7bfe4c480dc8be03c2155" + integrity sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg== dependencies: "@eslint-community/eslint-utils" "^4.2.0" "@eslint-community/regexpp" "^4.6.1" "@eslint/eslintrc" "^2.1.2" - "@eslint/js" "^8.47.0" + "@eslint/js" "8.48.0" "@humanwhocodes/config-array" "^0.11.10" "@humanwhocodes/module-importer" "^1.0.1" "@nodelib/fs.walk" "^1.2.8" @@ -5990,14 +5990,15 @@ findup-sync@^3.0.0: resolve-dir "^1.0.1" flat-cache@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" - integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + version "3.1.0" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.1.0.tgz#0e54ab4a1a60fe87e2946b6b00657f1c99e1af3f" + integrity sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew== dependencies: - flatted "^3.1.0" + flatted "^3.2.7" + keyv "^4.5.3" rimraf "^3.0.2" -flatted@^3.1.0: +flatted@^3.2.7: version "3.2.7" resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== @@ -7843,6 +7844,11 @@ jsesc@~0.5.0: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + json-parse-better-errors@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" @@ -7934,6 +7940,13 @@ keycode@^2.1.7: resolved "https://registry.yarnpkg.com/keycode/-/keycode-2.2.1.tgz#09c23b2be0611d26117ea2501c2c391a01f39eff" integrity sha512-Rdgz9Hl9Iv4QKi8b0OlCRQEzp4AgVxyCtz5S/+VIHezDmrDhkp2N2TqBWOLz0/gbeREXOOiI9/4b8BY9uw2vFg== +keyv@^4.5.3: + version "4.5.3" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.3.tgz#00873d2b046df737963157bd04f294ca818c9c25" + integrity sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug== + dependencies: + json-buffer "3.0.1" + killable@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" @@ -11329,7 +11342,6 @@ stringz@^2.1.0: char-regex "^1.0.2" "strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: - name strip-ansi-cjs version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== From 822a35b9d577539a63984ca81d6668ca3b8435fd Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 28 Aug 2023 10:31:51 +0200 Subject: [PATCH 06/65] Fix not being able to negate prefix clauses in search (#26672) --- app/lib/search_query_parser.rb | 2 +- app/lib/search_query_transformer.rb | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/app/lib/search_query_parser.rb b/app/lib/search_query_parser.rb index 15956d4cfd..5d6ffbf29d 100644 --- a/app/lib/search_query_parser.rb +++ b/app/lib/search_query_parser.rb @@ -9,7 +9,7 @@ class SearchQueryParser < Parslet::Parser rule(:prefix) { (term >> colon).as(:prefix) } rule(:shortcode) { (colon >> term >> colon.maybe).as(:shortcode) } rule(:phrase) { (quote >> (term >> space.maybe).repeat >> quote).as(:phrase) } - rule(:clause) { (prefix.maybe >> operator.maybe >> (phrase | term | shortcode)).as(:clause) } + rule(:clause) { (operator.maybe >> prefix.maybe >> (phrase | term | shortcode)).as(:clause) } rule(:query) { (clause >> space.maybe).repeat.as(:query) } root(:query) end diff --git a/app/lib/search_query_transformer.rb b/app/lib/search_query_transformer.rb index dad99cbd2d..915f9c3312 100644 --- a/app/lib/search_query_transformer.rb +++ b/app/lib/search_query_transformer.rb @@ -36,7 +36,11 @@ class SearchQueryTransformer < Parslet::Transform def clause_to_filter(clause) case clause when PrefixClause - { clause.type => { clause.filter => clause.term } } + if clause.negated? + { bool: { must_not: { clause.type => { clause.filter => clause.term } } } } + else + { clause.type => { clause.filter => clause.term } } + end else raise "Unexpected clause type: #{clause}" end @@ -81,7 +85,8 @@ class SearchQueryTransformer < Parslet::Transform class PrefixClause attr_reader :type, :filter, :operator, :term - def initialize(prefix, term) + def initialize(prefix, operator, term) + @negated = operator == '-' @operator = :filter case prefix @@ -114,6 +119,10 @@ class SearchQueryTransformer < Parslet::Transform end end + def negated? + @negated + end + private def account_id_from_term(term) @@ -132,7 +141,7 @@ class SearchQueryTransformer < Parslet::Transform operator = clause[:operator]&.to_s if clause[:prefix] - PrefixClause.new(prefix, clause[:term].to_s) + PrefixClause.new(prefix, operator, clause[:term].to_s) elsif clause[:term] TermClause.new(prefix, operator, clause[:term].to_s) elsif clause[:shortcode] From b42fe5e3382ef1415748030ed7842095dcefa6a9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 28 Aug 2023 10:32:13 +0200 Subject: [PATCH 07/65] Update dependency haml_lint to v0.50.0 (#26665) 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 f801b1b560..7a68249c28 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -324,7 +324,7 @@ GEM ruby-progressbar (~> 1.4) globalid (1.1.0) activesupport (>= 5.0) - haml (6.1.1) + haml (6.1.2) temple (>= 0.8.2) thor tilt @@ -333,7 +333,7 @@ GEM activesupport (>= 5.1) haml (>= 4.0.6) railties (>= 5.1) - haml_lint (0.49.3) + haml_lint (0.50.0) haml (>= 4.0, < 6.2) parallel (~> 1.10) rainbow From 4ea5db90da2d0fd0e888ea6c9f777835874c4302 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 28 Aug 2023 11:04:06 +0200 Subject: [PATCH 08/65] Update DefinitelyTyped types (non-major) (#26693) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 135 +++++++++++++++++++++++++++++------------------------- 1 file changed, 73 insertions(+), 62 deletions(-) diff --git a/yarn.lock b/yarn.lock index 8804218290..4a6d642cef 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1538,12 +1538,12 @@ "@types/node" "*" jest-mock "^29.6.2" -"@jest/expect-utils@^29.6.2": - version "29.6.2" - resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.6.2.tgz#1b97f290d0185d264dd9fdec7567a14a38a90534" - integrity sha512-6zIhM8go3RV2IG4aIZaZbxwpOzz3ZiM23oxAlkquOIole+G6TrbeXnykxWYlqF7kz2HlBjdKtca20x9atkEQYg== +"@jest/expect-utils@^29.6.2", "@jest/expect-utils@^29.6.4": + version "29.6.4" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.6.4.tgz#17c7dfe6cec106441f218b0aff4b295f98346679" + integrity sha512-FEhkJhqtvBwgSpiTrocquJCdXPsyvNKcl/n7A3u7X4pVoF4bswm11c9d4AV+kfq2Gpv/mM8x7E7DsRvH+djkrg== dependencies: - jest-get-type "^29.4.3" + jest-get-type "^29.6.3" "@jest/expect@^29.6.2": version "29.6.2" @@ -1605,10 +1605,10 @@ strip-ansi "^6.0.0" v8-to-istanbul "^9.0.1" -"@jest/schemas@^29.6.0": - version "29.6.0" - resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.0.tgz#0f4cb2c8e3dca80c135507ba5635a4fd755b0040" - integrity sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ== +"@jest/schemas@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" + integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== dependencies: "@sinclair/typebox" "^0.27.8" @@ -1662,12 +1662,12 @@ slash "^3.0.0" write-file-atomic "^4.0.2" -"@jest/types@^29.6.1": - version "29.6.1" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.1.tgz#ae79080278acff0a6af5eb49d063385aaa897bf2" - integrity sha512-tPKQNMPuXgvdOn2/Lg9HNfUvjYVGolt04Hp03f5hAk878uwOLikN+JzeLY0HcVgKgFl9Hs3EIqpu3WX27XNhnw== +"@jest/types@^29.6.1", "@jest/types@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59" + integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== dependencies: - "@jest/schemas" "^29.6.0" + "@jest/schemas" "^29.6.3" "@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-reports" "^3.0.0" "@types/node" "*" @@ -2226,9 +2226,9 @@ "@types/istanbul-lib-report" "*" "@types/jest@*", "@types/jest@^29.5.2": - version "29.5.3" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.3.tgz#7a35dc0044ffb8b56325c6802a4781a626b05777" - integrity sha512-1Nq7YrO/vJE/FYnqYyw0FS8LdrjExSgIiHyKg7xPpn+yi8Q4huZryKnkJatN1ZRH89Kw2v33/8ZMB7DuZeSLlA== + version "29.5.4" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.4.tgz#9d0a16edaa009a71e6a71a999acd582514dab566" + integrity sha512-PhglGmhWeD46FYOVLt3X7TiWjzwuVGW9wG/4qocPevXMjCmrIc5b6db9WjeGE4QYVpUAWMDv3v0IiBwObY289A== dependencies: expect "^29.0.0" pretty-format "^29.0.0" @@ -2288,9 +2288,9 @@ integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== "@types/node@*": - version "20.4.9" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.9.tgz#c7164e0f8d3f12dfae336af0b1f7fdec8c6b204f" - integrity sha512-8e2HYcg7ohnTUbHk8focoklEQYvemQmu9M/f43DZVx43kHn0tE3BY/6gSDxS7k0SprtS0NHvj+L80cGLnoOUcQ== + version "20.5.7" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.5.7.tgz#4b8ecac87fbefbc92f431d09c30e176fc0a7c377" + integrity sha512-dP7f3LdZIysZnmvP3ANJYTSwg+wLLl8p7RqniVlV7j+oXSXAbt9h0WIBFmJy5inWZoX9wZN6eXx+YXd9Rh3RBA== "@types/node@14 || 16 || 17": version "17.0.45" @@ -2466,9 +2466,9 @@ "@types/react" "*" "@types/react@*", "@types/react@16 || 17 || 18", "@types/react@>=16.9.11", "@types/react@^18.0.26", "@types/react@^18.2.7": - version "18.2.20" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.20.tgz#1605557a83df5c8a2cc4eeb743b3dfc0eb6aaeb2" - integrity sha512-WKNtmsLWJM/3D5mG4U84cysVY31ivmyw85dE84fOCk5Hx78wezB/XEjVPWl2JTZ5FkEeaTJf+VgUAUn3PE7Isw== + version "18.2.21" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.21.tgz#774c37fd01b522d0b91aed04811b58e4e0514ed9" + integrity sha512-neFKG/sBAwGxHgXiIxnbm3/AAVQ/cMRS93hvBpg8xYRbeQSPVABp9U2bRnPf0iI4+Ucdv3plSxKK+3CW2ENJxA== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" @@ -4922,10 +4922,10 @@ detect-passive-events@^2.0.3: dependencies: detect-it "^4.0.1" -diff-sequences@^29.4.3: - version "29.4.3" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.4.3.tgz#9314bc1fabe09267ffeca9cbafc457d8499a13f2" - integrity sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA== +diff-sequences@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" + integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== diffie-hellman@^5.0.0: version "5.0.3" @@ -5734,7 +5734,18 @@ expand-tilde@^2.0.0, expand-tilde@^2.0.2: dependencies: homedir-polyfill "^1.0.1" -expect@^29.0.0, expect@^29.6.2: +expect@^29.0.0: + version "29.6.4" + resolved "https://registry.yarnpkg.com/expect/-/expect-29.6.4.tgz#a6e6f66d4613717859b2fe3da98a739437b6f4b8" + integrity sha512-F2W2UyQ8XYyftHT57dtfg8Ue3X5qLgm2sSug0ivvLRH/VKNRL/pDxg/TH7zVzbQB0tu80clNFy6LU7OS/VSEKA== + dependencies: + "@jest/expect-utils" "^29.6.4" + jest-get-type "^29.6.3" + jest-matcher-utils "^29.6.4" + jest-message-util "^29.6.3" + jest-util "^29.6.3" + +expect@^29.6.2: version "29.6.2" resolved "https://registry.yarnpkg.com/expect/-/expect-29.6.2.tgz#7b08e83eba18ddc4a2cf62b5f2d1918f5cd84521" integrity sha512-iAErsLxJ8C+S02QbLAwgSGSezLQK+XXRDt8IuFXFpwCNw2ECmzZSmjKcCaFVp5VRMk+WAvz6h6jokzEzBFZEuA== @@ -7431,15 +7442,15 @@ jest-config@^29.6.2: slash "^3.0.0" strip-json-comments "^3.1.1" -jest-diff@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.6.2.tgz#c36001e5543e82a0805051d3ceac32e6825c1c46" - integrity sha512-t+ST7CB9GX5F2xKwhwCf0TAR17uNDiaPTZnVymP9lw0lssa9vG+AFyDZoeIHStU3WowFFwT+ky+er0WVl2yGhA== +jest-diff@^29.6.2, jest-diff@^29.6.4: + version "29.6.4" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.6.4.tgz#85aaa6c92a79ae8cd9a54ebae8d5b6d9a513314a" + integrity sha512-9F48UxR9e4XOEZvoUXEHSWY4qC4zERJaOfrbBg9JpbJOO43R1vN76REt/aMGZoY6GD5g84nnJiBIVlscegefpw== dependencies: chalk "^4.0.0" - diff-sequences "^29.4.3" - jest-get-type "^29.4.3" - pretty-format "^29.6.2" + diff-sequences "^29.6.3" + jest-get-type "^29.6.3" + pretty-format "^29.6.3" jest-docblock@^29.4.3: version "29.4.3" @@ -7485,10 +7496,10 @@ jest-environment-node@^29.6.2: jest-mock "^29.6.2" jest-util "^29.6.2" -jest-get-type@^29.4.3: - version "29.4.3" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.4.3.tgz#1ab7a5207c995161100b5187159ca82dd48b3dd5" - integrity sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg== +jest-get-type@^29.4.3, jest-get-type@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.6.3.tgz#36f499fdcea197c1045a127319c0481723908fd1" + integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw== jest-haste-map@^29.6.2: version "29.6.2" @@ -7517,28 +7528,28 @@ jest-leak-detector@^29.6.2: jest-get-type "^29.4.3" pretty-format "^29.6.2" -jest-matcher-utils@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.6.2.tgz#39de0be2baca7a64eacb27291f0bd834fea3a535" - integrity sha512-4LiAk3hSSobtomeIAzFTe+N8kL6z0JtF3n6I4fg29iIW7tt99R7ZcIFW34QkX+DuVrf+CUe6wuVOpm7ZKFJzZQ== +jest-matcher-utils@^29.6.2, jest-matcher-utils@^29.6.4: + version "29.6.4" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.6.4.tgz#327db7ababea49455df3b23e5d6109fe0c709d24" + integrity sha512-KSzwyzGvK4HcfnserYqJHYi7sZVqdREJ9DMPAKVbS98JsIAvumihaNUbjrWw0St7p9IY7A9UskCW5MYlGmBQFQ== dependencies: chalk "^4.0.0" - jest-diff "^29.6.2" - jest-get-type "^29.4.3" - pretty-format "^29.6.2" + jest-diff "^29.6.4" + jest-get-type "^29.6.3" + pretty-format "^29.6.3" -jest-message-util@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.6.2.tgz#af7adc2209c552f3f5ae31e77cf0a261f23dc2bb" - integrity sha512-vnIGYEjoPSuRqV8W9t+Wow95SDp6KPX2Uf7EoeG9G99J2OVh7OSwpS4B6J0NfpEIpfkBNHlBZpA2rblEuEFhZQ== +jest-message-util@^29.6.2, jest-message-util@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.6.3.tgz#bce16050d86801b165f20cfde34dc01d3cf85fbf" + integrity sha512-FtzaEEHzjDpQp51HX4UMkPZjy46ati4T5pEMyM6Ik48ztu4T9LQplZ6OsimHx7EuM9dfEh5HJa6D3trEftu3dA== dependencies: "@babel/code-frame" "^7.12.13" - "@jest/types" "^29.6.1" + "@jest/types" "^29.6.3" "@types/stack-utils" "^2.0.0" chalk "^4.0.0" graceful-fs "^4.2.9" micromatch "^4.0.4" - pretty-format "^29.6.2" + pretty-format "^29.6.3" slash "^3.0.0" stack-utils "^2.0.3" @@ -7665,12 +7676,12 @@ jest-snapshot@^29.6.2: pretty-format "^29.6.2" semver "^7.5.3" -jest-util@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.6.2.tgz#8a052df8fff2eebe446769fd88814521a517664d" - integrity sha512-3eX1qb6L88lJNCFlEADKOkjpXJQyZRiavX1INZ4tRnrBVr2COd3RgcTLyUiEXMNBlDU/cgYq6taUS0fExrWW4w== +jest-util@^29.6.2, jest-util@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.6.3.tgz#e15c3eac8716440d1ed076f09bc63ace1aebca63" + integrity sha512-QUjna/xSy4B32fzcKTSz1w7YYzgiHrjjJjevdRf61HYk998R5vVMMNmrHESYZVDS5DSWs+1srPLPKxXPkeSDOA== dependencies: - "@jest/types" "^29.6.1" + "@jest/types" "^29.6.3" "@types/node" "*" chalk "^4.0.0" ci-info "^3.2.0" @@ -9710,12 +9721,12 @@ pretty-format@^27.0.2: ansi-styles "^5.0.0" react-is "^17.0.1" -pretty-format@^29.0.0, pretty-format@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.6.2.tgz#3d5829261a8a4d89d8b9769064b29c50ed486a47" - integrity sha512-1q0oC8eRveTg5nnBEWMXAU2qpv65Gnuf2eCQzSjxpWFkPaPARwqZZDGuNE0zPAZfTCHzIk3A8dIjwlQKKLphyg== +pretty-format@^29.0.0, pretty-format@^29.6.2, pretty-format@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.6.3.tgz#d432bb4f1ca6f9463410c3fb25a0ba88e594ace7" + integrity sha512-ZsBgjVhFAj5KeK+nHfF1305/By3lechHQSMWCTl8iHSbfOm2TN5nHEtFc/+W7fAyUeCs2n5iow72gld4gW0xDw== dependencies: - "@jest/schemas" "^29.6.0" + "@jest/schemas" "^29.6.3" ansi-styles "^5.0.0" react-is "^18.0.0" From 7bd5ebb0c50bb481c85ef81816089a04746f762d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 28 Aug 2023 11:36:17 +0200 Subject: [PATCH 09/65] Fix multiple issues with status index mappings (#26686) --- app/chewy/accounts_index.rb | 9 +++++---- app/chewy/public_statuses_index.rb | 14 ++++++++++---- app/chewy/statuses_index.rb | 14 ++++++++++---- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/app/chewy/accounts_index.rb b/app/chewy/accounts_index.rb index 61e3399aa8..8881b08f66 100644 --- a/app/chewy/accounts_index.rb +++ b/app/chewy/accounts_index.rb @@ -21,19 +21,20 @@ class AccountsIndex < Chewy::Index analyzer: { natural: { - tokenizer: 'uax_url_email', + tokenizer: 'standard', filter: %w( - english_possessive_stemmer lowercase asciifolding cjk_width + elision + english_possessive_stemmer english_stop english_stemmer ), }, verbatim: { - tokenizer: 'standard', + tokenizer: 'uax_url_email', filter: %w(lowercase asciifolding cjk_width), }, @@ -62,6 +63,6 @@ class AccountsIndex < Chewy::Index field(:last_status_at, type: 'date', value: ->(account) { account.last_status_at || account.created_at }) field(:display_name, type: 'text', analyzer: 'verbatim') { field :edge_ngram, type: 'text', analyzer: 'edge_ngram', search_analyzer: 'verbatim' } field(:username, type: 'text', analyzer: 'verbatim', value: ->(account) { [account.username, account.domain].compact.join('@') }) { field :edge_ngram, type: 'text', analyzer: 'edge_ngram', search_analyzer: 'verbatim' } - field(:text, type: 'text', analyzer: 'whitespace', value: ->(account) { account.searchable_text }) { field :stemmed, type: 'text', analyzer: 'natural' } + field(:text, type: 'text', analyzer: 'verbatim', value: ->(account) { account.searchable_text }) { field :stemmed, type: 'text', analyzer: 'natural' } end end diff --git a/app/chewy/public_statuses_index.rb b/app/chewy/public_statuses_index.rb index 1fad5de3a1..5c68a13658 100644 --- a/app/chewy/public_statuses_index.rb +++ b/app/chewy/public_statuses_index.rb @@ -20,13 +20,19 @@ class PublicStatusesIndex < Chewy::Index }, analyzer: { - content: { + verbatim: { tokenizer: 'uax_url_email', + filter: %w(lowercase), + }, + + content: { + tokenizer: 'standard', filter: %w( - english_possessive_stemmer lowercase asciifolding cjk_width + elision + english_possessive_stemmer english_stop english_stemmer ), @@ -40,9 +46,9 @@ class PublicStatusesIndex < Chewy::Index .includes(:media_attachments, :preloadable_poll, :preview_cards) root date_detection: false do - field(:id, type: 'keyword') + field(:id, type: 'long') field(:account_id, type: 'long') - field(:text, type: 'text', analyzer: 'whitespace', value: ->(status) { status.searchable_text }) { field(:stemmed, type: 'text', analyzer: 'content') } + field(:text, type: 'text', analyzer: 'verbatim', value: ->(status) { status.searchable_text }) { field(:stemmed, type: 'text', analyzer: 'content') } field(:language, type: 'keyword') field(:properties, type: 'keyword', value: ->(status) { status.searchable_properties }) field(:created_at, type: 'date') diff --git a/app/chewy/statuses_index.rb b/app/chewy/statuses_index.rb index 130f8801df..6d33521051 100644 --- a/app/chewy/statuses_index.rb +++ b/app/chewy/statuses_index.rb @@ -20,13 +20,19 @@ class StatusesIndex < Chewy::Index }, analyzer: { - content: { + verbatim: { tokenizer: 'uax_url_email', + filter: %w(lowercase), + }, + + content: { + tokenizer: 'standard', filter: %w( - english_possessive_stemmer lowercase asciifolding cjk_width + elision + english_possessive_stemmer english_stop english_stemmer ), @@ -64,9 +70,9 @@ class StatusesIndex < Chewy::Index end root date_detection: false do - field(:id, type: 'keyword') + field(:id, type: 'long') field(:account_id, type: 'long') - field(:text, type: 'text', analyzer: 'whitespace', value: ->(status) { status.searchable_text }) { field(:stemmed, type: 'text', analyzer: 'content') } + field(:text, type: 'text', analyzer: 'verbatim', value: ->(status) { status.searchable_text }) { field(:stemmed, type: 'text', analyzer: 'content') } field(:searchable_by, type: 'long', value: ->(status, crutches) { status.searchable_by(crutches) }) field(:language, type: 'keyword') field(:properties, type: 'keyword', value: ->(status) { status.searchable_properties }) From 9d9de8d219b7545826e9fb70f84aa65a0409d138 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 28 Aug 2023 12:19:42 +0200 Subject: [PATCH 10/65] Update dependency @testing-library/jest-dom to v6 (#26479) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Renaud Chaput --- app/javascript/mastodon/test_setup.js | 2 +- package.json | 2 +- yarn.lock | 25 +++++++++---------------- 3 files changed, 11 insertions(+), 18 deletions(-) diff --git a/app/javascript/mastodon/test_setup.js b/app/javascript/mastodon/test_setup.js index 666127af39..7b0828bfa8 100644 --- a/app/javascript/mastodon/test_setup.js +++ b/app/javascript/mastodon/test_setup.js @@ -1 +1 @@ -import '@testing-library/jest-dom/extend-expect'; +import '@testing-library/jest-dom'; diff --git a/package.json b/package.json index 16c5d529a6..4038831050 100644 --- a/package.json +++ b/package.json @@ -152,7 +152,7 @@ }, "devDependencies": { "@formatjs/cli": "^6.1.1", - "@testing-library/jest-dom": "^5.16.5", + "@testing-library/jest-dom": "^6.0.0", "@testing-library/react": "^14.0.0", "@types/babel__core": "^7.20.1", "@types/emoji-mart": "^3.0.9", diff --git a/yarn.lock b/yarn.lock index 4a6d642cef..3e9c9abf77 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2022,14 +2022,13 @@ lz-string "^1.5.0" pretty-format "^27.0.2" -"@testing-library/jest-dom@^5.16.5": - version "5.17.0" - resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz#5e97c8f9a15ccf4656da00fecab505728de81e0c" - integrity sha512-ynmNeT7asXyH3aSVv4vvX4Rb+0qjOhdNHnO/3vuZNqPmhDpV/+rCSGwQ7bLcmU2cJ4dvoheIO85LQj0IbJHEtg== +"@testing-library/jest-dom@^6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-6.0.0.tgz#d2ba5a3fd13724d5966b3f8cd24d2cedcab4fa76" + integrity sha512-Ye2R3+/oM27jir8CzYPmuWdavTaKwNZcu0d22L9pO/vnOYE0wmrtpw79TQJa8H6gV8/i7yd+pLaqeLlA0rTMfg== dependencies: "@adobe/css-tools" "^4.0.1" "@babel/runtime" "^7.9.2" - "@types/testing-library__jest-dom" "^5.9.1" aria-query "^5.0.0" chalk "^3.0.0" css.escape "^1.5.1" @@ -2225,10 +2224,10 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@*", "@types/jest@^29.5.2": - version "29.5.4" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.4.tgz#9d0a16edaa009a71e6a71a999acd582514dab566" - integrity sha512-PhglGmhWeD46FYOVLt3X7TiWjzwuVGW9wG/4qocPevXMjCmrIc5b6db9WjeGE4QYVpUAWMDv3v0IiBwObY289A== +"@types/jest@^29.5.2": + version "29.5.3" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.3.tgz#7a35dc0044ffb8b56325c6802a4781a626b05777" + integrity sha512-1Nq7YrO/vJE/FYnqYyw0FS8LdrjExSgIiHyKg7xPpn+yi8Q4huZryKnkJatN1ZRH89Kw2v33/8ZMB7DuZeSLlA== dependencies: expect "^29.0.0" pretty-format "^29.0.0" @@ -2535,13 +2534,6 @@ resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.8.tgz#b94a4391c85666c7b73299fd3ad79d4faa435310" integrity sha512-ipixuVrh2OdNmauvtT51o3d8z12p6LtFW9in7U79der/kwejjdNchQC5UMn5u/KxNoM7VHHOs/l8KS8uHxhODQ== -"@types/testing-library__jest-dom@^5.9.1": - version "5.14.9" - resolved "https://registry.yarnpkg.com/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.9.tgz#0fb1e6a0278d87b6737db55af5967570b67cb466" - integrity sha512-FSYhIjFlfOpGSRyVoMBMuS3ws5ehFQODymf3vlI7U1K8c7PHwWwFY7VREfmsuzHSOnoKs/9/Y983ayOs7eRzqw== - dependencies: - "@types/jest" "*" - "@types/tough-cookie@*": version "4.0.2" resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.2.tgz#6286b4c7228d58ab7866d19716f3696e03a09397" @@ -11353,6 +11345,7 @@ stringz@^2.1.0: char-regex "^1.0.2" "strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: + name strip-ansi-cjs version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== From 67166de865b00a972e7d1c4e507c9f20a454efbd Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 28 Aug 2023 12:43:00 +0200 Subject: [PATCH 11/65] Add `from:me` syntax to search (#26660) --- app/lib/search_query_transformer.rb | 13 ++++++++----- app/services/statuses_search_service.rb | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/app/lib/search_query_transformer.rb b/app/lib/search_query_transformer.rb index 915f9c3312..f1fc687e47 100644 --- a/app/lib/search_query_transformer.rb +++ b/app/lib/search_query_transformer.rb @@ -85,8 +85,9 @@ class SearchQueryTransformer < Parslet::Transform class PrefixClause attr_reader :type, :filter, :operator, :term - def initialize(prefix, operator, term) + def initialize(prefix, operator, term, options = {}) @negated = operator == '-' + @options = options @operator = :filter case prefix @@ -105,15 +106,15 @@ class SearchQueryTransformer < Parslet::Transform when 'before' @filter = :created_at @type = :range - @term = { lt: term } + @term = { lt: term, time_zone: @options[:current_account]&.user_time_zone || 'UTC' } when 'after' @filter = :created_at @type = :range - @term = { gt: term } + @term = { gt: term, time_zone: @options[:current_account]&.user_time_zone || 'UTC' } when 'during' @filter = :created_at @type = :range - @term = { gte: term, lte: term } + @term = { gte: term, lte: term, time_zone: @options[:current_account]&.user_time_zone || 'UTC' } else raise Mastodon::SyntaxError end @@ -126,6 +127,8 @@ class SearchQueryTransformer < Parslet::Transform private def account_id_from_term(term) + return @options[:current_account]&.id || -1 if term == 'me' + username, domain = term.gsub(/\A@/, '').split('@') domain = nil if TagManager.instance.local_domain?(domain) account = Account.find_remote(username, domain) @@ -141,7 +144,7 @@ class SearchQueryTransformer < Parslet::Transform operator = clause[:operator]&.to_s if clause[:prefix] - PrefixClause.new(prefix, operator, clause[:term].to_s) + PrefixClause.new(prefix, operator, clause[:term].to_s, current_account: current_account) elsif clause[:term] TermClause.new(prefix, operator, clause[:term].to_s) elsif clause[:shortcode] diff --git a/app/services/statuses_search_service.rb b/app/services/statuses_search_service.rb index 0d0de2a9d2..2317a2a1ac 100644 --- a/app/services/statuses_search_service.rb +++ b/app/services/statuses_search_service.rb @@ -59,6 +59,6 @@ class StatusesSearchService < BaseService end def parsed_query - SearchQueryTransformer.new.apply(SearchQueryParser.new.parse(@query)) + SearchQueryTransformer.new.apply(SearchQueryParser.new.parse(@query), current_account: @account) end end From bceb8931591b4b9df6e8dcfb47864c230884262c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 28 Aug 2023 13:18:39 +0200 Subject: [PATCH 12/65] Add search options to search popout in web UI (#26662) --- .../features/compose/components/search.jsx | 47 +++++++++++++++++-- app/javascript/mastodon/locales/en.json | 4 ++ .../styles/mastodon/components.scss | 6 +++ 3 files changed, 52 insertions(+), 5 deletions(-) diff --git a/app/javascript/mastodon/features/compose/components/search.jsx b/app/javascript/mastodon/features/compose/components/search.jsx index 682f8d3c8c..1c629bcbb4 100644 --- a/app/javascript/mastodon/features/compose/components/search.jsx +++ b/app/javascript/mastodon/features/compose/components/search.jsx @@ -1,7 +1,7 @@ import PropTypes from 'prop-types'; import { PureComponent } from 'react'; -import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; +import { defineMessages, injectIntl, FormattedMessage, FormattedList } from 'react-intl'; import classNames from 'classnames'; @@ -45,6 +45,16 @@ class Search extends PureComponent { options: [], }; + defaultOptions = [ + { label: <>has: , action: e => { e.preventDefault(); this._insertText('has:') } }, + { label: <>is: , action: e => { e.preventDefault(); this._insertText('is:') } }, + { label: <>language: , action: e => { e.preventDefault(); this._insertText('language:') } }, + { label: <>from: , action: e => { e.preventDefault(); this._insertText('from:') } }, + { label: <>before: , action: e => { e.preventDefault(); this._insertText('before:') } }, + { label: <>during: , action: e => { e.preventDefault(); this._insertText('during:') } }, + { label: <>after: , action: e => { e.preventDefault(); this._insertText('after:') } }, + ]; + setRef = c => { this.searchForm = c; }; @@ -70,7 +80,7 @@ class Search extends PureComponent { handleKeyDown = (e) => { const { selectedOption } = this.state; - const options = this._getOptions(); + const options = this._getOptions().concat(this.defaultOptions); switch(e.key) { case 'Escape': @@ -100,11 +110,9 @@ class Search extends PureComponent { if (selectedOption === -1) { this._submit(); } else if (options.length > 0) { - options[selectedOption].action(); + options[selectedOption].action(e); } - this._unfocus(); - break; case 'Delete': if (selectedOption > -1 && options.length > 0) { @@ -147,6 +155,7 @@ class Search extends PureComponent { router.history.push(`/tags/${query}`); onClickSearchResult(query, 'hashtag'); + this._unfocus(); }; handleAccountClick = () => { @@ -157,6 +166,7 @@ class Search extends PureComponent { router.history.push(`/@${query}`); onClickSearchResult(query, 'account'); + this._unfocus(); }; handleURLClick = () => { @@ -164,6 +174,7 @@ class Search extends PureComponent { const { value, onOpenURL } = this.props; onOpenURL(value, router.history); + this._unfocus(); }; handleStatusSearch = () => { @@ -182,6 +193,8 @@ class Search extends PureComponent { } else if (search.get('type') === 'hashtag') { router.history.push(`/tags/${search.get('q')}`); } + + this._unfocus(); }; handleForgetRecentSearchClick = search => { @@ -194,6 +207,18 @@ class Search extends PureComponent { document.querySelector('.ui').parentElement.focus(); } + _insertText (text) { + const { value, onChange } = this.props; + + if (value === '') { + onChange(text); + } else if (value[value.length - 1] === ' ') { + onChange(`${value}${text}`); + } else { + onChange(`${value} ${text}`); + } + } + _submit (type) { const { onSubmit, openInRoute } = this.props; const { router } = this.context; @@ -203,6 +228,8 @@ class Search extends PureComponent { if (openInRoute) { router.history.push('/search'); } + + this._unfocus(); } _getOptions () { @@ -325,6 +352,16 @@ class Search extends PureComponent { )} + +

+ +
+ {this.defaultOptions.map(({ key, label, action }, i) => ( + + ))} +
); diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index 5eeaf8044b..5871b08def 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -586,8 +586,12 @@ "search.quick_action.open_url": "Open URL in Mastodon", "search.quick_action.status_search": "Posts matching {x}", "search.search_or_paste": "Search or paste URL", + "search_popout.language_code": "ISO language code", + "search_popout.options": "Search options", "search_popout.quick_actions": "Quick actions", "search_popout.recent": "Recent searches", + "search_popout.specific_date": "specific date", + "search_popout.user": "user", "search_results.accounts": "Profiles", "search_results.all": "All", "search_results.hashtags": "Hashtags", diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 7e7bf4488c..6fa5c545ea 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -4991,6 +4991,12 @@ a.status-card { } &__menu { + margin-bottom: 20px; + + &:last-child { + margin-bottom: 0; + } + &__message { color: $dark-text-color; padding: 0 10px; From 0cce7fb6172680fb5819c4d61d7adfba4147dfc1 Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 28 Aug 2023 15:04:57 +0200 Subject: [PATCH 13/65] Fix incorrect call to `PublicStatusesIndex.import` (#26697) --- app/models/concerns/account_statuses_search.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/concerns/account_statuses_search.rb b/app/models/concerns/account_statuses_search.rb index 626bf38900..fa9238e6ef 100644 --- a/app/models/concerns/account_statuses_search.rb +++ b/app/models/concerns/account_statuses_search.rb @@ -32,7 +32,7 @@ module AccountStatusesSearch return unless Chewy.enabled? statuses.without_reblogs.where(visibility: :public).find_in_batches do |batch| - PublicStatusesIndex.import(query: batch) + PublicStatusesIndex.import(batch) end end From 2304cc6456a5a03624e94849f95d324b132ee72b Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 28 Aug 2023 17:08:37 +0200 Subject: [PATCH 14/65] Fix bad search type heuristic (#26673) --- app/services/search_service.rb | 14 ++++++-------- spec/services/search_service_spec.rb | 9 --------- 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/app/services/search_service.rb b/app/services/search_service.rb index 4e1e7ea26e..40d82fc525 100644 --- a/app/services/search_service.rb +++ b/app/services/search_service.rb @@ -17,7 +17,7 @@ class SearchService < BaseService results.merge!(url_resource_results) unless url_resource.nil? || @offset.positive? || (@options[:type].present? && url_resource_symbol != @options[:type].to_sym) elsif @query.present? results[:accounts] = perform_accounts_search! if account_searchable? - results[:statuses] = perform_statuses_search! if full_text_searchable? + results[:statuses] = perform_statuses_search! if status_searchable? results[:hashtags] = perform_hashtags_search! if hashtag_searchable? end end @@ -79,18 +79,16 @@ class SearchService < BaseService url_resource.class.name.downcase.pluralize.to_sym end - def full_text_searchable? - return false unless Chewy.enabled? - - statuses_search? && !@account.nil? && !(@query.include?('@') && !@query.include?(' ')) + def status_searchable? + Chewy.enabled? && status_search? && @account.present? end def account_searchable? - account_search? && !(@query.include?('@') && @query.include?(' ')) + account_search? end def hashtag_searchable? - hashtag_search? && !@query.include?('@') + hashtag_search? end def account_search? @@ -101,7 +99,7 @@ class SearchService < BaseService @options[:type].blank? || @options[:type] == 'hashtags' end - def statuses_search? + def status_search? @options[:type].blank? || @options[:type] == 'statuses' end end diff --git a/spec/services/search_service_spec.rb b/spec/services/search_service_spec.rb index 123bd4f560..cb69af5f54 100644 --- a/spec/services/search_service_spec.rb +++ b/spec/services/search_service_spec.rb @@ -83,15 +83,6 @@ describe SearchService, type: :service do expect(Tag).to have_received(:search_for).with('tag', 10, 0, exclude_unreviewed: nil) expect(results).to eq empty_results.merge(hashtags: [tag]) end - - it 'does not include tag when starts with @ character' do - query = '@username' - allow(Tag).to receive(:search_for) - - results = subject.call(query, nil, 10) - expect(Tag).to_not have_received(:search_for) - expect(results).to eq empty_results - end end end end From dd72a8d28b4479afdc19ac73cac83609d85b5f9e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 28 Aug 2023 17:10:58 +0200 Subject: [PATCH 15/65] Update dependency stoplight to v3.0.2 (#26698) 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 7a68249c28..49ada55d2a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -731,7 +731,7 @@ GEM net-ssh (>= 2.8.0) stackprof (0.2.25) statsd-ruby (1.5.0) - stoplight (3.0.1) + stoplight (3.0.2) redlock (~> 1.0) strong_migrations (0.8.0) activerecord (>= 5.2) From 01b87a1632a9024eb8be807cfc41a592b6a3c8ce Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 28 Aug 2023 19:40:08 +0200 Subject: [PATCH 16/65] Change video compression parameters (#26631) --- app/models/media_attachment.rb | 16 ++++++---------- lib/paperclip/transcoder.rb | 10 ++++++++-- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/app/models/media_attachment.rb b/app/models/media_attachment.rb index 7474b5653f..88abd93390 100644 --- a/app/models/media_attachment.rb +++ b/app/models/media_attachment.rb @@ -44,6 +44,7 @@ class MediaAttachment < ApplicationRecord MAX_VIDEO_MATRIX_LIMIT = 8_294_400 # 3840x2160px MAX_VIDEO_FRAME_RATE = 120 + MAX_VIDEO_FRAMES = 36_000 # Approx. 5 minutes at 120 fps IMAGE_FILE_EXTENSIONS = %w(.jpg .jpeg .png .gif .webp .heic .heif .avif).freeze VIDEO_FILE_EXTENSIONS = %w(.webm .mp4 .m4v .mov).freeze @@ -98,17 +99,12 @@ class MediaAttachment < ApplicationRecord convert_options: { output: { 'loglevel' => 'fatal', - 'movflags' => 'faststart', - 'pix_fmt' => 'yuv420p', - 'vf' => 'scale=\'trunc(iw/2)*2:trunc(ih/2)*2\'', - 'vsync' => 'cfr', + 'preset' => 'veryfast', 'c:v' => 'h264', - 'maxrate' => '1300K', - 'bufsize' => '1300K', - 'b:v' => '1300K', - 'frames:v' => 60 * 60 * 3, - 'crf' => 18, + 'c:a' => 'aac', + 'b:a' => '192k', 'map_metadata' => '-1', + 'frames:v' => MAX_VIDEO_FRAMES, }.freeze, }.freeze, }.freeze @@ -135,7 +131,7 @@ class MediaAttachment < ApplicationRecord convert_options: { output: { 'loglevel' => 'fatal', - :vf => 'scale=\'min(400\, iw):min(400\, ih)\':force_original_aspect_ratio=decrease', + :vf => 'scale=\'min(640\, iw):min(640\, ih)\':force_original_aspect_ratio=decrease', }.freeze, }.freeze, format: 'png', diff --git a/lib/paperclip/transcoder.rb b/lib/paperclip/transcoder.rb index 0f2e30f7d5..b88cf662c2 100644 --- a/lib/paperclip/transcoder.rb +++ b/lib/paperclip/transcoder.rb @@ -4,6 +4,9 @@ module Paperclip # This transcoder is only to be used for the MediaAttachment model # to check when uploaded videos are actually gifv's class Transcoder < Paperclip::Processor + # This is the H.264 "High" value taken from https://www.dr-lex.be/info-stuff/videocalc.html + BITS_PER_PIXEL = 0.11 + def initialize(file, options = {}, attachment = nil) super @@ -38,8 +41,11 @@ module Paperclip @output_options['vframes'] = 1 when 'mp4' unless eligible_to_passthrough?(metadata) - @output_options['acodec'] = 'aac' - @output_options['strict'] = 'experimental' + bitrate = (metadata.width * metadata.height * 30 * BITS_PER_PIXEL) / 1_000 + + @output_options['b:v'] = "#{bitrate}k" + @output_options['maxrate'] = "#{bitrate + 192}k" + @output_options['bufsize'] = "#{bitrate * 5}k" if high_vfr?(metadata) @output_options['vsync'] = 'vfr' From 10b06436d13702aedaa92a8ece84fbfde2829d57 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 28 Aug 2023 19:49:38 +0200 Subject: [PATCH 17/65] Fix colors and typography on hashtag bar in web UI (#26666) --- .../mastodon/components/hashtag_bar.tsx | 6 +++--- .../styles/mastodon/components.scss | 19 ++++++++++++------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/app/javascript/mastodon/components/hashtag_bar.tsx b/app/javascript/mastodon/components/hashtag_bar.tsx index 674c481b81..d45a6e20eb 100644 --- a/app/javascript/mastodon/components/hashtag_bar.tsx +++ b/app/javascript/mastodon/components/hashtag_bar.tsx @@ -10,8 +10,8 @@ import { groupBy, minBy } from 'lodash'; import { getStatusContent } from './status_content'; -// About two lines on desktop -const VISIBLE_HASHTAGS = 7; +// Fit on a single line on desktop +const VISIBLE_HASHTAGS = 3; // Those types are not correct, they need to be replaced once this part of the state is typed export type TagLike = Record<{ name: string }>; @@ -210,7 +210,7 @@ const HashtagBar: React.FC<{ const revealedHashtags = expanded ? hashtags - : hashtags.slice(0, VISIBLE_HASHTAGS - 1); + : hashtags.slice(0, VISIBLE_HASHTAGS); return (
diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 6fa5c545ea..c07f95f564 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -9308,19 +9308,24 @@ noscript { display: flex; flex-wrap: wrap; font-size: 14px; + line-height: 18px; gap: 4px; + color: $darker-text-color; a { display: inline-flex; - color: $dark-text-color; + color: inherit; text-decoration: none; - &:hover { - text-decoration: none; - - span { - text-decoration: underline; - } + &:hover span { + text-decoration: underline; } } + + .link-button { + color: inherit; + font-size: inherit; + line-height: inherit; + padding: 0; + } } From a7d96e6affd4a2da65f09f3f4ffa1b9350bb9a42 Mon Sep 17 00:00:00 2001 From: Lukas Martini Date: Tue, 29 Aug 2023 09:14:44 +0200 Subject: [PATCH 18/65] Improve error messages when DeepL quota is exceeded (#26704) --- .../api/v1/statuses/translations_controller.rb | 10 +++++++++- config/locales/en.yml | 4 ++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/app/controllers/api/v1/statuses/translations_controller.rb b/app/controllers/api/v1/statuses/translations_controller.rb index 540b17d009..ec5ea5b85b 100644 --- a/app/controllers/api/v1/statuses/translations_controller.rb +++ b/app/controllers/api/v1/statuses/translations_controller.rb @@ -8,7 +8,15 @@ class Api::V1::Statuses::TranslationsController < Api::BaseController before_action :set_translation rescue_from TranslationService::NotConfiguredError, with: :not_found - rescue_from TranslationService::UnexpectedResponseError, TranslationService::QuotaExceededError, TranslationService::TooManyRequestsError, with: :service_unavailable + rescue_from TranslationService::UnexpectedResponseError, with: :service_unavailable + + rescue_from TranslationService::QuotaExceededError do + render json: { error: I18n.t('translation.errors.quota_exceeded') }, status: 503 + end + + rescue_from TranslationService::TooManyRequestsError do + render json: { error: I18n.t('translation.errors.too_many_requests') }, status: 503 + end def create render json: @translation, serializer: REST::TranslationSerializer diff --git a/config/locales/en.yml b/config/locales/en.yml index 71121bb2e2..8bdfd1ec91 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1709,6 +1709,10 @@ en: default: "%b %d, %Y, %H:%M" month: "%b %Y" time: "%H:%M" + translation: + errors: + quota_exceeded: The server-wide usage quota for the translation service has been exceeded. + too_many_requests: There have been too many requests to the translation service recently. two_factor_authentication: add: Add disable: Disable 2FA From 0719216368bf3a90fdb7ab27201a0607b63ea203 Mon Sep 17 00:00:00 2001 From: Christian Schmidt Date: Tue, 29 Aug 2023 10:16:18 +0200 Subject: [PATCH 19/65] Remove dead code from public.jsx (#26547) --- app/javascript/packs/public.jsx | 81 ++++----------------------------- 1 file changed, 9 insertions(+), 72 deletions(-) diff --git a/app/javascript/packs/public.jsx b/app/javascript/packs/public.jsx index 1d917d60ee..ae4a7410e1 100644 --- a/app/javascript/packs/public.jsx +++ b/app/javascript/packs/public.jsx @@ -7,8 +7,6 @@ import { defineMessages } from 'react-intl'; import { delegate } from '@rails/ujs'; import axios from 'axios'; -import escapeTextContentForBrowser from 'escape-html'; -import { createBrowserHistory } from 'history'; import { throttle } from 'lodash'; import { start } from '../mastodon/common'; @@ -48,23 +46,6 @@ window.addEventListener('message', e => { function loaded() { const { messages: localeData } = getLocale(); - const scrollToDetailedStatus = () => { - const history = createBrowserHistory(); - const detailedStatuses = document.querySelectorAll('.public-layout .detailed-status'); - const location = history.location; - - if (detailedStatuses.length === 1 && (!location.state || !location.state.scrolledToDetailedStatus)) { - detailedStatuses[0].scrollIntoView(); - history.replace(location.pathname, { ...location.state, scrolledToDetailedStatus: true }); - } - }; - - const getEmojiAnimationHandler = (swapTo) => { - return ({ target }) => { - target.src = target.getAttribute(swapTo); - }; - }; - const locale = document.documentElement.lang; const dateTimeFormat = new Intl.DateTimeFormat(locale, { @@ -158,27 +139,21 @@ function loaded() { const root = createRoot(content); root.render(); document.body.appendChild(content); - scrollToDetailedStatus(); }) .catch(error => { console.error(error); - scrollToDetailedStatus(); }); - } else { - scrollToDetailedStatus(); } - delegate(document, '#user_account_attributes_username', 'input', throttle(() => { - const username = document.getElementById('user_account_attributes_username'); - - if (username.value && username.value.length > 0) { - axios.get('/api/v1/accounts/lookup', { params: { acct: username.value } }).then(() => { - username.setCustomValidity(formatMessage(messages.usernameTaken)); + delegate(document, '#user_account_attributes_username', 'input', throttle(({ target }) => { + if (target.value && target.value.length > 0) { + axios.get('/api/v1/accounts/lookup', { params: { acct: target.value } }).then(() => { + target.setCustomValidity(formatMessage(messages.usernameTaken)); }).catch(() => { - username.setCustomValidity(''); + target.setCustomValidity(''); }); } else { - username.setCustomValidity(''); + target.setCustomValidity(''); } }, 500, { leading: false, trailing: true })); @@ -196,9 +171,6 @@ function loaded() { } }); - delegate(document, '.custom-emoji', 'mouseover', getEmojiAnimationHandler('data-original')); - delegate(document, '.custom-emoji', 'mouseout', getEmojiAnimationHandler('data-static')); - delegate(document, '.status__content__spoiler-link', 'click', function() { const statusEl = this.parentNode.parentNode; @@ -220,17 +192,6 @@ function loaded() { }); } -delegate(document, '#account_display_name', 'input', ({ target }) => { - const name = document.querySelector('.card .display-name strong'); - if (name) { - if (target.value) { - name.innerHTML = emojify(escapeTextContentForBrowser(target.value)); - } else { - name.textContent = target.dataset.default; - } - } -}); - delegate(document, '#edit_profile input[type=file]', 'change', ({ target }) => { const avatar = document.getElementById(target.id + '-preview'); const [file] = target.files || []; @@ -239,33 +200,6 @@ delegate(document, '#edit_profile input[type=file]', 'change', ({ target }) => { avatar.src = url; }); -const getProfileAvatarAnimationHandler = (swapTo) => { - //animate avatar gifs on the profile page when moused over - return ({ target }) => { - const swapSrc = target.getAttribute(swapTo); - //only change the img source if autoplay is off and the image src is actually different - if(target.getAttribute('data-autoplay') !== 'true' && target.src !== swapSrc) { - target.src = swapSrc; - } - }; -}; - -delegate(document, 'img#profile_page_avatar', 'mouseover', getProfileAvatarAnimationHandler('data-original')); - -delegate(document, 'img#profile_page_avatar', 'mouseout', getProfileAvatarAnimationHandler('data-static')); - -delegate(document, '#account_locked', 'change', ({ target }) => { - const lock = document.querySelector('.card .display-name i'); - - if (lock) { - if (target.checked) { - delete lock.dataset.hidden; - } else { - lock.dataset.hidden = 'true'; - } - } -}); - delegate(document, '.input-copy input', 'click', ({ target }) => { target.focus(); target.select(); @@ -325,6 +259,9 @@ delegate(document, '.sidebar__toggle__icon', 'keydown', e => { } }); +delegate(document, '.custom-emoji', 'mouseover', ({ target }) => target.src = target.getAttribute('data-original')); +delegate(document, '.custom-emoji', 'mouseout', ({ target }) => target.src = target.getAttribute('data-static')); + // Empty the honeypot fields in JS in case something like an extension // automatically filled them. delegate(document, '#registration_new_user,#new_user', 'submit', () => { From 286a21afdc427a24a32d506dcb5355df434e22ce Mon Sep 17 00:00:00 2001 From: Christian Schmidt Date: Tue, 29 Aug 2023 10:17:57 +0200 Subject: [PATCH 20/65] Support webpacker live-reloading on Docker (#26419) --- .devcontainer/docker-compose.yml | 1 + Procfile.dev | 2 +- config/initializers/content_security_policy.rb | 3 ++- config/webpacker.yml | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml index a2658ea8ba..20aecd71d6 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -25,6 +25,7 @@ services: command: sleep infinity ports: - '127.0.0.1:3000:3000' + - '127.0.0.1:3035:3035' - '127.0.0.1:4000:4000' networks: - external_network diff --git a/Procfile.dev b/Procfile.dev index ba04fb661b..fbb2c2de23 100644 --- a/Procfile.dev +++ b/Procfile.dev @@ -1,4 +1,4 @@ web: env PORT=3000 RAILS_ENV=development bundle exec puma -C config/puma.rb sidekiq: env PORT=3000 RAILS_ENV=development bundle exec sidekiq stream: env PORT=4000 yarn run start -webpack: ./bin/webpack-dev-server --listen-host 0.0.0.0 +webpack: bin/webpack-dev-server diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb index 98c4f541f3..59ac3bdea2 100644 --- a/config/initializers/content_security_policy.rb +++ b/config/initializers/content_security_policy.rb @@ -34,7 +34,8 @@ Rails.application.config.content_security_policy do |p| p.worker_src :self, :blob, assets_host if Rails.env.development? - webpacker_urls = %w(ws http).map { |protocol| "#{protocol}#{Webpacker.dev_server.https? ? 's' : ''}://#{Webpacker.dev_server.host_with_port}" } + webpacker_public_host = ENV.fetch('WEBPACKER_DEV_SERVER_PUBLIC', Webpacker.config.dev_server[:public]) + webpacker_urls = %w(ws http).map { |protocol| "#{protocol}#{Webpacker.dev_server.https? ? 's' : ''}://#{webpacker_public_host}" } p.connect_src :self, :data, :blob, assets_host, media_host, Rails.configuration.x.streaming_api_base_url, *webpacker_urls p.script_src :self, :unsafe_inline, :unsafe_eval, assets_host diff --git a/config/webpacker.yml b/config/webpacker.yml index 6fd0fa1a0c..f8462e53a0 100644 --- a/config/webpacker.yml +++ b/config/webpacker.yml @@ -58,7 +58,7 @@ development: # Reference: https://webpack.js.org/configuration/dev-server/ dev_server: https: false - host: localhost + host: 0.0.0.0 port: 3035 public: localhost:3035 hmr: false From 075cc8e8a64bd43b83865c7beddb877787ed674f Mon Sep 17 00:00:00 2001 From: Christian Schmidt Date: Tue, 29 Aug 2023 10:20:36 +0200 Subject: [PATCH 21/65] Improve Codespaces port forwarding (#26400) --- .devcontainer/Dockerfile | 4 -- .devcontainer/codespaces/devcontainer.json | 49 ++++++++++++++++++++++ .devcontainer/devcontainer.json | 22 +++++++--- README.md | 34 +++++++++++---- config/environments/development.rb | 2 + 5 files changed, 93 insertions(+), 18 deletions(-) create mode 100644 .devcontainer/codespaces/devcontainer.json diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index f991036add..b3b1d97a24 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -4,10 +4,6 @@ FROM mcr.microsoft.com/devcontainers/ruby:1-3.2-bullseye # Install Rails # RUN gem install rails webdrivers -# Default value to allow debug server to serve content over GitHub Codespace's port forwarding service -# The value is a comma-separated list of allowed domains -ENV RAILS_DEVELOPMENT_HOSTS=".githubpreview.dev,.preview.app.github.dev,.app.github.dev" - ARG NODE_VERSION="16" RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1" diff --git a/.devcontainer/codespaces/devcontainer.json b/.devcontainer/codespaces/devcontainer.json new file mode 100644 index 0000000000..ca9156fdaa --- /dev/null +++ b/.devcontainer/codespaces/devcontainer.json @@ -0,0 +1,49 @@ +{ + "name": "Mastodon on GitHub Codespaces", + "dockerComposeFile": "../docker-compose.yml", + "service": "app", + "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}", + + "features": { + "ghcr.io/devcontainers/features/sshd:1": {} + }, + + "runServices": ["app", "db", "redis"], + + "forwardPorts": [3000, 4000], + + "portsAttributes": { + "3000": { + "label": "web", + "onAutoForward": "notify" + }, + "4000": { + "label": "stream", + "onAutoForward": "silent" + } + }, + + "otherPortsAttributes": { + "onAutoForward": "silent" + }, + + "remoteEnv": { + "LOCAL_DOMAIN": "${localEnv:CODESPACE_NAME}-3000.app.github.dev", + "LOCAL_HTTPS": "true", + "STREAMING_API_BASE_URL": "https://${localEnv:CODESPACE_NAME}-4000.app.github.dev", + "DISABLE_FORGERY_REQUEST_PROTECTION": "true", + "ES_ENABLED": "", + "LIBRE_TRANSLATE_ENDPOINT": "" + }, + + "onCreateCommand": "git config --global --add safe.directory ${containerWorkspaceFolder}", + "postCreateCommand": ".devcontainer/post-create.sh", + "waitFor": "postCreateCommand", + + "customizations": { + "vscode": { + "settings": {}, + "extensions": ["EditorConfig.EditorConfig", "webben.browserslist"] + } + } +} diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index ce14169aae..fa8d6542c1 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,5 +1,5 @@ { - "name": "Mastodon", + "name": "Mastodon on local machine", "dockerComposeFile": "docker-compose.yml", "service": "app", "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}", @@ -8,13 +8,23 @@ "ghcr.io/devcontainers/features/sshd:1": {} }, - "runServices": ["app", "db", "redis"], - "forwardPorts": [3000, 4000], - "containerEnv": { - "ES_ENABLED": "", - "LIBRE_TRANSLATE_ENDPOINT": "" + "portsAttributes": { + "3000": { + "label": "web", + "onAutoForward": "notify", + "requireLocalPort": true + }, + "4000": { + "label": "stream", + "onAutoForward": "silent", + "requireLocalPort": true + } + }, + + "otherPortsAttributes": { + "onAutoForward": "silent" }, "onCreateCommand": "git config --global --add safe.directory ${containerWorkspaceFolder}", diff --git a/README.md b/README.md index 37cd3dfb46..e925bec519 100644 --- a/README.md +++ b/README.md @@ -59,13 +59,13 @@ Mastodon acts as an OAuth2 provider, so 3rd party apps can use the REST and Stre ## Deployment -### Tech stack: +### Tech stack - **Ruby on Rails** powers the REST API and other web pages - **React.js** and Redux are used for the dynamic parts of the interface - **Node.js** powers the streaming API -### Requirements: +### Requirements - **PostgreSQL** 9.5+ - **Redis** 4+ @@ -74,6 +74,10 @@ Mastodon acts as an OAuth2 provider, so 3rd party apps can use the REST and Stre The repository includes deployment configurations for **Docker and docker-compose** as well as specific platforms like **Heroku**, **Scalingo**, and **Nanobox**. For Helm charts, reference the [mastodon/chart repository](https://github.com/mastodon/chart). The [**standalone** installation guide](https://docs.joinmastodon.org/admin/install/) is available in the documentation. +## Development + +### Vagrant + A **Vagrant** configuration is included for development purposes. To use it, complete the following steps: - Install Vagrant and Virtualbox @@ -82,9 +86,11 @@ A **Vagrant** configuration is included for development purposes. To use it, com - Run `vagrant ssh -c "cd /vagrant && foreman start"` - Open `http://mastodon.local` in your browser +### MacOS + To set up **MacOS** for native development, complete the following steps: -- Install the latest stable Ruby version (use a ruby version manager for easy installation and management of ruby versions) +- Install the latest stable Ruby version (use a Ruby version manager for easy installation and management of Ruby versions) - Run `brew install postgresql@14` - Run `brew install redis` - Run `brew install imagemagick` @@ -94,15 +100,27 @@ To set up **MacOS** for native development, complete the following steps: - Run `bundle exec rails db:setup` (optionally prepend `RAILS_ENV=development` to target the dev environment) - Finally, run `overmind start -f Procfile.dev` -### Getting Started with GitHub Codespaces +### Docker -To get started, create a codespace for this repository by clicking this 👇 +For development with **Docker**, complete the following steps: -[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new?hide_repo_select=true&ref=main&repo=52281283) +- Install Docker Desktop +- Run `docker compose -f .devcontainer/docker-compose.yml up -d` +- Run `docker compose -f .devcontainer/docker-compose.yml exec app .devcontainer/post-create.sh` +- Finally, run `docker compose -f .devcontainer/docker-compose.yml exec app foreman start -f Procfile.dev` -A codespace will open in a web-based version of Visual Studio Code. The [dev container](.devcontainer/devcontainer.json) is fully configured with the software needed for this project. +If you are using an IDE with [support for the Development Container specification](https://containers.dev/supporting), it will run the above `docker compose` commands automatically. For **Visual Studio Code** this requires the [Dev Container extension](https://containers.dev/supporting#dev-containers). -**Note**: Dev containers are an open spec that is supported by [GitHub Codespaces](https://github.com/codespaces) and [other tools](https://containers.dev/supporting). +### GitHub Codespaces + +To get you coding in just a few minutes, GitHub Codespaces provides a web-based version of Visual Studio Code and a cloud-hosted development environment fully configured with the software needed for this project.. + +- Click this button to create a new codespace:
+ [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new?hide_repo_select=true&ref=main&repo=52281283&devcontainer_path=.devcontainer%2Fcodespaces%2Fdevcontainer.json) +- Wait for the environment to build. This will take a few minutes. +- When the editor is ready, run `foreman start -f Procfile.dev` in the terminal. +- After a few seconds, a popup will appear with a button labeled _Open in Browser_. This will open Mastodon. +- On the _Ports_ tab, right click on the “stream” row and select _Port visibility_ → _Public_. ## Contributing diff --git a/config/environments/development.rb b/config/environments/development.rb index 31a3962458..9a6637bdb9 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -35,6 +35,8 @@ Rails.application.configure do config.cache_store = :null_store end + config.action_controller.forgery_protection_origin_check = ENV['DISABLE_FORGERY_REQUEST_PROTECTION'].nil? + ActiveSupport::Logger.new(STDOUT).tap do |logger| logger.formatter = config.log_formatter config.logger = ActiveSupport::TaggedLogging.new(logger) From 25bf6406290f49f87c6ed00474702d6729fc98f2 Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 29 Aug 2023 10:29:07 +0200 Subject: [PATCH 22/65] Add debug logging on signature verification failure (#26637) --- app/controllers/concerns/signature_verification.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controllers/concerns/signature_verification.rb b/app/controllers/concerns/signature_verification.rb index 1d27c92c8c..b0c4fff8bc 100644 --- a/app/controllers/concerns/signature_verification.rb +++ b/app/controllers/concerns/signature_verification.rb @@ -119,6 +119,8 @@ module SignatureVerification private def fail_with!(message, **options) + Rails.logger.warn { "Signature verification failed: #{message}" } + @signature_verification_failure_reason = { error: message }.merge(options) @signed_request_actor = nil end From a67cf439eebe0763ae920d242dfe7b8cd0730f23 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 29 Aug 2023 10:50:27 +0200 Subject: [PATCH 23/65] Update dependency axios to v1.5.0 (#26680) 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 3e9c9abf77..0f34ad3551 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3344,9 +3344,9 @@ axe-core@^4.6.2: integrity sha512-zIURGIS1E1Q4pcrMjp+nnEh+16G56eG/MUllJH8yEvw7asDo7Ac9uhC9KIH5jzpITueEZolfYglnCGIuSBz39g== axios@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.4.0.tgz#38a7bf1224cd308de271146038b551d725f0be1f" - integrity sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA== + version "1.5.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.5.0.tgz#f02e4af823e2e46a9768cfc74691fdd0517ea267" + integrity sha512-D4DdjDo5CY50Qms0qGQTTw6Q44jl7zRwY7bthds06pUGfChBCTcQs+N743eFWGEd6pRTMd6A+I87aWyFV5wiZQ== dependencies: follow-redirects "^1.15.0" form-data "^4.0.0" From 4ad1c5aa7174e5cef4ba9608a44429916a119bee Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 29 Aug 2023 10:53:01 +0200 Subject: [PATCH 24/65] Update dependency aws-sdk-s3 to v1.133.0 (#26616) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 49ada55d2a..f26856bf94 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -124,8 +124,8 @@ GEM attr_required (1.0.1) awrence (1.2.1) aws-eventstream (1.2.0) - aws-partitions (1.793.0) - aws-sdk-core (3.180.3) + aws-partitions (1.809.0) + aws-sdk-core (3.181.0) aws-eventstream (~> 1, >= 1.0.2) aws-partitions (~> 1, >= 1.651.0) aws-sigv4 (~> 1.5) @@ -133,8 +133,8 @@ GEM aws-sdk-kms (1.71.0) aws-sdk-core (~> 3, >= 3.177.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.132.1) - aws-sdk-core (~> 3, >= 3.179.0) + aws-sdk-s3 (1.133.0) + aws-sdk-core (~> 3, >= 3.181.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.6) aws-sigv4 (1.6.0) From ae6cf33321a9f240ef73666a552e552b65390012 Mon Sep 17 00:00:00 2001 From: Tim Rogers Date: Tue, 29 Aug 2023 03:56:19 -0500 Subject: [PATCH 25/65] Fix bug with favourited view on Toots only showing latest favouriting accounts (#26577) --- .../mastodon/actions/interactions.js | 58 ++++++++++++++++++- .../mastodon/features/favourites/index.jsx | 25 +++++--- .../mastodon/reducers/user_lists.js | 15 ++++- 3 files changed, 85 insertions(+), 13 deletions(-) diff --git a/app/javascript/mastodon/actions/interactions.js b/app/javascript/mastodon/actions/interactions.js index 092a67ea75..1ffd23db53 100644 --- a/app/javascript/mastodon/actions/interactions.js +++ b/app/javascript/mastodon/actions/interactions.js @@ -1,5 +1,6 @@ -import api from '../api'; +import api, { getLinks } from '../api'; +import { fetchRelationships } from './accounts'; import { importFetchedAccounts, importFetchedStatus } from './importer'; export const REBLOG_REQUEST = 'REBLOG_REQUEST'; @@ -26,6 +27,10 @@ export const FAVOURITES_FETCH_REQUEST = 'FAVOURITES_FETCH_REQUEST'; export const FAVOURITES_FETCH_SUCCESS = 'FAVOURITES_FETCH_SUCCESS'; export const FAVOURITES_FETCH_FAIL = 'FAVOURITES_FETCH_FAIL'; +export const FAVOURITES_EXPAND_REQUEST = 'FAVOURITES_EXPAND_REQUEST'; +export const FAVOURITES_EXPAND_SUCCESS = 'FAVOURITES_EXPAND_SUCCESS'; +export const FAVOURITES_EXPAND_FAIL = 'FAVOURITES_EXPAND_FAIL'; + export const PIN_REQUEST = 'PIN_REQUEST'; export const PIN_SUCCESS = 'PIN_SUCCESS'; export const PIN_FAIL = 'PIN_FAIL'; @@ -308,8 +313,10 @@ export function fetchFavourites(id) { dispatch(fetchFavouritesRequest(id)); api(getState).get(`/api/v1/statuses/${id}/favourited_by`).then(response => { + const next = getLinks(response).refs.find(link => link.rel === 'next'); dispatch(importFetchedAccounts(response.data)); - dispatch(fetchFavouritesSuccess(id, response.data)); + dispatch(fetchFavouritesSuccess(id, response.data, next ? next.uri : null)); + dispatch(fetchRelationships(response.data.map(item => item.id))); }).catch(error => { dispatch(fetchFavouritesFail(id, error)); }); @@ -323,17 +330,62 @@ export function fetchFavouritesRequest(id) { }; } -export function fetchFavouritesSuccess(id, accounts) { +export function fetchFavouritesSuccess(id, accounts, next) { return { type: FAVOURITES_FETCH_SUCCESS, id, accounts, + next, }; } export function fetchFavouritesFail(id, error) { return { type: FAVOURITES_FETCH_FAIL, + id, + error, + }; +} + +export function expandFavourites(id) { + return (dispatch, getState) => { + const url = getState().getIn(['user_lists', 'favourited_by', id, 'next']); + if (url === null) { + return; + } + + dispatch(expandFavouritesRequest(id)); + + api(getState).get(url).then(response => { + const next = getLinks(response).refs.find(link => link.rel === 'next'); + + dispatch(importFetchedAccounts(response.data)); + dispatch(expandFavouritesSuccess(id, response.data, next ? next.uri : null)); + dispatch(fetchRelationships(response.data.map(item => item.id))); + }).catch(error => dispatch(expandFavouritesFail(id, error))); + }; +} + +export function expandFavouritesRequest(id) { + return { + type: FAVOURITES_EXPAND_REQUEST, + id, + }; +} + +export function expandFavouritesSuccess(id, accounts, next) { + return { + type: FAVOURITES_EXPAND_SUCCESS, + id, + accounts, + next, + }; +} + +export function expandFavouritesFail(id, error) { + return { + type: FAVOURITES_EXPAND_FAIL, + id, error, }; } diff --git a/app/javascript/mastodon/features/favourites/index.jsx b/app/javascript/mastodon/features/favourites/index.jsx index bfde78708e..b8ba948728 100644 --- a/app/javascript/mastodon/features/favourites/index.jsx +++ b/app/javascript/mastodon/features/favourites/index.jsx @@ -8,7 +8,9 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; import { connect } from 'react-redux'; -import { fetchFavourites } from 'mastodon/actions/interactions'; +import { debounce } from 'lodash'; + +import { fetchFavourites, expandFavourites } from 'mastodon/actions/interactions'; import ColumnHeader from 'mastodon/components/column_header'; import { Icon } from 'mastodon/components/icon'; import { LoadingIndicator } from 'mastodon/components/loading_indicator'; @@ -21,7 +23,9 @@ const messages = defineMessages({ }); const mapStateToProps = (state, props) => ({ - accountIds: state.getIn(['user_lists', 'favourited_by', props.params.statusId]), + accountIds: state.getIn(['user_lists', 'favourited_by', props.params.statusId, 'items']), + hasMore: !!state.getIn(['user_lists', 'favourited_by', props.params.statusId, 'next']), + isLoading: state.getIn(['user_lists', 'favourited_by', props.params.statusId, 'isLoading'], true), }); class Favourites extends ImmutablePureComponent { @@ -30,6 +34,8 @@ class Favourites extends ImmutablePureComponent { params: PropTypes.object.isRequired, dispatch: PropTypes.func.isRequired, accountIds: ImmutablePropTypes.list, + hasMore: PropTypes.bool, + isLoading: PropTypes.bool, multiColumn: PropTypes.bool, intl: PropTypes.object.isRequired, }; @@ -40,18 +46,16 @@ class Favourites extends ImmutablePureComponent { } } - UNSAFE_componentWillReceiveProps (nextProps) { - if (nextProps.params.statusId !== this.props.params.statusId && nextProps.params.statusId) { - this.props.dispatch(fetchFavourites(nextProps.params.statusId)); - } - } - handleRefresh = () => { this.props.dispatch(fetchFavourites(this.props.params.statusId)); }; + handleLoadMore = debounce(() => { + this.props.dispatch(expandFavourites(this.props.params.statusId)); + }, 300, { leading: true }); + render () { - const { intl, accountIds, multiColumn } = this.props; + const { intl, accountIds, hasMore, isLoading, multiColumn } = this.props; if (!accountIds) { return ( @@ -75,6 +79,9 @@ class Favourites extends ImmutablePureComponent { diff --git a/app/javascript/mastodon/reducers/user_lists.js b/app/javascript/mastodon/reducers/user_lists.js index e33d365c9c..cc9a8b19a5 100644 --- a/app/javascript/mastodon/reducers/user_lists.js +++ b/app/javascript/mastodon/reducers/user_lists.js @@ -46,7 +46,12 @@ import { } from '../actions/blocks'; import { REBLOGS_FETCH_SUCCESS, + FAVOURITES_FETCH_REQUEST, FAVOURITES_FETCH_SUCCESS, + FAVOURITES_FETCH_FAIL, + FAVOURITES_EXPAND_REQUEST, + FAVOURITES_EXPAND_SUCCESS, + FAVOURITES_EXPAND_FAIL, } from '../actions/interactions'; import { MUTES_FETCH_REQUEST, @@ -136,7 +141,15 @@ export default function userLists(state = initialState, action) { case REBLOGS_FETCH_SUCCESS: return state.setIn(['reblogged_by', action.id], ImmutableList(action.accounts.map(item => item.id))); case FAVOURITES_FETCH_SUCCESS: - return state.setIn(['favourited_by', action.id], ImmutableList(action.accounts.map(item => item.id))); + return normalizeList(state, ['favourited_by', action.id], action.accounts, action.next); + case FAVOURITES_EXPAND_SUCCESS: + return appendToList(state, ['favourited_by', action.id], action.accounts, action.next); + case FAVOURITES_FETCH_REQUEST: + case FAVOURITES_EXPAND_REQUEST: + return state.setIn(['favourited_by', action.id, 'isLoading'], true); + case FAVOURITES_FETCH_FAIL: + case FAVOURITES_EXPAND_FAIL: + return state.setIn(['favourited_by', action.id, 'isLoading'], false); case NOTIFICATIONS_UPDATE: return action.notification.type === 'follow_request' ? normalizeFollowRequest(state, action.notification) : state; case FOLLOW_REQUESTS_FETCH_SUCCESS: From c0605747adf028c7f5c7cc8aeca01f8285aa6802 Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 29 Aug 2023 14:06:22 +0200 Subject: [PATCH 26/65] Fix N+1 in `tootctl search deploy` (#26710) --- .../public_statuses_index_importer.rb | 23 ++++++------------- app/lib/importer/statuses_index_importer.rb | 2 +- 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/app/lib/importer/public_statuses_index_importer.rb b/app/lib/importer/public_statuses_index_importer.rb index 8e36e36f90..72d02318b1 100644 --- a/app/lib/importer/public_statuses_index_importer.rb +++ b/app/lib/importer/public_statuses_index_importer.rb @@ -2,23 +2,14 @@ class Importer::PublicStatusesIndexImporter < Importer::BaseImporter def import! - indexable_statuses_scope.find_in_batches(batch_size: @batch_size) do |batch| - in_work_unit(batch.map(&:status_id)) do |status_ids| + scope.select(:id).find_in_batches(batch_size: @batch_size) do |batch| + in_work_unit(batch.pluck(:id)) do |status_ids| bulk = ActiveRecord::Base.connection_pool.with_connection do - Chewy::Index::Import::BulkBuilder.new(index, to_index: Status.includes(:media_attachments, :preloadable_poll).where(id: status_ids)).bulk_body + Chewy::Index::Import::BulkBuilder.new(index, to_index: Status.includes(:media_attachments, :preloadable_poll, :preview_cards).where(id: status_ids)).bulk_body end - indexed = 0 - deleted = 0 - - bulk.map! do |entry| - if entry[:index] - indexed += 1 - else - deleted += 1 - end - entry - end + indexed = bulk.count { |entry| entry[:index] } + deleted = bulk.count { |entry| entry[:delete] } Chewy::Index::Import::BulkRequest.new(index).perform(bulk) @@ -35,7 +26,7 @@ class Importer::PublicStatusesIndexImporter < Importer::BaseImporter PublicStatusesIndex end - def indexable_statuses_scope - Status.indexable.select('"statuses"."id", COALESCE("statuses"."reblog_of_id", "statuses"."id") AS status_id') + def scope + Status.indexable end end diff --git a/app/lib/importer/statuses_index_importer.rb b/app/lib/importer/statuses_index_importer.rb index b0721c2e02..0277cd0ef5 100644 --- a/app/lib/importer/statuses_index_importer.rb +++ b/app/lib/importer/statuses_index_importer.rb @@ -14,7 +14,7 @@ class Importer::StatusesIndexImporter < Importer::BaseImporter scope.find_in_batches(batch_size: @batch_size) do |tmp| in_work_unit(tmp.map(&:status_id)) do |status_ids| bulk = ActiveRecord::Base.connection_pool.with_connection do - Chewy::Index::Import::BulkBuilder.new(index, to_index: Status.includes(:media_attachments, :preloadable_poll).where(id: status_ids)).bulk_body + Chewy::Index::Import::BulkBuilder.new(index, to_index: Status.includes(:media_attachments, :preloadable_poll, :preview_cards).where(id: status_ids)).bulk_body end indexed = 0 From 74eb7dbf2d79b74f7d6f09ca3d39b3ba67f5f7bf Mon Sep 17 00:00:00 2001 From: Tim Rogers Date: Tue, 29 Aug 2023 07:42:20 -0500 Subject: [PATCH 27/65] Fix bug with reblogged view on Toots only showing latest reblogging accounts (#26574) --- .../mastodon/actions/interactions.js | 55 ++++++++++++++++++- .../mastodon/features/reblogs/index.jsx | 27 +++++---- .../mastodon/reducers/user_lists.js | 15 ++++- 3 files changed, 84 insertions(+), 13 deletions(-) diff --git a/app/javascript/mastodon/actions/interactions.js b/app/javascript/mastodon/actions/interactions.js index 1ffd23db53..7d0144438a 100644 --- a/app/javascript/mastodon/actions/interactions.js +++ b/app/javascript/mastodon/actions/interactions.js @@ -7,6 +7,10 @@ export const REBLOG_REQUEST = 'REBLOG_REQUEST'; export const REBLOG_SUCCESS = 'REBLOG_SUCCESS'; export const REBLOG_FAIL = 'REBLOG_FAIL'; +export const REBLOGS_EXPAND_REQUEST = 'REBLOGS_EXPAND_REQUEST'; +export const REBLOGS_EXPAND_SUCCESS = 'REBLOGS_EXPAND_SUCCESS'; +export const REBLOGS_EXPAND_FAIL = 'REBLOGS_EXPAND_FAIL'; + export const FAVOURITE_REQUEST = 'FAVOURITE_REQUEST'; export const FAVOURITE_SUCCESS = 'FAVOURITE_SUCCESS'; export const FAVOURITE_FAIL = 'FAVOURITE_FAIL'; @@ -278,8 +282,10 @@ export function fetchReblogs(id) { dispatch(fetchReblogsRequest(id)); api(getState).get(`/api/v1/statuses/${id}/reblogged_by`).then(response => { + const next = getLinks(response).refs.find(link => link.rel === 'next'); dispatch(importFetchedAccounts(response.data)); - dispatch(fetchReblogsSuccess(id, response.data)); + dispatch(fetchReblogsSuccess(id, response.data, next ? next.uri : null)); + dispatch(fetchRelationships(response.data.map(item => item.id))); }).catch(error => { dispatch(fetchReblogsFail(id, error)); }); @@ -293,17 +299,62 @@ export function fetchReblogsRequest(id) { }; } -export function fetchReblogsSuccess(id, accounts) { +export function fetchReblogsSuccess(id, accounts, next) { return { type: REBLOGS_FETCH_SUCCESS, id, accounts, + next, }; } export function fetchReblogsFail(id, error) { return { type: REBLOGS_FETCH_FAIL, + id, + error, + }; +} + +export function expandReblogs(id) { + return (dispatch, getState) => { + const url = getState().getIn(['user_lists', 'reblogged_by', id, 'next']); + if (url === null) { + return; + } + + dispatch(expandReblogsRequest(id)); + + api(getState).get(url).then(response => { + const next = getLinks(response).refs.find(link => link.rel === 'next'); + + dispatch(importFetchedAccounts(response.data)); + dispatch(expandReblogsSuccess(id, response.data, next ? next.uri : null)); + dispatch(fetchRelationships(response.data.map(item => item.id))); + }).catch(error => dispatch(expandReblogsFail(id, error))); + }; +} + +export function expandReblogsRequest(id) { + return { + type: REBLOGS_EXPAND_REQUEST, + id, + }; +} + +export function expandReblogsSuccess(id, accounts, next) { + return { + type: REBLOGS_EXPAND_SUCCESS, + id, + accounts, + next, + }; +} + +export function expandReblogsFail(id, error) { + return { + type: REBLOGS_EXPAND_FAIL, + id, error, }; } diff --git a/app/javascript/mastodon/features/reblogs/index.jsx b/app/javascript/mastodon/features/reblogs/index.jsx index 8bcef863f2..0c4e6dbb93 100644 --- a/app/javascript/mastodon/features/reblogs/index.jsx +++ b/app/javascript/mastodon/features/reblogs/index.jsx @@ -8,9 +8,11 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; import { connect } from 'react-redux'; +import { debounce } from 'lodash'; + import { Icon } from 'mastodon/components/icon'; -import { fetchReblogs } from '../../actions/interactions'; +import { fetchReblogs, expandReblogs } from '../../actions/interactions'; import ColumnHeader from '../../components/column_header'; import { LoadingIndicator } from '../../components/loading_indicator'; import ScrollableList from '../../components/scrollable_list'; @@ -22,7 +24,9 @@ const messages = defineMessages({ }); const mapStateToProps = (state, props) => ({ - accountIds: state.getIn(['user_lists', 'reblogged_by', props.params.statusId]), + accountIds: state.getIn(['user_lists', 'reblogged_by', props.params.statusId, 'items']), + hasMore: !!state.getIn(['user_lists', 'reblogged_by', props.params.statusId, 'next']), + isLoading: state.getIn(['user_lists', 'reblogged_by', props.params.statusId, 'isLoading'], true), }); class Reblogs extends ImmutablePureComponent { @@ -31,6 +35,8 @@ class Reblogs extends ImmutablePureComponent { params: PropTypes.object.isRequired, dispatch: PropTypes.func.isRequired, accountIds: ImmutablePropTypes.list, + hasMore: PropTypes.bool, + isLoading: PropTypes.bool, multiColumn: PropTypes.bool, intl: PropTypes.object.isRequired, }; @@ -39,20 +45,18 @@ class Reblogs extends ImmutablePureComponent { if (!this.props.accountIds) { this.props.dispatch(fetchReblogs(this.props.params.statusId)); } - } - - UNSAFE_componentWillReceiveProps(nextProps) { - if (nextProps.params.statusId !== this.props.params.statusId && nextProps.params.statusId) { - this.props.dispatch(fetchReblogs(nextProps.params.statusId)); - } - } + }; handleRefresh = () => { this.props.dispatch(fetchReblogs(this.props.params.statusId)); }; + handleLoadMore = debounce(() => { + this.props.dispatch(expandReblogs(this.props.params.statusId)); + }, 300, { leading: true }); + render () { - const { intl, accountIds, multiColumn } = this.props; + const { intl, accountIds, hasMore, isLoading, multiColumn } = this.props; if (!accountIds) { return ( @@ -76,6 +80,9 @@ class Reblogs extends ImmutablePureComponent { diff --git a/app/javascript/mastodon/reducers/user_lists.js b/app/javascript/mastodon/reducers/user_lists.js index cc9a8b19a5..089899398e 100644 --- a/app/javascript/mastodon/reducers/user_lists.js +++ b/app/javascript/mastodon/reducers/user_lists.js @@ -45,7 +45,12 @@ import { BLOCKS_EXPAND_FAIL, } from '../actions/blocks'; import { + REBLOGS_FETCH_REQUEST, REBLOGS_FETCH_SUCCESS, + REBLOGS_FETCH_FAIL, + REBLOGS_EXPAND_REQUEST, + REBLOGS_EXPAND_SUCCESS, + REBLOGS_EXPAND_FAIL, FAVOURITES_FETCH_REQUEST, FAVOURITES_FETCH_SUCCESS, FAVOURITES_FETCH_FAIL, @@ -139,7 +144,15 @@ export default function userLists(state = initialState, action) { case FOLLOWING_EXPAND_FAIL: return state.setIn(['following', action.id, 'isLoading'], false); case REBLOGS_FETCH_SUCCESS: - return state.setIn(['reblogged_by', action.id], ImmutableList(action.accounts.map(item => item.id))); + return normalizeList(state, ['reblogged_by', action.id], action.accounts, action.next); + case REBLOGS_EXPAND_SUCCESS: + return appendToList(state, ['reblogged_by', action.id], action.accounts, action.next); + case REBLOGS_FETCH_REQUEST: + case REBLOGS_EXPAND_REQUEST: + return state.setIn(['reblogged_by', action.id, 'isLoading'], true); + case REBLOGS_FETCH_FAIL: + case REBLOGS_EXPAND_FAIL: + return state.setIn(['reblogged_by', action.id, 'isLoading'], false); case FAVOURITES_FETCH_SUCCESS: return normalizeList(state, ['favourited_by', action.id], action.accounts, action.next); case FAVOURITES_EXPAND_SUCCESS: From 9e77ab7db245a9a4725600cf69a617c0be1f1018 Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 29 Aug 2023 17:51:13 +0200 Subject: [PATCH 28/65] Change private statuses index to index without crutches (#26713) --- app/chewy/statuses_index.rb | 31 ++------------------ app/lib/importer/statuses_index_importer.rb | 2 +- app/models/concerns/status_search_concern.rb | 28 +++++++----------- app/models/poll.rb | 1 + app/models/status.rb | 6 ++++ 5 files changed, 21 insertions(+), 47 deletions(-) diff --git a/app/chewy/statuses_index.rb b/app/chewy/statuses_index.rb index 6d33521051..2be7e45250 100644 --- a/app/chewy/statuses_index.rb +++ b/app/chewy/statuses_index.rb @@ -40,40 +40,13 @@ class StatusesIndex < Chewy::Index }, } - # We do not use delete_if option here because it would call a method that we - # expect to be called with crutches without crutches, causing n+1 queries - index_scope ::Status.unscoped.kept.without_reblogs.includes(:media_attachments, :preloadable_poll, :preview_cards) - - crutch :mentions do |collection| - data = ::Mention.where(status_id: collection.map(&:id)).where(account: Account.local, silent: false).pluck(:status_id, :account_id) - data.each.with_object({}) { |(id, name), result| (result[id] ||= []).push(name) } - end - - crutch :favourites do |collection| - data = ::Favourite.where(status_id: collection.map(&:id)).where(account: Account.local).pluck(:status_id, :account_id) - data.each.with_object({}) { |(id, name), result| (result[id] ||= []).push(name) } - end - - crutch :reblogs do |collection| - data = ::Status.where(reblog_of_id: collection.map(&:id)).where(account: Account.local).pluck(:reblog_of_id, :account_id) - data.each.with_object({}) { |(id, name), result| (result[id] ||= []).push(name) } - end - - crutch :bookmarks do |collection| - data = ::Bookmark.where(status_id: collection.map(&:id)).where(account: Account.local).pluck(:status_id, :account_id) - data.each.with_object({}) { |(id, name), result| (result[id] ||= []).push(name) } - end - - crutch :votes do |collection| - data = ::PollVote.joins(:poll).where(poll: { status_id: collection.map(&:id) }).where(account: Account.local).pluck(:status_id, :account_id) - data.each.with_object({}) { |(id, name), result| (result[id] ||= []).push(name) } - end + index_scope ::Status.unscoped.kept.without_reblogs.includes(:media_attachments, :preview_cards, :local_mentioned, :local_favorited, :local_reblogged, :local_bookmarked, preloadable_poll: :local_voters), delete_if: ->(status) { status.searchable_by.empty? } root date_detection: false do field(:id, type: 'long') field(:account_id, type: 'long') field(:text, type: 'text', analyzer: 'verbatim', value: ->(status) { status.searchable_text }) { field(:stemmed, type: 'text', analyzer: 'content') } - field(:searchable_by, type: 'long', value: ->(status, crutches) { status.searchable_by(crutches) }) + field(:searchable_by, type: 'long', value: ->(status) { status.searchable_by }) field(:language, type: 'keyword') field(:properties, type: 'keyword', value: ->(status) { status.searchable_properties }) field(:created_at, type: 'date') diff --git a/app/lib/importer/statuses_index_importer.rb b/app/lib/importer/statuses_index_importer.rb index 0277cd0ef5..285ddc871a 100644 --- a/app/lib/importer/statuses_index_importer.rb +++ b/app/lib/importer/statuses_index_importer.rb @@ -14,7 +14,7 @@ class Importer::StatusesIndexImporter < Importer::BaseImporter scope.find_in_batches(batch_size: @batch_size) do |tmp| in_work_unit(tmp.map(&:status_id)) do |status_ids| bulk = ActiveRecord::Base.connection_pool.with_connection do - Chewy::Index::Import::BulkBuilder.new(index, to_index: Status.includes(:media_attachments, :preloadable_poll, :preview_cards).where(id: status_ids)).bulk_body + Chewy::Index::Import::BulkBuilder.new(index, to_index: index.adapter.default_scope.where(id: status_ids)).bulk_body end indexed = 0 diff --git a/app/models/concerns/status_search_concern.rb b/app/models/concerns/status_search_concern.rb index 21048b5682..3ef45754ab 100644 --- a/app/models/concerns/status_search_concern.rb +++ b/app/models/concerns/status_search_concern.rb @@ -7,26 +7,20 @@ module StatusSearchConcern scope :indexable, -> { without_reblogs.where(visibility: :public).joins(:account).where(account: { indexable: true }) } end - def searchable_by(preloaded = nil) - ids = [] + def searchable_by + @searchable_by ||= begin + ids = [] - ids << account_id if local? + ids << account_id if local? - if preloaded.nil? - ids += mentions.joins(:account).merge(Account.local).active.pluck(:account_id) - ids += favourites.joins(:account).merge(Account.local).pluck(:account_id) - ids += reblogs.joins(:account).merge(Account.local).pluck(:account_id) - ids += bookmarks.joins(:account).merge(Account.local).pluck(:account_id) - ids += poll.votes.joins(:account).merge(Account.local).pluck(:account_id) if poll.present? - else - ids += preloaded.mentions[id] || [] - ids += preloaded.favourites[id] || [] - ids += preloaded.reblogs[id] || [] - ids += preloaded.bookmarks[id] || [] - ids += preloaded.votes[id] || [] + ids += local_mentioned.pluck(:id) + ids += local_favorited.pluck(:id) + ids += local_reblogged.pluck(:id) + ids += local_bookmarked.pluck(:id) + ids += preloadable_poll.local_voters.pluck(:id) if preloadable_poll.present? + + ids.uniq end - - ids.uniq end def searchable_text diff --git a/app/models/poll.rb b/app/models/poll.rb index 74a77978b9..efa625eb5b 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -28,6 +28,7 @@ class Poll < ApplicationRecord has_many :votes, class_name: 'PollVote', inverse_of: :poll, dependent: :delete_all has_many :voters, -> { group('accounts.id') }, through: :votes, class_name: 'Account', source: :account + has_many :local_voters, -> { group('accounts.id').merge(Account.local) }, through: :votes, class_name: 'Account', source: :account has_many :notifications, as: :activity, dependent: :destroy diff --git a/app/models/status.rb b/app/models/status.rb index 760b8ec33e..1c41ef1d52 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -72,6 +72,12 @@ class Status < ApplicationRecord has_many :active_mentions, -> { active }, class_name: 'Mention', inverse_of: :status has_many :media_attachments, dependent: :nullify + # Those associations are used for the private search index + has_many :local_mentioned, -> { merge(Account.local) }, through: :active_mentions, source: :account + has_many :local_favorited, -> { merge(Account.local) }, through: :favourites, source: :account + has_many :local_reblogged, -> { merge(Account.local) }, through: :reblogs, source: :account + has_many :local_bookmarked, -> { merge(Account.local) }, through: :bookmarks, source: :account + has_and_belongs_to_many :tags has_and_belongs_to_many :preview_cards From 7c4a4b905bcbd196af75837da4641ed209efc6cd Mon Sep 17 00:00:00 2001 From: KMY Date: Wed, 30 Aug 2023 07:53:51 +0900 Subject: [PATCH 29/65] Add domain search prefix --- .../mastodon/features/compose/components/search.jsx | 1 + app/lib/search_query_transformer.rb | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/app/javascript/mastodon/features/compose/components/search.jsx b/app/javascript/mastodon/features/compose/components/search.jsx index 1c629bcbb4..5ae6ee1090 100644 --- a/app/javascript/mastodon/features/compose/components/search.jsx +++ b/app/javascript/mastodon/features/compose/components/search.jsx @@ -50,6 +50,7 @@ class Search extends PureComponent { { label: <>is: , action: e => { e.preventDefault(); this._insertText('is:') } }, { label: <>language: , action: e => { e.preventDefault(); this._insertText('language:') } }, { label: <>from: , action: e => { e.preventDefault(); this._insertText('from:') } }, + { label: <>domain: , action: e => { e.preventDefault(); this._insertText('domain:') } }, { label: <>before: , action: e => { e.preventDefault(); this._insertText('before:') } }, { label: <>during: , action: e => { e.preventDefault(); this._insertText('during:') } }, { label: <>after: , action: e => { e.preventDefault(); this._insertText('after:') } }, diff --git a/app/lib/search_query_transformer.rb b/app/lib/search_query_transformer.rb index 165359cd79..23c23cdedf 100644 --- a/app/lib/search_query_transformer.rb +++ b/app/lib/search_query_transformer.rb @@ -103,6 +103,10 @@ class SearchQueryTransformer < Parslet::Transform @filter = :account_id @type = :term @term = account_id_from_term(term) + when 'domain' + @filter = :domain + @type = :term + @term = domain_from_term(term) when 'before' @filter = :created_at @type = :range @@ -137,6 +141,12 @@ class SearchQueryTransformer < Parslet::Transform # an ID that does not exist account&.id || -1 end + + def domain_from_term(term) + return '' if %w(local me).include?(term) + + term + end end rule(clause: subtree(:clause)) do From f64656e50ed074b421ba0eeb2815b0eab64ca414 Mon Sep 17 00:00:00 2001 From: KMY Date: Wed, 30 Aug 2023 08:57:49 +0900 Subject: [PATCH 30/65] Add antenna deployment badge and remove details --- app/javascript/mastodon/features/antennas/index.jsx | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/app/javascript/mastodon/features/antennas/index.jsx b/app/javascript/mastodon/features/antennas/index.jsx index bac6105a50..a575527fce 100644 --- a/app/javascript/mastodon/features/antennas/index.jsx +++ b/app/javascript/mastodon/features/antennas/index.jsx @@ -12,7 +12,6 @@ import { createSelector } from 'reselect'; import { fetchAntennas } from 'mastodon/actions/antennas'; import Column from 'mastodon/components/column'; import ColumnHeader from 'mastodon/components/column_header'; -import { Icon } from 'mastodon/components/icon'; import { LoadingIndicator } from 'mastodon/components/loading_indicator'; import ScrollableList from 'mastodon/components/scrollable_list'; import ColumnLink from 'mastodon/features/ui/components/column_link'; @@ -23,6 +22,8 @@ import NewAntennaForm from './components/new_antenna_form'; const messages = defineMessages({ heading: { id: 'column.antennas', defaultMessage: 'Antennas' }, subheading: { id: 'antennas.subheading', defaultMessage: 'Your antennas' }, + insert_list: { id: 'antennas.insert_list', defaultMessage: 'List' }, + insert_home: { id: 'antennas.insert_home', defaultMessage: 'Home' }, }); const getOrderedAntennas = createSelector([state => state.get('antennas')], antennas => { @@ -77,14 +78,8 @@ class Antennas extends ImmutablePureComponent { bindToDocument={!multiColumn} > {antennas.map(antenna => ( - - - {antenna.get('accounts_count')} - {antenna.get('domains_count')} - {antenna.get('tags_count')} - {antenna.get('keywords_count')} - - + ))} From 40911078b5749f89ec114c5da8072fa350ae8330 Mon Sep 17 00:00:00 2001 From: KMY Date: Wed, 30 Aug 2023 08:58:44 +0900 Subject: [PATCH 31/65] Fix bookmark category icon --- .../bookmark_category_adder/components/bookmark_category.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/mastodon/features/bookmark_category_adder/components/bookmark_category.jsx b/app/javascript/mastodon/features/bookmark_category_adder/components/bookmark_category.jsx index f9fdb6b8e6..b28c58f303 100644 --- a/app/javascript/mastodon/features/bookmark_category_adder/components/bookmark_category.jsx +++ b/app/javascript/mastodon/features/bookmark_category_adder/components/bookmark_category.jsx @@ -55,7 +55,7 @@ class BookmarkCategory extends ImmutablePureComponent {
- + {bookmarkCategory.get('title')}
From e8ee0e801506e497781ed338037fca177cfdfbe4 Mon Sep 17 00:00:00 2001 From: KMY Date: Wed, 30 Aug 2023 09:04:12 +0900 Subject: [PATCH 32/65] Add bookmark category to detail status menu --- .../mastodon/features/status/components/action_bar.jsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/javascript/mastodon/features/status/components/action_bar.jsx b/app/javascript/mastodon/features/status/components/action_bar.jsx index c5980461e9..3047d1e1c8 100644 --- a/app/javascript/mastodon/features/status/components/action_bar.jsx +++ b/app/javascript/mastodon/features/status/components/action_bar.jsx @@ -23,11 +23,13 @@ const messages = defineMessages({ mention: { id: 'status.mention', defaultMessage: 'Mention @{name}' }, reply: { id: 'status.reply', defaultMessage: 'Reply' }, reblog: { id: 'status.reblog', defaultMessage: 'Boost' }, + cancel_reblog: { id: 'status.cancel_reblog_private', defaultMessage: 'Unboost' }, reblog_private: { id: 'status.reblog_private', defaultMessage: 'Boost with original visibility' }, cancel_reblog_private: { id: 'status.cancel_reblog_private', defaultMessage: 'Unboost' }, cannot_reblog: { id: 'status.cannot_reblog', defaultMessage: 'This post cannot be boosted' }, favourite: { id: 'status.favourite', defaultMessage: 'Favorite' }, bookmark: { id: 'status.bookmark', defaultMessage: 'Bookmark' }, + bookmark_category: { id: 'status.bookmark_category', defaultMessage: 'Bookmark category' }, more: { id: 'status.more', defaultMessage: 'More' }, mute: { id: 'status.mute', defaultMessage: 'Mute @{name}' }, muteConversation: { id: 'status.mute_conversation', defaultMessage: 'Mute conversation' }, @@ -114,6 +116,10 @@ class ActionBar extends PureComponent { } }; + handleBookmarkCategoryAdderClick = () => { + this.props.onBookmarkCategoryAdder(this.props.status); + }; + handleDeleteClick = () => { this.props.onDelete(this.props.status, this.context.router.history); }; @@ -237,11 +243,12 @@ class ActionBar extends PureComponent { if (signedIn) { menu.push(null); - menu.push({ text: intl.formatMessage(messages.reblog), action: this.handleReblogForceModalClick }); + menu.push({ text: intl.formatMessage(status.get('reblogged') ? messages.cancel_reblog : messages.reblog), action: this.handleReblogForceModalClick }); if (publicStatus) { menu.push({ text: intl.formatMessage(messages.reference), action: this.handleReference }); } + menu.push({ text: intl.formatMessage(messages.bookmark_category), action: this.handleBookmarkCategoryAdderClick }); if (writtenByMe) { if (pinnableStatus) { From ff06b04e91cecda4b51a81043eb39fd4b5f92bfa Mon Sep 17 00:00:00 2001 From: KMY Date: Wed, 30 Aug 2023 10:59:35 +0900 Subject: [PATCH 33/65] Fix misstake --- app/chewy/statuses_index.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/chewy/statuses_index.rb b/app/chewy/statuses_index.rb index 4c8ec5f440..ca119e3779 100644 --- a/app/chewy/statuses_index.rb +++ b/app/chewy/statuses_index.rb @@ -126,7 +126,7 @@ class StatusesIndex < Chewy::Index if status.searchability == 'direct' status.searchable_by.empty? else - status.searchability == 'limited' ? status.domain.blank? : false + status.searchability == 'limited' ? status.domain.present? : false end } From 168688ef1c538c295fe08516825c845f08e2b7d5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 30 Aug 2023 09:34:07 +0200 Subject: [PATCH 34/65] Update dependency webmock to v3.19.1 (#26722) 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 f26856bf94..7e5dac0318 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -109,7 +109,7 @@ GEM i18n (>= 1.6, < 2) minitest (>= 5.1) tzinfo (~> 2.0) - addressable (2.8.4) + addressable (2.8.5) public_suffix (>= 2.0.2, < 6.0) aes_key_wrap (1.1.0) airbrussh (1.4.1) @@ -795,7 +795,7 @@ GEM webfinger (1.2.0) activesupport httpclient (>= 2.4) - webmock (3.18.1) + webmock (3.19.1) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) From 24deaf2e4a6bd7a3d5fb50fa8ed5102286fa8988 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 30 Aug 2023 09:44:14 +0200 Subject: [PATCH 35/65] Update dependency postcss to v8.4.29 (#26720) 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 0f34ad3551..0a7c840dd5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9625,9 +9625,9 @@ postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== postcss@^8.2.15, postcss@^8.4.24, postcss@^8.4.25: - version "8.4.28" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.28.tgz#c6cc681ed00109072816e1557f889ef51cf950a5" - integrity sha512-Z7V5j0cq8oEKyejIKfpD8b4eBy9cwW2JWPk0+fB1HOAMsfHbnAXLLS+PfVWlzMSLQaWttKDt607I0XHmpE67Vw== + version "8.4.29" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.29.tgz#33bc121cf3b3688d4ddef50be869b2a54185a1dd" + integrity sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw== dependencies: nanoid "^3.3.6" picocolors "^1.0.0" From 0e1bff178ecaa4434191335d81d2a8809f31e550 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 30 Aug 2023 09:45:13 +0200 Subject: [PATCH 36/65] Update dependency chewy to v7.3.4 (#26717) 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 7e5dac0318..f1a61c5e09 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -203,7 +203,7 @@ GEM activesupport cbor (0.5.9.6) charlock_holmes (0.7.7) - chewy (7.3.3) + chewy (7.3.4) activesupport (>= 5.2) elasticsearch (>= 7.12.0, < 7.14.0) elasticsearch-dsl From 76013b10b47759360164e22663f6b624353869d3 Mon Sep 17 00:00:00 2001 From: KMY Date: Wed, 30 Aug 2023 17:42:26 +0900 Subject: [PATCH 37/65] Custom_filter working on status_reference --- app/lib/inline_renderer.rb | 3 +++ app/models/custom_filter.rb | 5 ++++- app/serializers/rest/status_internal_serializer.rb | 9 +++++++++ app/services/fan_out_on_write_service.rb | 2 +- streaming/index.js | 7 ++++++- 5 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 app/serializers/rest/status_internal_serializer.rb diff --git a/app/lib/inline_renderer.rb b/app/lib/inline_renderer.rb index 7071bb6804..ebdd1d189f 100644 --- a/app/lib/inline_renderer.rb +++ b/app/lib/inline_renderer.rb @@ -12,6 +12,9 @@ class InlineRenderer when :status serializer = REST::StatusSerializer preload_associations_for_status + when :status_internal + serializer = REST::StatusInternalSerializer + preload_associations_for_status when :notification serializer = REST::NotificationSerializer when :emoji_reaction diff --git a/app/models/custom_filter.rb b/app/models/custom_filter.rb index 5a19942e88..f443d08ca6 100644 --- a/app/models/custom_filter.rb +++ b/app/models/custom_filter.rb @@ -101,7 +101,10 @@ class CustomFilter < ApplicationRecord next if filter.exclude_follows && following next if filter.exclude_localusers && status.account.local? - match = rules[:keywords].match(status.proper.searchable_text) if rules[:keywords].present? + if rules[:keywords].present? + match = rules[:keywords].match(status.proper.searchable_text) + match = rules[:keywords].match(status.proper.references.pluck(:text).join("\n\n")) if match.nil? && status.proper.references.exists? + end keyword_matches = [match.to_s] unless match.nil? status_matches = [status.id, status.reblog_of_id].compact & rules[:status_ids] if rules[:status_ids].present? diff --git a/app/serializers/rest/status_internal_serializer.rb b/app/serializers/rest/status_internal_serializer.rb new file mode 100644 index 0000000000..7a2cbf5746 --- /dev/null +++ b/app/serializers/rest/status_internal_serializer.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class REST::StatusInternalSerializer < REST::StatusSerializer + attributes :reference_texts + + def reference_texts + object.references.pluck(:text) + end +end diff --git a/app/services/fan_out_on_write_service.rb b/app/services/fan_out_on_write_service.rb index 94f9612725..865589dacd 100644 --- a/app/services/fan_out_on_write_service.rb +++ b/app/services/fan_out_on_write_service.rb @@ -195,7 +195,7 @@ class FanOutOnWriteService < BaseService end def rendered_status - @rendered_status ||= InlineRenderer.render(@status, nil, :status) + @rendered_status ||= InlineRenderer.render(@status, nil, :status_internal) end def update? diff --git a/streaming/index.js b/streaming/index.js index 7bd3ddb0a7..8b16bfe533 100644 --- a/streaming/index.js +++ b/streaming/index.js @@ -763,6 +763,11 @@ const startServer = async () => { const listener = message => { const { event, payload } = message; + // reference_texts property is not working if ProcessReferencesWorker is + // used on PostStatusService and so on. (Asynchronous processing) + const reference_texts = payload.reference_texts || []; + delete payload.reference_texts; + // Streaming only needs to apply filtering to some channels and only to // some events. This is because majority of the filtering happens on the // Ruby on Rails side when producing the event for streaming. @@ -908,7 +913,7 @@ const startServer = async () => { if (req.cachedFilters) { const status = payload; // TODO: Calculate searchableContent in Ruby on Rails: - const searchableContent = ([status.spoiler_text || '', status.content].concat((status.poll && status.poll.options) ? status.poll.options.map(option => option.title) : [])).concat(status.media_attachments.map(att => att.description)).join('\n\n').replace(//g, '\n').replace(/<\/p>

/g, '\n\n'); + const searchableContent = ([status.spoiler_text || '', status.content, ...(reference_texts || [])].concat((status.poll && status.poll.options) ? status.poll.options.map(option => option.title) : [])).concat(status.media_attachments.map(att => att.description)).join('\n\n').replace(//g, '\n').replace(/<\/p>

/g, '\n\n'); const searchableTextContent = JSDOM.fragment(searchableContent).textContent; const now = new Date(); From bba76e726714e49dae8ea6dd4b2439ae1d7699a8 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 30 Aug 2023 16:07:26 +0200 Subject: [PATCH 38/65] Change `language:` to attempt to match to a known value in search (#26663) --- app/lib/search_query_transformer.rb | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/app/lib/search_query_transformer.rb b/app/lib/search_query_transformer.rb index f1fc687e47..86e3f50005 100644 --- a/app/lib/search_query_transformer.rb +++ b/app/lib/search_query_transformer.rb @@ -98,7 +98,7 @@ class SearchQueryTransformer < Parslet::Transform when 'language' @filter = :language @type = :term - @term = term + @term = language_code_from_term(term) when 'from' @filter = :account_id @type = :term @@ -137,6 +137,22 @@ class SearchQueryTransformer < Parslet::Transform # an ID that does not exist account&.id || -1 end + + def language_code_from_term(term) + language_code = term + + return language_code if LanguagesHelper::SUPPORTED_LOCALES.key?(language_code.to_sym) + + language_code = term.downcase + + return language_code if LanguagesHelper::SUPPORTED_LOCALES.key?(language_code.to_sym) + + language_code = term.split(/[_-]/).first.downcase + + return language_code if LanguagesHelper::SUPPORTED_LOCALES.key?(language_code.to_sym) + + term + end end rule(clause: subtree(:clause)) do From 21ec596dabbe28a5cfc5b29362f46f47b48eb140 Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 30 Aug 2023 16:29:52 +0200 Subject: [PATCH 39/65] Fix sign up steps progress layout in right-to-left locales (#26728) --- app/javascript/styles/mastodon/forms.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/javascript/styles/mastodon/forms.scss b/app/javascript/styles/mastodon/forms.scss index beb45ab6e9..a7079c1457 100644 --- a/app/javascript/styles/mastodon/forms.scss +++ b/app/javascript/styles/mastodon/forms.scss @@ -1185,14 +1185,14 @@ code { } li:first-child .label { - left: auto; inset-inline-start: 0; + inset-inline-end: auto; text-align: start; transform: none; } li:last-child .label { - left: auto; + inset-inline-start: auto; inset-inline-end: 0; text-align: end; transform: none; From 5c38c3a9a1e6bb07f33f5fee598b51cb1fd695ba Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 30 Aug 2023 17:36:16 +0200 Subject: [PATCH 40/65] Change text extraction in `PlainTextFormatter` to be faster (#26727) --- app/lib/plain_text_formatter.rb | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/app/lib/plain_text_formatter.rb b/app/lib/plain_text_formatter.rb index 8eac730bec..d1ff6808b2 100644 --- a/app/lib/plain_text_formatter.rb +++ b/app/lib/plain_text_formatter.rb @@ -1,8 +1,6 @@ # frozen_string_literal: true class PlainTextFormatter - include ActionView::Helpers::TextHelper - NEWLINE_TAGS_RE = %r{(
|
|

)+} attr_reader :text, :local @@ -18,7 +16,10 @@ class PlainTextFormatter if local? text else - html_entities.decode(strip_tags(insert_newlines)).chomp + node = Nokogiri::HTML.fragment(insert_newlines) + # Elements that are entirely removed with our Sanitize config + node.xpath('.//iframe|.//math|.//noembed|.//noframes|.//noscript|.//plaintext|.//script|.//style|.//svg|.//xmp').remove + node.text.chomp end end @@ -27,8 +28,4 @@ class PlainTextFormatter def insert_newlines text.gsub(NEWLINE_TAGS_RE) { |match| "#{match}\n" } end - - def html_entities - HTMLEntities.new - end end From 15949e42c292344c63f828bed24d6af045a686e6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 31 Aug 2023 09:49:34 +0200 Subject: [PATCH 41/65] Update dependency glob to v10.3.4 (#26734) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/yarn.lock b/yarn.lock index 0a7c840dd5..ec5566be39 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6231,9 +6231,9 @@ glob-parent@^6.0.2: is-glob "^4.0.3" glob@^10.2.5, glob@^10.2.6: - version "10.3.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.3.tgz#8360a4ffdd6ed90df84aa8d52f21f452e86a123b" - integrity sha512-92vPiMb/iqpmEgsOoIDvTjc50wf9CCCvMzsi6W0JLPeUKE8TWP1a73PgqSrqy7iAZxaSD1YdzU7QZR5LF51MJw== + version "10.3.4" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.4.tgz#c85c9c7ab98669102b6defda76d35c5b1ef9766f" + integrity sha512-6LFElP3A+i/Q8XQKEvZjkEWEOTgAIALR9AO2rwT8bgPhDd1anmqDJDZ6lLddI4ehxxxR1S5RIqKe1uapMQfYaQ== dependencies: foreground-child "^3.1.0" jackspeak "^2.0.3" @@ -7336,9 +7336,9 @@ iterator.prototype@^1.1.0: reflect.getprototypeof "^1.0.3" jackspeak@^2.0.3: - version "2.2.1" - resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.2.1.tgz#655e8cf025d872c9c03d3eb63e8f0c024fef16a6" - integrity sha512-MXbxovZ/Pm42f6cDIDkl3xpwv1AGwObKwfmjs2nQePiy85tP3fatofl3FC1aBsOtP/6fq5SbtgHwWcMsLP+bDw== + version "2.3.1" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.3.1.tgz#ce2effa4c458e053640e61938865a5b5fae98456" + integrity sha512-4iSY3Bh1Htv+kLhiiZunUhQ+OYXIn0ze3ulq8JeWrFKmhPAJSySV2+kdtRh2pGcCeF0s6oR8Oc+pYZynJj4t8A== dependencies: "@isaacs/cliui" "^8.0.2" optionalDependencies: @@ -8192,9 +8192,9 @@ lru-cache@^6.0.0: yallist "^4.0.0" "lru-cache@^9.1.1 || ^10.0.0": - version "10.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.0.tgz#b9e2a6a72a129d81ab317202d93c7691df727e61" - integrity sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw== + version "10.0.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.1.tgz#0a3be479df549cca0e5d693ac402ff19537a6b7a" + integrity sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g== lz-string@^1.5.0: version "1.5.0" @@ -8526,9 +8526,9 @@ minipass@^5.0.0: integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== "minipass@^5.0.0 || ^6.0.2 || ^7.0.0": - version "7.0.2" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.2.tgz#58a82b7d81c7010da5bd4b2c0c85ac4b4ec5131e" - integrity sha512-eL79dXrE1q9dBbDCLg7xfn/vl7MS4F1gvJAgjJrQli/jbQWdUttuVawphqpffoIYfRdq78LHx6GP4bU/EQ2ATA== + version "7.0.3" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.3.tgz#05ea638da44e475037ed94d1c7efcc76a25e1974" + integrity sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg== minizlib@^2.1.1: version "2.1.2" @@ -11345,7 +11345,6 @@ stringz@^2.1.0: char-regex "^1.0.2" "strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: - name strip-ansi-cjs version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== From ef9a85a2d82908478cf7cd7fbc5ea6311200264e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 31 Aug 2023 09:52:23 +0200 Subject: [PATCH 42/65] Update dependency webpack-bundle-analyzer to v4.9.1 (#26733) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 74 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 53 insertions(+), 21 deletions(-) diff --git a/yarn.lock b/yarn.lock index ec5566be39..89b11e8e2b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2913,16 +2913,16 @@ acorn@^6.4.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== -acorn@^8.0.4, acorn@^8.8.2: - version "8.8.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" - integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== - -acorn@^8.1.0, acorn@^8.8.1, acorn@^8.9.0: +acorn@^8.0.4, acorn@^8.1.0, acorn@^8.8.1, acorn@^8.9.0: version "8.10.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== +acorn@^8.8.2: + version "8.8.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" + integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== + agent-base@6: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" @@ -8100,6 +8100,16 @@ lodash.debounce@^4.0.8: resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== +lodash.escape@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-4.0.1.tgz#c9044690c21e04294beaa517712fded1fa88de98" + integrity sha512-nXEOnb/jK9g0DYMr1/Xvq6l5xMD7GDG55+GSYIYmS0G4tBk/hURD4JR9WCavs04t33WmJx9kCyp9vJ+mr4BOUw== + +lodash.flatten@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" + integrity sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g== + lodash.get@^4.0: version "4.4.2" resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" @@ -8110,6 +8120,11 @@ lodash.has@^4.0: resolved "https://registry.yarnpkg.com/lodash.has/-/lodash.has-4.5.2.tgz#d19f4dc1095058cccbe2b0cdf4ee0fe4aa37c862" integrity sha512-rnYUdIo6xRCJnQmbVFEwcxF144erlD+M3YcJUVesflU9paQaE8p+fJDcIQrlMYbxoANFL+AB9hZrzSBBk5PL+g== +lodash.invokemap@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.invokemap/-/lodash.invokemap-4.6.0.tgz#1748cda5d8b0ef8369c4eb3ec54c21feba1f2d62" + integrity sha512-CfkycNtMqgUlfjfdh2BhKO/ZXrP8ePOX5lEU/g0R3ItJcnuxWDwokMGKx1hWcfOikmyOVx6X9IwWnDGlgKl61w== + lodash.isboolean@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" @@ -8135,6 +8150,11 @@ lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== +lodash.pullall@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.pullall/-/lodash.pullall-4.2.0.tgz#9d98b8518b7c965b0fae4099bd9fb7df8bbf38ba" + integrity sha512-VhqxBKH0ZxPpLhiu68YD1KnHmbhQJQctcipvmFnqIBDYzcIHzf3Zpu0tpeOKtR4x76p9yohc506eGdOjTmyIBg== + lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" @@ -8150,6 +8170,11 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== +lodash.uniqby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz#d99c07a669e9e6d24e1362dfe266c67616af1302" + integrity sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww== + lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" @@ -10905,14 +10930,14 @@ signal-exit@^4.0.1: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== -sirv@^1.0.7: - version "1.0.19" - resolved "https://registry.yarnpkg.com/sirv/-/sirv-1.0.19.tgz#1d73979b38c7fe91fcba49c85280daa9c2363b49" - integrity sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ== +sirv@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/sirv/-/sirv-2.0.3.tgz#ca5868b87205a74bef62a469ed0296abceccd446" + integrity sha512-O9jm9BsID1P+0HOi81VpXPoDxYP374pkOLzACAoyUQ/3OUVndNpsz6wMnY2z+yOxzbllCKZrM+9QrWsv4THnyA== dependencies: "@polka/url" "^1.0.0-next.20" mrmime "^1.0.0" - totalist "^1.0.0" + totalist "^3.0.0" sisteransi@^1.0.5: version "1.0.5" @@ -11831,10 +11856,10 @@ toidentifier@1.0.1: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== -totalist@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/totalist/-/totalist-1.1.0.tgz#a4d65a3e546517701e3e5c37a47a70ac97fe56df" - integrity sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g== +totalist@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/totalist/-/totalist-3.0.1.tgz#ba3a3d600c915b1a97872348f79c127475f6acf8" + integrity sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ== tough-cookie@^4.1.2: version "4.1.3" @@ -12387,19 +12412,26 @@ webpack-assets-manifest@^4.0.6: webpack-sources "^1.0" webpack-bundle-analyzer@^4.8.0: - version "4.9.0" - resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.9.0.tgz#fc093c4ab174fd3dcbd1c30b763f56d10141209d" - integrity sha512-+bXGmO1LyiNx0i9enBu3H8mv42sj/BJWhZNFwjz92tVnBa9J3JMGo2an2IXlEleoDOPn/Hofl5hr/xCpObUDtw== + version "4.9.1" + resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.9.1.tgz#d00bbf3f17500c10985084f22f1a2bf45cb2f09d" + integrity sha512-jnd6EoYrf9yMxCyYDPj8eutJvtjQNp8PHmni/e/ulydHBWhT5J3menXt3HEkScsu9YqMAcG4CfFjs3rj5pVU1w== dependencies: "@discoveryjs/json-ext" "0.5.7" acorn "^8.0.4" acorn-walk "^8.0.0" - chalk "^4.1.0" commander "^7.2.0" + escape-string-regexp "^4.0.0" gzip-size "^6.0.0" - lodash "^4.17.20" + is-plain-object "^5.0.0" + lodash.debounce "^4.0.8" + lodash.escape "^4.0.1" + lodash.flatten "^4.4.0" + lodash.invokemap "^4.6.0" + lodash.pullall "^4.2.0" + lodash.uniqby "^4.7.0" opener "^1.5.2" - sirv "^1.0.7" + picocolors "^1.0.0" + sirv "^2.0.3" ws "^7.3.1" webpack-cli@^3.3.12: From 430eac3eb1021d30f1ca73ec21444a3a5cb0bab7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 31 Aug 2023 10:23:24 +0200 Subject: [PATCH 43/65] Update dependency @babel/preset-env to v7.22.14 (#26732) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 224 +++++++++++++++++++++++++++--------------------------- 1 file changed, 111 insertions(+), 113 deletions(-) diff --git a/yarn.lock b/yarn.lock index 89b11e8e2b..880ded9773 100644 --- a/yarn.lock +++ b/yarn.lock @@ -29,7 +29,7 @@ jsonpointer "^5.0.0" leven "^3.1.0" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.22.10", "@babel/code-frame@^7.22.5": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.22.10": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.10.tgz#1c20e612b768fefa75f6e90d6ecb86329247f0a3" integrity sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA== @@ -44,7 +44,15 @@ dependencies: "@babel/highlight" "^7.22.5" -"@babel/compat-data@^7.22.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.22.9": +"@babel/code-frame@^7.22.5": + version "7.22.13" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e" + integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w== + dependencies: + "@babel/highlight" "^7.22.13" + chalk "^2.4.2" + +"@babel/compat-data@^7.22.6", "@babel/compat-data@^7.22.9": version "7.22.9" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.9.tgz#71cdb00a1ce3a329ce4cbec3a44f9fef35669730" integrity sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ== @@ -113,7 +121,7 @@ lru-cache "^5.1.1" semver "^6.3.1" -"@babel/helper-create-class-features-plugin@^7.22.11": +"@babel/helper-create-class-features-plugin@^7.22.11", "@babel/helper-create-class-features-plugin@^7.22.5": version "7.22.11" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.11.tgz#4078686740459eeb4af3494a273ac09148dfb213" integrity sha512-y1grdYL4WzmUDBRGK0pDbIoFd7UZKoDurDzWEoNMYoj1EL+foGRQNyPWDcC+YyegN5y1DUsFFmzjGijB3nSVAQ== @@ -128,21 +136,6 @@ "@babel/helper-split-export-declaration" "^7.22.6" semver "^6.3.1" -"@babel/helper-create-class-features-plugin@^7.22.5": - version "7.22.10" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.10.tgz#dd2612d59eac45588021ac3d6fa976d08f4e95a3" - integrity sha512-5IBb77txKYQPpOEdUdIhBx8VrZyDCQ+H82H0+5dX1TmuscP5vJKEE3cKurjtIw/vFwzbVH48VweE78kVDBrqjA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-environment-visitor" "^7.22.5" - "@babel/helper-function-name" "^7.22.5" - "@babel/helper-member-expression-to-functions" "^7.22.5" - "@babel/helper-optimise-call-expression" "^7.22.5" - "@babel/helper-replace-supers" "^7.22.9" - "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.6" - semver "^6.3.1" - "@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.22.5": version "7.22.9" resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.9.tgz#9d8e61a8d9366fe66198f57c40565663de0825f6" @@ -292,7 +285,16 @@ "@babel/traverse" "^7.22.11" "@babel/types" "^7.22.11" -"@babel/highlight@^7.22.10", "@babel/highlight@^7.22.5": +"@babel/highlight@^7.22.10", "@babel/highlight@^7.22.13": + version "7.22.13" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.13.tgz#9cda839e5d3be9ca9e8c26b6dd69e7548f0cbf16" + integrity sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ== + dependencies: + "@babel/helper-validator-identifier" "^7.22.5" + chalk "^2.4.2" + js-tokens "^4.0.0" + +"@babel/highlight@^7.22.5": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.10.tgz#02a3f6d8c1cb4521b2fd0ab0da8f4739936137d7" integrity sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ== @@ -306,11 +308,16 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.10.tgz#e37634f9a12a1716136c44624ef54283cabd3f55" integrity sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ== -"@babel/parser@^7.22.11", "@babel/parser@^7.22.5": +"@babel/parser@^7.22.11": version "7.22.11" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.11.tgz#becf8ee33aad2a35ed5607f521fe6e72a615f905" integrity sha512-R5zb8eJIBPJriQtbH/htEQy4k7E2dHWlD2Y2VT07JCzwYZHBxV5ZYtM0UhXSNMT74LyxuM+b1jdL7pSesXbC/g== +"@babel/parser@^7.22.5": + version "7.22.14" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.14.tgz#c7de58e8de106e88efca42ce17f0033209dfd245" + integrity sha512-1KucTHgOvaw/LzCVrEOAyXkr9rQlp0A1HiHRYnSUE9dmb8PvPW7o5sscg+5169r54n3vGlbx6GevTE/Iw/P3AQ== + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.5.tgz#87245a21cd69a73b0b81bcda98d443d6df08f05e" @@ -487,10 +494,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-async-generator-functions@^7.22.10": - version "7.22.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.10.tgz#45946cd17f915b10e65c29b8ed18a0a50fc648c8" - integrity sha512-eueE8lvKVzq5wIObKK/7dvoeKJ+xc6TvRn6aysIjS6pSCeLy7S/eVi7pEQknZqyqvzaNKdDtem8nUNTBgDVR2g== +"@babel/plugin-transform-async-generator-functions@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.11.tgz#dbe3b1ff5a52e2e5edc4b19a60d325a675ed2649" + integrity sha512-0pAlmeRJn6wU84zzZsEOx1JV1Jf8fqO9ok7wofIJwUnplYo247dcd24P+cMJht7ts9xkzdtB0EPHmOb7F+KzXw== dependencies: "@babel/helper-environment-visitor" "^7.22.5" "@babel/helper-plugin-utils" "^7.22.5" @@ -528,12 +535,12 @@ "@babel/helper-create-class-features-plugin" "^7.22.5" "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-class-static-block@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.5.tgz#3e40c46f048403472d6f4183116d5e46b1bff5ba" - integrity sha512-SPToJ5eYZLxlnp1UzdARpOGeC2GbHvr9d/UV0EukuVx8atktg194oe+C5BqQ8jRTkgLRVOPYeXRSBg1IlMoVRA== +"@babel/plugin-transform-class-static-block@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.11.tgz#dc8cc6e498f55692ac6b4b89e56d87cec766c974" + integrity sha512-GMM8gGmqI7guS/llMFk1bJDkKfn3v3C4KHK9Yg1ey5qcHcOlKb0QvcMrgzvxo+T03/4szNh5lghY+fEC98Kq9g== dependencies: - "@babel/helper-create-class-features-plugin" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.22.11" "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-class-static-block" "^7.14.5" @@ -582,10 +589,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-dynamic-import@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.5.tgz#d6908a8916a810468c4edff73b5b75bda6ad393e" - integrity sha512-0MC3ppTB1AMxd8fXjSrbPa7LT9hrImt+/fcj+Pg5YMD7UQyWp/02+JWpdnCymmsXwIx5Z+sYn1bwCn4ZJNvhqQ== +"@babel/plugin-transform-dynamic-import@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.11.tgz#2c7722d2a5c01839eaf31518c6ff96d408e447aa" + integrity sha512-g/21plo58sfteWjaO0ZNVb+uEOkJNjAaHhbejrnBmu011l/eNDScmkbjCC3l4FKb10ViaGU4aOkFznSu2zRHgA== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-dynamic-import" "^7.8.3" @@ -598,10 +605,10 @@ "@babel/helper-builder-binary-assignment-operator-visitor" "^7.22.5" "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-export-namespace-from@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.5.tgz#57c41cb1d0613d22f548fddd8b288eedb9973a5b" - integrity sha512-X4hhm7FRnPgd4nDA4b/5V280xCx6oL7Oob5+9qVS5C13Zq4bh1qq7LU0GgRU6b5dBWBvhGaXYVB4AcN6+ol6vg== +"@babel/plugin-transform-export-namespace-from@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.11.tgz#b3c84c8f19880b6c7440108f8929caf6056db26c" + integrity sha512-xa7aad7q7OiT8oNZ1mU7NrISjlSkVdMbNxn9IuLZyL9AJEhs1Apba3I+u5riX1dIkdptP5EKDG5XDPByWxtehw== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" @@ -622,10 +629,10 @@ "@babel/helper-function-name" "^7.22.5" "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-json-strings@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.5.tgz#14b64352fdf7e1f737eed68de1a1468bd2a77ec0" - integrity sha512-DuCRB7fu8MyTLbEQd1ew3R85nx/88yMoqo2uPSjevMj3yoN7CDM8jkgrY0wmVxfJZyJ/B9fE1iq7EQppWQmR5A== +"@babel/plugin-transform-json-strings@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.11.tgz#689a34e1eed1928a40954e37f74509f48af67835" + integrity sha512-CxT5tCqpA9/jXFlme9xIBCc5RPtdDq3JpkkhgHQqtDdiTnTI0jtZ0QzXhr5DILeYifDPp2wvY2ad+7+hLMW5Pw== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-json-strings" "^7.8.3" @@ -637,10 +644,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-logical-assignment-operators@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.5.tgz#66ae5f068fd5a9a5dc570df16f56c2a8462a9d6c" - integrity sha512-MQQOUW1KL8X0cDWfbwYP+TbVbZm16QmQXJQ+vndPtH/BoO0lOKpVoEDMI7+PskYxH+IiE0tS8xZye0qr1lGzSA== +"@babel/plugin-transform-logical-assignment-operators@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.11.tgz#24c522a61688bde045b7d9bc3c2597a4d948fc9c" + integrity sha512-qQwRTP4+6xFCDV5k7gZBF3C31K34ut0tbEcTKxlX/0KXxm9GLcO14p570aWxFvVzx6QAfPgq7gaeIHXJC8LswQ== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" @@ -669,22 +676,13 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-simple-access" "^7.22.5" -"@babel/plugin-transform-modules-commonjs@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.5.tgz#7d9875908d19b8c0536085af7b053fd5bd651bfa" - integrity sha512-B4pzOXj+ONRmuaQTg05b3y/4DuFz3WcCNAXPLb2Q0GT0TrGKGxNKV4jwsXts+StaM0LQczZbOpj8o1DLPDJIiA== - dependencies: - "@babel/helper-module-transforms" "^7.22.5" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-simple-access" "^7.22.5" - -"@babel/plugin-transform-modules-systemjs@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.5.tgz#18c31410b5e579a0092638f95c896c2a98a5d496" - integrity sha512-emtEpoaTMsOs6Tzz+nbmcePl6AKVtS1yC4YNAeMun9U8YCsgadPNxnOPQ8GhHFB2qdx+LZu9LgoC0Lthuu05DQ== +"@babel/plugin-transform-modules-systemjs@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.11.tgz#3386be5875d316493b517207e8f1931d93154bb1" + integrity sha512-rIqHmHoMEOhI3VkVf5jQ15l539KrwhzqcBO6wdCNWPWc/JWt9ILNYNUssbRpeq0qWns8svuw8LnMNCvWBIJ8wA== dependencies: "@babel/helper-hoist-variables" "^7.22.5" - "@babel/helper-module-transforms" "^7.22.5" + "@babel/helper-module-transforms" "^7.22.9" "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-validator-identifier" "^7.22.5" @@ -711,7 +709,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-nullish-coalescing-operator@^7.22.3", "@babel/plugin-transform-nullish-coalescing-operator@^7.22.5": +"@babel/plugin-transform-nullish-coalescing-operator@^7.22.11", "@babel/plugin-transform-nullish-coalescing-operator@^7.22.3": version "7.22.11" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.11.tgz#debef6c8ba795f5ac67cd861a81b744c5d38d9fc" integrity sha512-YZWOw4HxXrotb5xsjMJUDlLgcDXSfO9eCmdl1bgW4+/lAGdkjaEvOnQ4p5WKKdUgSzO39dgPl0pTnfxm0OAXcg== @@ -719,21 +717,21 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" -"@babel/plugin-transform-numeric-separator@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.5.tgz#57226a2ed9e512b9b446517ab6fa2d17abb83f58" - integrity sha512-NbslED1/6M+sXiwwtcAB/nieypGw02Ejf4KtDeMkCEpP6gWFMX1wI9WKYua+4oBneCCEmulOkRpwywypVZzs/g== +"@babel/plugin-transform-numeric-separator@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.11.tgz#498d77dc45a6c6db74bb829c02a01c1d719cbfbd" + integrity sha512-3dzU4QGPsILdJbASKhF/V2TVP+gJya1PsueQCxIPCEcerqF21oEcrob4mzjsp2Py/1nLfF5m+xYNMDpmA8vffg== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-transform-object-rest-spread@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.5.tgz#9686dc3447df4753b0b2a2fae7e8bc33cdc1f2e1" - integrity sha512-Kk3lyDmEslH9DnvCDA1s1kkd3YWQITiBOHngOtDL9Pt6BZjzqb6hiOlb8VfjiiQJ2unmegBqZu0rx5RxJb5vmQ== +"@babel/plugin-transform-object-rest-spread@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.11.tgz#dbbb06ce783cd994a8f430d8cefa553e9b42ca62" + integrity sha512-nX8cPFa6+UmbepISvlf5jhQyaC7ASs/7UxHmMkuJ/k5xSHvDPPaibMo+v3TXwU/Pjqhep/nFNpd3zn4YR59pnw== dependencies: - "@babel/compat-data" "^7.22.5" - "@babel/helper-compilation-targets" "^7.22.5" + "@babel/compat-data" "^7.22.9" + "@babel/helper-compilation-targets" "^7.22.10" "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-object-rest-spread" "^7.8.3" "@babel/plugin-transform-parameters" "^7.22.5" @@ -746,18 +744,18 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-replace-supers" "^7.22.5" -"@babel/plugin-transform-optional-catch-binding@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.5.tgz#842080be3076703be0eaf32ead6ac8174edee333" - integrity sha512-pH8orJahy+hzZje5b8e2QIlBWQvGpelS76C63Z+jhZKsmzfNaPQ+LaW6dcJ9bxTpo1mtXbgHwy765Ro3jftmUg== +"@babel/plugin-transform-optional-catch-binding@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.11.tgz#461cc4f578a127bb055527b3e77404cad38c08e0" + integrity sha512-rli0WxesXUeCJnMYhzAglEjLWVDF6ahb45HuprcmQuLidBJFWjNnOzssk2kuc6e33FlLaiZhG/kUIzUMWdBKaQ== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" -"@babel/plugin-transform-optional-chaining@^7.22.10", "@babel/plugin-transform-optional-chaining@^7.22.5": - version "7.22.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.10.tgz#076d28a7e074392e840d4ae587d83445bac0372a" - integrity sha512-MMkQqZAZ+MGj+jGTG3OTuhKeBpNcO+0oCEbrGNEaOmiEn+1MzRyQlYsruGiU8RTK3zV6XwrVJTmwiDOyYK6J9g== +"@babel/plugin-transform-optional-chaining@^7.22.12", "@babel/plugin-transform-optional-chaining@^7.22.5": + version "7.22.12" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.12.tgz#d7ebf6a88cd2f4d307b0e000ab630acd8124b333" + integrity sha512-7XXCVqZtyFWqjDsYDY4T45w4mlx1rf7aOgkc/Ww76xkgBiOlmjPkx36PBLHa1k1rwWvVgYMPsbuVnIamx2ZQJw== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" @@ -778,13 +776,13 @@ "@babel/helper-create-class-features-plugin" "^7.22.5" "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-private-property-in-object@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.5.tgz#07a77f28cbb251546a43d175a1dda4cf3ef83e32" - integrity sha512-/9xnaTTJcVoBtSSmrVyhtSvO3kbqS2ODoh2juEU72c3aYonNF0OMGiaz2gjukyKM2wBBYJP38S4JiE0Wfb5VMQ== +"@babel/plugin-transform-private-property-in-object@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.11.tgz#ad45c4fc440e9cb84c718ed0906d96cf40f9a4e1" + integrity sha512-sSCbqZDBKHetvjSwpyWzhuHkmW5RummxJBVbYLkGkaiTOWGxml7SXt0iWa03bzxFIx7wOj3g/ILRd0RcJKBeSQ== dependencies: "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-create-class-features-plugin" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.22.11" "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-private-property-in-object" "^7.14.5" @@ -948,9 +946,9 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/preset-env@^7.11.0", "@babel/preset-env@^7.12.1", "@babel/preset-env@^7.22.4": - version "7.22.10" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.22.10.tgz#3263b9fe2c8823d191d28e61eac60a79f9ce8a0f" - integrity sha512-riHpLb1drNkpLlocmSyEg4oYJIQFeXAK/d7rI6mbD0XsvoTOOweXDmQPG/ErxsEhWk3rl3Q/3F6RFQlVFS8m0A== + version "7.22.14" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.22.14.tgz#1cbb468d899f64fa71c53446f13b7ff8c0005cc1" + integrity sha512-daodMIoVo+ol/g+//c/AH+szBkFj4STQUikvBijRGL72Ph+w+AMTSh55DUETe8KJlPlDT1k/mp7NBfOuiWmoig== dependencies: "@babel/compat-data" "^7.22.9" "@babel/helper-compilation-targets" "^7.22.10" @@ -978,41 +976,41 @@ "@babel/plugin-syntax-top-level-await" "^7.14.5" "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" "@babel/plugin-transform-arrow-functions" "^7.22.5" - "@babel/plugin-transform-async-generator-functions" "^7.22.10" + "@babel/plugin-transform-async-generator-functions" "^7.22.11" "@babel/plugin-transform-async-to-generator" "^7.22.5" "@babel/plugin-transform-block-scoped-functions" "^7.22.5" "@babel/plugin-transform-block-scoping" "^7.22.10" "@babel/plugin-transform-class-properties" "^7.22.5" - "@babel/plugin-transform-class-static-block" "^7.22.5" + "@babel/plugin-transform-class-static-block" "^7.22.11" "@babel/plugin-transform-classes" "^7.22.6" "@babel/plugin-transform-computed-properties" "^7.22.5" "@babel/plugin-transform-destructuring" "^7.22.10" "@babel/plugin-transform-dotall-regex" "^7.22.5" "@babel/plugin-transform-duplicate-keys" "^7.22.5" - "@babel/plugin-transform-dynamic-import" "^7.22.5" + "@babel/plugin-transform-dynamic-import" "^7.22.11" "@babel/plugin-transform-exponentiation-operator" "^7.22.5" - "@babel/plugin-transform-export-namespace-from" "^7.22.5" + "@babel/plugin-transform-export-namespace-from" "^7.22.11" "@babel/plugin-transform-for-of" "^7.22.5" "@babel/plugin-transform-function-name" "^7.22.5" - "@babel/plugin-transform-json-strings" "^7.22.5" + "@babel/plugin-transform-json-strings" "^7.22.11" "@babel/plugin-transform-literals" "^7.22.5" - "@babel/plugin-transform-logical-assignment-operators" "^7.22.5" + "@babel/plugin-transform-logical-assignment-operators" "^7.22.11" "@babel/plugin-transform-member-expression-literals" "^7.22.5" "@babel/plugin-transform-modules-amd" "^7.22.5" - "@babel/plugin-transform-modules-commonjs" "^7.22.5" - "@babel/plugin-transform-modules-systemjs" "^7.22.5" + "@babel/plugin-transform-modules-commonjs" "^7.22.11" + "@babel/plugin-transform-modules-systemjs" "^7.22.11" "@babel/plugin-transform-modules-umd" "^7.22.5" "@babel/plugin-transform-named-capturing-groups-regex" "^7.22.5" "@babel/plugin-transform-new-target" "^7.22.5" - "@babel/plugin-transform-nullish-coalescing-operator" "^7.22.5" - "@babel/plugin-transform-numeric-separator" "^7.22.5" - "@babel/plugin-transform-object-rest-spread" "^7.22.5" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.22.11" + "@babel/plugin-transform-numeric-separator" "^7.22.11" + "@babel/plugin-transform-object-rest-spread" "^7.22.11" "@babel/plugin-transform-object-super" "^7.22.5" - "@babel/plugin-transform-optional-catch-binding" "^7.22.5" - "@babel/plugin-transform-optional-chaining" "^7.22.10" + "@babel/plugin-transform-optional-catch-binding" "^7.22.11" + "@babel/plugin-transform-optional-chaining" "^7.22.12" "@babel/plugin-transform-parameters" "^7.22.5" "@babel/plugin-transform-private-methods" "^7.22.5" - "@babel/plugin-transform-private-property-in-object" "^7.22.5" + "@babel/plugin-transform-private-property-in-object" "^7.22.11" "@babel/plugin-transform-property-literals" "^7.22.5" "@babel/plugin-transform-regenerator" "^7.22.10" "@babel/plugin-transform-reserved-words" "^7.22.5" @@ -1026,7 +1024,7 @@ "@babel/plugin-transform-unicode-regex" "^7.22.5" "@babel/plugin-transform-unicode-sets-regex" "^7.22.5" "@babel/preset-modules" "0.1.6-no-external-plugins" - "@babel/types" "^7.22.10" + "@babel/types" "^7.22.11" babel-plugin-polyfill-corejs2 "^0.4.5" babel-plugin-polyfill-corejs3 "^0.8.3" babel-plugin-polyfill-regenerator "^0.5.2" @@ -1125,7 +1123,7 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.3.3", "@babel/types@^7.4.4": +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.3.3": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.10.tgz#4a9e76446048f2c66982d1a989dd12b8a2d2dc03" integrity sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg== @@ -1143,7 +1141,7 @@ "@babel/helper-validator-identifier" "^7.22.5" to-fast-properties "^2.0.0" -"@babel/types@^7.22.10", "@babel/types@^7.22.11", "@babel/types@^7.22.5": +"@babel/types@^7.22.10", "@babel/types@^7.22.11", "@babel/types@^7.22.5", "@babel/types@^7.4.4": version "7.22.11" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.11.tgz#0e65a6a1d4d9cbaa892b2213f6159485fe632ea2" integrity sha512-siazHiGuZRz9aB9NpHy9GOs9xiQPKnMzgdr493iI1M67vRXpnEq8ZOOKzezC5q7zwuQ6sDhdSp4SD9ixKSqKZg== @@ -3932,9 +3930,9 @@ caniuse-lite@^1.0.30001502: integrity sha512-eEFDwUOZbE24sb+Ecsx3+OvNETqjWIdabMy52oOkIgcUtAsQifjUG9q4U9dgTHJM2mfk4uEPxc0+xuFdJ629QA== caniuse-lite@^1.0.30001517: - version "1.0.30001522" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001522.tgz#44b87a406c901269adcdb834713e23582dd71856" - integrity sha512-TKiyTVZxJGhsTszLuzb+6vUZSjVOAhClszBr2Ta2k9IwtNBT/4dzmL6aywt0HCgEZlmwJzXJd8yNiob6HgwTRg== + version "1.0.30001524" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001524.tgz#1e14bce4f43c41a7deaeb5ebfe86664fe8dadb80" + integrity sha512-Jj917pJtYg9HSJBF95HVX3Cdr89JUyLT4IZ8SvM5aDRni95swKgYi3TgYLH5hnGfPE/U1dg6IfZ50UsIlLkwSA== caniuse-lite@^1.0.30001520: version "1.0.30001520" @@ -4335,11 +4333,11 @@ copy-descriptor@^0.1.0: integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw== core-js-compat@^3.31.0: - version "3.32.0" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.32.0.tgz#f41574b6893ab15ddb0ac1693681bd56c8550a90" - integrity sha512-7a9a3D1k4UCVKnLhrgALyFcP7YCsLOQIxPd0dKjf/6GuPcgyiGP70ewWdCGrSK7evyhymi0qO4EqCmSJofDeYw== + version "3.32.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.32.1.tgz#55f9a7d297c0761a8eb1d31b593e0f5b6ffae964" + integrity sha512-GSvKDv4wE0bPnQtjklV101juQ85g6H3rm5PDP20mqlS5j0kXF3pP97YvAu5hl+uFHqMictp3b2VxOHljWMAtuA== dependencies: - browserslist "^4.21.9" + browserslist "^4.21.10" core-js@^2.5.0: version "2.6.12" @@ -5085,9 +5083,9 @@ electron-to-chromium@^1.4.428: integrity sha512-/g3UyNDmDd6ebeWapmAoiyy+Sy2HyJ+/X8KyvNeHfKRFfHaA2W8oF5fxD5F3tjBDcjpwo0iek6YNgxNXDBoEtA== electron-to-chromium@^1.4.477: - version "1.4.500" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.500.tgz#7dd05fdfbe02ed34b9f6099cfe01407b473d5af7" - integrity sha512-P38NO8eOuWOKY1sQk5yE0crNtrjgjJj6r3NrbIKtG18KzCHmHE2Bt+aQA7/y0w3uYsHWxDa6icOohzjLJ4vJ4A== + version "1.4.505" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.505.tgz#00571ade5975b58413f0f56a665b065bfc29cdfc" + integrity sha512-0A50eL5BCCKdxig2SsCXhpuztnB9PfUgRMojj5tMvt8O54lbwz3t6wNgnpiTRosw5QjlJB7ixhVyeg8daLQwSQ== elliptic@^6.5.3: version "6.5.4" From cb9f96036cf78835e22aafb30b80717b5a8b7394 Mon Sep 17 00:00:00 2001 From: gunchleoc Date: Thu, 31 Aug 2023 12:17:10 +0200 Subject: [PATCH 44/65] Add suggestion for secure cyphers to nginx.conf (#26349) --- dist/nginx.conf | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dist/nginx.conf b/dist/nginx.conf index 39fa58e50d..5bb9903864 100644 --- a/dist/nginx.conf +++ b/dist/nginx.conf @@ -36,7 +36,11 @@ server { server_name example.com; ssl_protocols TLSv1.2 TLSv1.3; - ssl_ciphers HIGH:!MEDIUM:!LOW:!aNULL:!NULL:!SHA; + + # You can use https://ssl-config.mozilla.org/ to generate your cipher set. + # We recommend their "Intermediate" level. + ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305; + ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_tickets off; From 40b69cc1cd62fa57047905a6999985ae6c183f6c Mon Sep 17 00:00:00 2001 From: Stanislas Signoud Date: Thu, 31 Aug 2023 12:18:46 +0200 Subject: [PATCH 45/65] Add an explanation banner on switching to single column mode (#26019) --- .../features/ui/components/navigation_panel.jsx | 16 +++++++++++----- app/javascript/mastodon/locales/en.json | 1 + app/javascript/mastodon/locales/fr.json | 1 + app/javascript/styles/mastodon/components.scss | 16 ++++++++++++++++ 4 files changed, 29 insertions(+), 5 deletions(-) diff --git a/app/javascript/mastodon/features/ui/components/navigation_panel.jsx b/app/javascript/mastodon/features/ui/components/navigation_panel.jsx index d36abf8f17..8006ca89a2 100644 --- a/app/javascript/mastodon/features/ui/components/navigation_panel.jsx +++ b/app/javascript/mastodon/features/ui/components/navigation_panel.jsx @@ -31,6 +31,7 @@ const messages = defineMessages({ about: { id: 'navigation_bar.about', defaultMessage: 'About' }, search: { id: 'navigation_bar.search', defaultMessage: 'Search' }, advancedInterface: { id: 'navigation_bar.advanced_interface', defaultMessage: 'Open in advanced web interface' }, + openedInClassicInterface: { id: 'navigation_bar.opened_in_classic_interface', defaultMessage: 'Posts, accounts, and other specific pages are opened by default in the classic web interface.' }, }); class NavigationPanel extends Component { @@ -57,12 +58,17 @@ class NavigationPanel extends Component {
- {transientSingleColumn && ( - - {intl.formatMessage(messages.advancedInterface)} - + {transientSingleColumn ? ( +
+ {intl.formatMessage(messages.openedInClassicInterface)} + {" "} + + {intl.formatMessage(messages.advancedInterface)} + +
+ ) : ( +
)} -
{signedIn && ( diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index 5871b08def..90bb9616f0 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -411,6 +411,7 @@ "navigation_bar.lists": "Lists", "navigation_bar.logout": "Logout", "navigation_bar.mutes": "Muted users", + "navigation_bar.opened_in_classic_interface": "Posts, accounts, and other specific pages are opened by default in the classic web interface.", "navigation_bar.personal": "Personal", "navigation_bar.pins": "Pinned posts", "navigation_bar.preferences": "Preferences", diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json index 2bef3bb4b3..116ed66d03 100644 --- a/app/javascript/mastodon/locales/fr.json +++ b/app/javascript/mastodon/locales/fr.json @@ -409,6 +409,7 @@ "navigation_bar.lists": "Listes", "navigation_bar.logout": "Déconnexion", "navigation_bar.mutes": "Comptes masqués", + "navigation_bar.opened_in_classic_interface": "Les messages, les comptes et les pages spécifiques sont ouvertes dans l’interface classique.", "navigation_bar.personal": "Personnel", "navigation_bar.pins": "Messages épinglés", "navigation_bar.preferences": "Préférences", diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index c07f95f564..95e6667b5d 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -3270,6 +3270,22 @@ $ui-header-height: 55px; border-color: $ui-highlight-color; } +.switch-to-advanced { + color: $classic-primary-color; + background-color: $classic-base-color; + padding: 15px; + border-radius: 4px; + margin-top: 4px; + margin-bottom: 12px; + font-size: 13px; + line-height: 18px; + + .switch-to-advanced__toggle { + color: $ui-button-tertiary-color; + font-weight: bold; + } +} + .column-link { background: lighten($ui-base-color, 8%); color: $primary-text-color; From 725ffa02587b50a8ba89de3b9c87b8e9f4250cd8 Mon Sep 17 00:00:00 2001 From: KMY Date: Thu, 31 Aug 2023 19:24:08 +0900 Subject: [PATCH 46/65] Fix api design misstake --- app/services/post_status_service.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb index 9404168c2b..5a7724fba4 100644 --- a/app/services/post_status_service.rb +++ b/app/services/post_status_service.rb @@ -92,7 +92,7 @@ class PostStatusService < BaseService end def load_circle - return unless @options[:visibility] == 'circle' + return unless @options[:visibility] == 'circle' || (@options[:visibility] == 'limited' && @options[:circle_id].present?) @circle = @options[:circle_id].present? && Circle.find(@options[:circle_id]) raise ArgumentError if @circle.nil? || @circle.account_id != @account.id From 05ae3c1948e4ee33d1dfe2d99b28e6bc29df29c7 Mon Sep 17 00:00:00 2001 From: KMY Date: Thu, 31 Aug 2023 19:33:50 +0900 Subject: [PATCH 47/65] Fix limited_scope --- app/services/post_status_service.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb index 5a7724fba4..22624dc913 100644 --- a/app/services/post_status_service.rb +++ b/app/services/post_status_service.rb @@ -95,6 +95,7 @@ class PostStatusService < BaseService return unless @options[:visibility] == 'circle' || (@options[:visibility] == 'limited' && @options[:circle_id].present?) @circle = @options[:circle_id].present? && Circle.find(@options[:circle_id]) + @limited_scope = :circle raise ArgumentError if @circle.nil? || @circle.account_id != @account.id end From 336ec503c28356a969e2987ef426063f0943b4e3 Mon Sep 17 00:00:00 2001 From: Tyler Deitz Date: Thu, 31 Aug 2023 04:46:27 -0700 Subject: [PATCH 48/65] Add avatar image to webfinger responses (#26558) --- app/serializers/webfinger_serializer.rb | 37 +++++++---- .../well_known/webfinger_controller_spec.rb | 64 +++++++++++++++++++ 2 files changed, 89 insertions(+), 12 deletions(-) diff --git a/app/serializers/webfinger_serializer.rb b/app/serializers/webfinger_serializer.rb index 3ca3441169..b67cd2771a 100644 --- a/app/serializers/webfinger_serializer.rb +++ b/app/serializers/webfinger_serializer.rb @@ -18,18 +18,31 @@ class WebfingerSerializer < ActiveModel::Serializer end def links - if object.instance_actor? - [ - { rel: 'http://webfinger.net/rel/profile-page', type: 'text/html', href: about_more_url(instance_actor: true) }, - { rel: 'self', type: 'application/activity+json', href: instance_actor_url }, - { rel: 'http://ostatus.org/schema/1.0/subscribe', template: "#{authorize_interaction_url}?uri={uri}" }, - ] - else - [ - { rel: 'http://webfinger.net/rel/profile-page', type: 'text/html', href: short_account_url(object) }, - { rel: 'self', type: 'application/activity+json', href: account_url(object) }, - { rel: 'http://ostatus.org/schema/1.0/subscribe', template: "#{authorize_interaction_url}?uri={uri}" }, - ] + [ + { rel: 'http://webfinger.net/rel/profile-page', type: 'text/html', href: profile_page_href }, + { rel: 'self', type: 'application/activity+json', href: self_href }, + { rel: 'http://ostatus.org/schema/1.0/subscribe', template: "#{authorize_interaction_url}?uri={uri}" }, + ].tap do |x| + x << { rel: 'http://webfinger.net/rel/avatar', type: object.avatar.content_type, href: full_asset_url(object.avatar_original_url) } if show_avatar? end end + + private + + def show_avatar? + media_present = object.avatar.present? && object.avatar.content_type.present? + + # Show avatar only if an instance shows profiles to logged out users + allowed_by_config = ENV['DISALLOW_UNAUTHENTICATED_API_ACCESS'] != 'true' && !Rails.configuration.x.limited_federation_mode + + media_present && allowed_by_config + end + + def profile_page_href + object.instance_actor? ? about_more_url(instance_actor: true) : short_account_url(object) + end + + def self_href + object.instance_actor? ? instance_actor_url : account_url(object) + end end diff --git a/spec/controllers/well_known/webfinger_controller_spec.rb b/spec/controllers/well_known/webfinger_controller_spec.rb index 8dc0f329b6..20770a7211 100644 --- a/spec/controllers/well_known/webfinger_controller_spec.rb +++ b/spec/controllers/well_known/webfinger_controller_spec.rb @@ -3,6 +3,8 @@ require 'rails_helper' describe WellKnown::WebfingerController do + include RoutingHelper + render_views describe 'GET #show' do @@ -167,5 +169,67 @@ describe WellKnown::WebfingerController do expect(response).to have_http_status(400) end end + + context 'when an account has an avatar' do + let(:alice) { Fabricate(:account, username: 'alice', avatar: attachment_fixture('attachment.jpg')) } + let(:resource) { alice.to_webfinger_s } + + it 'returns avatar in response' do + perform_show! + + avatar_link = get_avatar_link(body_as_json) + expect(avatar_link).to_not be_nil + expect(avatar_link[:type]).to eq alice.avatar.content_type + expect(avatar_link[:href]).to eq full_asset_url(alice.avatar) + end + + context 'with limited federation mode' do + before do + allow(Rails.configuration.x).to receive(:limited_federation_mode).and_return(true) + end + + it 'does not return avatar in response' do + perform_show! + + avatar_link = get_avatar_link(body_as_json) + expect(avatar_link).to be_nil + end + end + + context 'when enabling DISALLOW_UNAUTHENTICATED_API_ACCESS' do + around do |example| + ClimateControl.modify DISALLOW_UNAUTHENTICATED_API_ACCESS: 'true' do + example.run + end + end + + it 'does not return avatar in response' do + perform_show! + + avatar_link = get_avatar_link(body_as_json) + expect(avatar_link).to be_nil + end + end + end + + context 'when an account does not have an avatar' do + let(:alice) { Fabricate(:account, username: 'alice', avatar: nil) } + let(:resource) { alice.to_webfinger_s } + + before do + perform_show! + end + + it 'does not return avatar in response' do + avatar_link = get_avatar_link(body_as_json) + expect(avatar_link).to be_nil + end + end + end + + private + + def get_avatar_link(json) + json[:links].find { |link| link[:rel] == 'http://webfinger.net/rel/avatar' } end end From ccca542db1e73610a86c1d34d8b42f3f4a818af9 Mon Sep 17 00:00:00 2001 From: Daniel M Brasil Date: Thu, 31 Aug 2023 08:53:24 -0300 Subject: [PATCH 49/65] Fix `/api/v1/timelines/tag/:hashtag` allowing for unauthenticated access when public preview is disabled (#26237) --- .../api/v1/timelines/tag_controller.rb | 5 ++ .../api/v1/timelines/tag_controller_spec.rb | 66 ++++++++++++++----- 2 files changed, 53 insertions(+), 18 deletions(-) diff --git a/app/controllers/api/v1/timelines/tag_controller.rb b/app/controllers/api/v1/timelines/tag_controller.rb index 9cd7b99046..a79d65c124 100644 --- a/app/controllers/api/v1/timelines/tag_controller.rb +++ b/app/controllers/api/v1/timelines/tag_controller.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true class Api::V1::Timelines::TagController < Api::BaseController + before_action -> { doorkeeper_authorize! :read, :'read:statuses' }, only: :show, if: :require_auth? before_action :load_tag after_action :insert_pagination_headers, unless: -> { @statuses.empty? } @@ -12,6 +13,10 @@ class Api::V1::Timelines::TagController < Api::BaseController private + def require_auth? + !Setting.timeline_preview + end + def load_tag @tag = Tag.find_normalized(params[:id]) end diff --git a/spec/controllers/api/v1/timelines/tag_controller_spec.rb b/spec/controllers/api/v1/timelines/tag_controller_spec.rb index 7189110833..1c60798fcf 100644 --- a/spec/controllers/api/v1/timelines/tag_controller_spec.rb +++ b/spec/controllers/api/v1/timelines/tag_controller_spec.rb @@ -5,36 +5,66 @@ require 'rails_helper' describe Api::V1::Timelines::TagController do render_views - let(:user) { Fabricate(:user) } + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:statuses') } before do allow(controller).to receive(:doorkeeper_token) { token } end - context 'with a user context' do - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id) } + describe 'GET #show' do + subject do + get :show, params: { id: 'test' } + end - describe 'GET #show' do - before do - PostStatusService.new.call(user.account, text: 'It is a #test') + before do + PostStatusService.new.call(user.account, text: 'It is a #test') + end + + context 'when the instance allows public preview' do + context 'when the user is not authenticated' do + let(:token) { nil } + + it 'returns http success', :aggregate_failures do + subject + + expect(response).to have_http_status(200) + expect(response.headers['Link'].links.size).to eq(2) + end end - it 'returns http success' do - get :show, params: { id: 'test' } - expect(response).to have_http_status(200) - expect(response.headers['Link'].links.size).to eq(2) + context 'when the user is authenticated' do + it 'returns http success', :aggregate_failures do + subject + + expect(response).to have_http_status(200) + expect(response.headers['Link'].links.size).to eq(2) + end end end - end - context 'without a user context' do - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: nil) } + context 'when the instance does not allow public preview' do + before do + Form::AdminSettings.new(timeline_preview: false).save + end - describe 'GET #show' do - it 'returns http success' do - get :show, params: { id: 'test' } - expect(response).to have_http_status(200) - expect(response.headers['Link']).to be_nil + context 'when the user is not authenticated' do + let(:token) { nil } + + it 'returns http unauthorized' do + subject + + expect(response).to have_http_status(401) + end + end + + context 'when the user is authenticated' do + it 'returns http success', :aggregate_failures do + subject + + expect(response).to have_http_status(200) + expect(response.headers['Link'].links.size).to eq(2) + end end end end From f1d250135ccf9be5c4d982a2c48417da89d38eb5 Mon Sep 17 00:00:00 2001 From: Santiago Kozak Date: Thu, 31 Aug 2023 09:15:58 -0300 Subject: [PATCH 50/65] Allow filter form in profiles directory to wrap (#26682) --- app/javascript/styles/mastodon/components.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 95e6667b5d..f61cd059fe 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -2381,6 +2381,7 @@ $ui-header-height: 55px; .filter-form { display: flex; + flex-wrap: wrap; } .autosuggest-textarea__textarea { From cffc5d2b0180e2ead23f32391246cdac357bf71b Mon Sep 17 00:00:00 2001 From: Renaud Chaput Date: Thu, 31 Aug 2023 14:59:50 +0200 Subject: [PATCH 51/65] Fix comment in build image workflow (#26740) --- .github/workflows/build-container-image.yml | 2 -- .github/workflows/build-releases.yml | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-container-image.yml b/.github/workflows/build-container-image.yml index 897bb9caaa..a1aeddf201 100644 --- a/.github/workflows/build-container-image.yml +++ b/.github/workflows/build-container-image.yml @@ -76,8 +76,6 @@ jobs: if: ${{ inputs.push_to_images != '' }} with: images: ${{ inputs.push_to_images }} - # Only tag with latest when ran against the latest stable branch - # This needs to be updated after each minor version release flavor: ${{ inputs.flavor }} tags: ${{ inputs.tags }} labels: ${{ inputs.labels }} diff --git a/.github/workflows/build-releases.yml b/.github/workflows/build-releases.yml index b408174688..f739a69d9a 100644 --- a/.github/workflows/build-releases.yml +++ b/.github/workflows/build-releases.yml @@ -17,6 +17,8 @@ jobs: push_to_images: | tootsuite/mastodon ghcr.io/mastodon/mastodon + # Only tag with latest when ran against the latest stable branch + # This needs to be updated after each minor version release flavor: | latest=${{ startsWith(github.ref, 'refs/tags/v4.1.') }} tags: | From 6b58cfd8dd2f635dbb1b9d10b6b243d20ba23535 Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 31 Aug 2023 15:35:58 +0200 Subject: [PATCH 52/65] Fix searching by username by reverting account verbatim tokenizer to `standard` (#26739) --- app/chewy/accounts_index.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/chewy/accounts_index.rb b/app/chewy/accounts_index.rb index 8881b08f66..00db257ac7 100644 --- a/app/chewy/accounts_index.rb +++ b/app/chewy/accounts_index.rb @@ -34,7 +34,7 @@ class AccountsIndex < Chewy::Index }, verbatim: { - tokenizer: 'uax_url_email', + tokenizer: 'standard', filter: %w(lowercase asciifolding cjk_width), }, From 1471be82255d948460b0b653dd48cdfbc67d90cf Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 31 Aug 2023 15:47:30 +0200 Subject: [PATCH 53/65] Fix `AddUniqueIndexOnPreviewCardsStatuses` migration requiring PostgreSQL 12+ in some cases (#26737) --- ...1_add_unique_index_on_preview_cards_statuses.rb | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/db/post_migrate/20230803082451_add_unique_index_on_preview_cards_statuses.rb b/db/post_migrate/20230803082451_add_unique_index_on_preview_cards_statuses.rb index c35ad80028..3e9ab134b7 100644 --- a/db/post_migrate/20230803082451_add_unique_index_on_preview_cards_statuses.rb +++ b/db/post_migrate/20230803082451_add_unique_index_on_preview_cards_statuses.rb @@ -15,10 +15,22 @@ class AddUniqueIndexOnPreviewCardsStatuses < ActiveRecord::Migration[6.1] private + def supports_concurrent_reindex? + @supports_concurrent_reindex ||= begin + version = select_one("SELECT current_setting('server_version_num') AS v")['v'].to_i + version >= 12_000 + end + end + def deduplicate_and_reindex! deduplicate_preview_cards! - safety_assured { execute 'REINDEX INDEX CONCURRENTLY preview_cards_statuses_pkey' } + if supports_concurrent_reindex? + safety_assured { execute 'REINDEX INDEX CONCURRENTLY preview_cards_statuses_pkey' } + else + remove_index :preview_cards_statuses, name: :preview_cards_statuses_pkey + add_index :preview_cards_statuses, [:status_id, :preview_card_id], name: :preview_cards_statuses_pkey, algorithm: :concurrently, unique: true + end rescue ActiveRecord::RecordNotUnique retry end From ecd76fa413e31d4eb26e09fa4b65f8b13bbbb0b7 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 31 Aug 2023 17:21:06 +0200 Subject: [PATCH 54/65] Fix videos not playing in some browsers due to unsupported color space (#26745) --- app/models/media_attachment.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/models/media_attachment.rb b/app/models/media_attachment.rb index 88abd93390..984f4252a1 100644 --- a/app/models/media_attachment.rb +++ b/app/models/media_attachment.rb @@ -100,6 +100,8 @@ class MediaAttachment < ApplicationRecord output: { 'loglevel' => 'fatal', 'preset' => 'veryfast', + 'movflags' => 'faststart', # Move metadata to start of file so playback can begin before download finishes + 'pix_fmt' => 'yuv420p', # Ensure color space for cross-browser compatibility 'c:v' => 'h264', 'c:a' => 'aac', 'b:a' => '192k', From 9bb2fb6b1484c90c5b2c6cc52ce148019e82a3e2 Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 31 Aug 2023 19:04:27 +0200 Subject: [PATCH 55/65] Change importers to avoid a few inefficiencies (#26721) --- app/lib/importer/accounts_index_importer.rb | 6 ++-- app/lib/importer/base_importer.rb | 8 +++++ app/lib/importer/instances_index_importer.rb | 6 ++-- .../public_statuses_index_importer.rb | 6 ++-- app/lib/importer/statuses_index_importer.rb | 35 ++++++++----------- app/lib/importer/tags_index_importer.rb | 6 ++-- 6 files changed, 34 insertions(+), 33 deletions(-) diff --git a/app/lib/importer/accounts_index_importer.rb b/app/lib/importer/accounts_index_importer.rb index fd869c3960..d8b9190275 100644 --- a/app/lib/importer/accounts_index_importer.rb +++ b/app/lib/importer/accounts_index_importer.rb @@ -4,10 +4,10 @@ class Importer::AccountsIndexImporter < Importer::BaseImporter def import! scope.includes(:account_stat).find_in_batches(batch_size: @batch_size) do |tmp| in_work_unit(tmp) do |accounts| - bulk = Chewy::Index::Import::BulkBuilder.new(index, to_index: accounts).bulk_body + bulk = build_bulk_body(accounts) - indexed = bulk.count { |entry| entry[:index] } - deleted = bulk.count { |entry| entry[:delete] } + indexed = bulk.size + deleted = 0 Chewy::Index::Import::BulkRequest.new(index).perform(bulk) diff --git a/app/lib/importer/base_importer.rb b/app/lib/importer/base_importer.rb index cc1b7b44d7..a21557d303 100644 --- a/app/lib/importer/base_importer.rb +++ b/app/lib/importer/base_importer.rb @@ -68,6 +68,14 @@ class Importer::BaseImporter protected + def build_bulk_body(to_import) + # Specialize `Chewy::Index::Import::BulkBuilder#bulk_body` to avoid a few + # inefficiencies, as none of our fields or join fields and we do not need + # `BulkBuilder`'s versatility. + crutches = Chewy::Index::Crutch::Crutches.new index, to_import + to_import.map { |object| { index: { _id: object.id, data: index.compose(object, crutches, fields: []) } } } + end + def in_work_unit(...) work_unit = Concurrent::Promises.future_on(@executor, ...) diff --git a/app/lib/importer/instances_index_importer.rb b/app/lib/importer/instances_index_importer.rb index 7318b51b5d..ebdceb72ed 100644 --- a/app/lib/importer/instances_index_importer.rb +++ b/app/lib/importer/instances_index_importer.rb @@ -4,10 +4,10 @@ class Importer::InstancesIndexImporter < Importer::BaseImporter def import! index.adapter.default_scope.find_in_batches(batch_size: @batch_size) do |tmp| in_work_unit(tmp) do |instances| - bulk = Chewy::Index::Import::BulkBuilder.new(index, to_index: instances).bulk_body + bulk = build_bulk_body(instances) - indexed = bulk.count { |entry| entry[:index] } - deleted = bulk.count { |entry| entry[:delete] } + indexed = bulk.size + deleted = 0 Chewy::Index::Import::BulkRequest.new(index).perform(bulk) diff --git a/app/lib/importer/public_statuses_index_importer.rb b/app/lib/importer/public_statuses_index_importer.rb index 72d02318b1..ebaac3794f 100644 --- a/app/lib/importer/public_statuses_index_importer.rb +++ b/app/lib/importer/public_statuses_index_importer.rb @@ -5,11 +5,11 @@ class Importer::PublicStatusesIndexImporter < Importer::BaseImporter scope.select(:id).find_in_batches(batch_size: @batch_size) do |batch| in_work_unit(batch.pluck(:id)) do |status_ids| bulk = ActiveRecord::Base.connection_pool.with_connection do - Chewy::Index::Import::BulkBuilder.new(index, to_index: Status.includes(:media_attachments, :preloadable_poll, :preview_cards).where(id: status_ids)).bulk_body + build_bulk_body(index.adapter.default_scope.where(id: status_ids)) end - indexed = bulk.count { |entry| entry[:index] } - deleted = bulk.count { |entry| entry[:delete] } + indexed = bulk.size + deleted = 0 Chewy::Index::Import::BulkRequest.new(index).perform(bulk) diff --git a/app/lib/importer/statuses_index_importer.rb b/app/lib/importer/statuses_index_importer.rb index 285ddc871a..08ad3e3797 100644 --- a/app/lib/importer/statuses_index_importer.rb +++ b/app/lib/importer/statuses_index_importer.rb @@ -13,32 +13,25 @@ class Importer::StatusesIndexImporter < Importer::BaseImporter scope.find_in_batches(batch_size: @batch_size) do |tmp| in_work_unit(tmp.map(&:status_id)) do |status_ids| - bulk = ActiveRecord::Base.connection_pool.with_connection do - Chewy::Index::Import::BulkBuilder.new(index, to_index: index.adapter.default_scope.where(id: status_ids)).bulk_body - end - - indexed = 0 deleted = 0 - # We can't use the delete_if proc to do the filtering because delete_if - # is called before rendering the data and we need to filter based - # on the results of the filter, so this filtering happens here instead - bulk.map! do |entry| - new_entry = if entry[:index] && entry.dig(:index, :data, 'searchable_by').blank? - { delete: entry[:index].except(:data) } - else - entry - end - - if new_entry[:index] - indexed += 1 - else - deleted += 1 + bulk = ActiveRecord::Base.connection_pool.with_connection do + to_index = index.adapter.default_scope.where(id: status_ids) + crutches = Chewy::Index::Crutch::Crutches.new index, to_index + to_index.map do |object| + # This is unlikely to happen, but the post may have been + # un-interacted with since it was queued for indexing + if object.searchable_by.empty? + deleted += 1 + { delete: { _id: object.id } } + else + { index: { _id: object.id, data: index.compose(object, crutches, fields: []) } } + end end - - new_entry end + indexed = bulk.size - deleted + Chewy::Index::Import::BulkRequest.new(index).perform(bulk) [indexed, deleted] diff --git a/app/lib/importer/tags_index_importer.rb b/app/lib/importer/tags_index_importer.rb index 77710ed7de..067fd8cd2d 100644 --- a/app/lib/importer/tags_index_importer.rb +++ b/app/lib/importer/tags_index_importer.rb @@ -4,10 +4,10 @@ class Importer::TagsIndexImporter < Importer::BaseImporter def import! index.adapter.default_scope.find_in_batches(batch_size: @batch_size) do |tmp| in_work_unit(tmp) do |tags| - bulk = Chewy::Index::Import::BulkBuilder.new(index, to_index: tags).bulk_body + bulk = build_bulk_body(tags) - indexed = bulk.count { |entry| entry[:index] } - deleted = bulk.count { |entry| entry[:delete] } + indexed = bulk.size + deleted = 0 Chewy::Index::Import::BulkRequest.new(index).perform(bulk) From 00084581289b4b7afd120845363b16247c5fa93b Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 31 Aug 2023 19:04:44 +0200 Subject: [PATCH 56/65] Fix search queries with slash causing or-condition (#26699) --- app/lib/search_query_transformer.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/lib/search_query_transformer.rb b/app/lib/search_query_transformer.rb index 86e3f50005..f10ccfb283 100644 --- a/app/lib/search_query_transformer.rb +++ b/app/lib/search_query_transformer.rb @@ -25,7 +25,7 @@ class SearchQueryTransformer < Parslet::Transform def clause_to_query(clause) case clause when TermClause - { multi_match: { type: 'most_fields', query: clause.term, fields: ['text', 'text.stemmed'] } } + { multi_match: { type: 'most_fields', query: clause.term, fields: ['text', 'text.stemmed'], operator: 'and' } } when PhraseClause { match_phrase: { text: { query: clause.phrase } } } else From 872145d1c2aec709770de10579d2a4f83c601f37 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 1 Sep 2023 09:27:03 +0200 Subject: [PATCH 57/65] Fix not being able to invoke phrase search using unicode quotation marks (#26687) --- app/services/search_service.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/services/search_service.rb b/app/services/search_service.rb index 40d82fc525..9a40d7bdd5 100644 --- a/app/services/search_service.rb +++ b/app/services/search_service.rb @@ -1,8 +1,10 @@ # frozen_string_literal: true class SearchService < BaseService + QUOTE_EQUIVALENT_CHARACTERS = /[“”„«»「」『』《》]/ + def call(query, account, limit, options = {}) - @query = query&.strip + @query = query&.strip&.gsub(QUOTE_EQUIVALENT_CHARACTERS, '"') @account = account @options = options @limit = limit.to_i From e754083e8a33778b5dd8d43efc5604ed50efb0e4 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 1 Sep 2023 09:43:12 +0200 Subject: [PATCH 58/65] Fix unmatched quotes and prefixes causing search to fail (#26701) --- app/lib/search_query_parser.rb | 4 +- app/lib/search_query_transformer.rb | 101 +++++++++++----------- spec/lib/search_query_parser_spec.rb | 98 +++++++++++++++++++++ spec/lib/search_query_transformer_spec.rb | 57 ++++++++++-- 4 files changed, 200 insertions(+), 60 deletions(-) create mode 100644 spec/lib/search_query_parser_spec.rb diff --git a/app/lib/search_query_parser.rb b/app/lib/search_query_parser.rb index 5d6ffbf29d..1c57b9b024 100644 --- a/app/lib/search_query_parser.rb +++ b/app/lib/search_query_parser.rb @@ -6,10 +6,10 @@ class SearchQueryParser < Parslet::Parser rule(:colon) { str(':') } rule(:space) { match('\s').repeat(1) } rule(:operator) { (str('+') | str('-')).as(:operator) } - rule(:prefix) { (term >> colon).as(:prefix) } + rule(:prefix) { term >> colon } rule(:shortcode) { (colon >> term >> colon.maybe).as(:shortcode) } rule(:phrase) { (quote >> (term >> space.maybe).repeat >> quote).as(:phrase) } - rule(:clause) { (operator.maybe >> prefix.maybe >> (phrase | term | shortcode)).as(:clause) } + rule(:clause) { (operator.maybe >> prefix.maybe.as(:prefix) >> (phrase | term | shortcode)).as(:clause) | prefix.as(:clause) | quote.as(:junk) } rule(:query) { (clause >> space.maybe).repeat.as(:query) } root(:query) end diff --git a/app/lib/search_query_transformer.rb b/app/lib/search_query_transformer.rb index f10ccfb283..e81c0c081e 100644 --- a/app/lib/search_query_transformer.rb +++ b/app/lib/search_query_transformer.rb @@ -1,50 +1,32 @@ # frozen_string_literal: true class SearchQueryTransformer < Parslet::Transform + SUPPORTED_PREFIXES = %w( + has + is + language + from + before + after + during + ).freeze + class Query - attr_reader :should_clauses, :must_not_clauses, :must_clauses, :filter_clauses + attr_reader :must_not_clauses, :must_clauses, :filter_clauses def initialize(clauses) - grouped = clauses.chunk(&:operator).to_h - @should_clauses = grouped.fetch(:should, []) + grouped = clauses.compact.chunk(&:operator).to_h @must_not_clauses = grouped.fetch(:must_not, []) @must_clauses = grouped.fetch(:must, []) @filter_clauses = grouped.fetch(:filter, []) end def apply(search) - should_clauses.each { |clause| search = search.query.should(clause_to_query(clause)) } - must_clauses.each { |clause| search = search.query.must(clause_to_query(clause)) } - must_not_clauses.each { |clause| search = search.query.must_not(clause_to_query(clause)) } - filter_clauses.each { |clause| search = search.filter(**clause_to_filter(clause)) } + must_clauses.each { |clause| search = search.query.must(clause.to_query) } + must_not_clauses.each { |clause| search = search.query.must_not(clause.to_query) } + filter_clauses.each { |clause| search = search.filter(**clause.to_query) } search.query.minimum_should_match(1) end - - private - - def clause_to_query(clause) - case clause - when TermClause - { multi_match: { type: 'most_fields', query: clause.term, fields: ['text', 'text.stemmed'], operator: 'and' } } - when PhraseClause - { match_phrase: { text: { query: clause.phrase } } } - else - raise "Unexpected clause type: #{clause}" - end - end - - def clause_to_filter(clause) - case clause - when PrefixClause - if clause.negated? - { bool: { must_not: { clause.type => { clause.filter => clause.term } } } } - else - { clause.type => { clause.filter => clause.term } } - end - else - raise "Unexpected clause type: #{clause}" - end - end end class Operator @@ -63,31 +45,38 @@ class SearchQueryTransformer < Parslet::Transform end class TermClause - attr_reader :prefix, :operator, :term + attr_reader :operator, :term - def initialize(prefix, operator, term) - @prefix = prefix + def initialize(operator, term) @operator = Operator.symbol(operator) @term = term end + + def to_query + { multi_match: { type: 'most_fields', query: @term, fields: ['text', 'text.stemmed'], operator: 'and' } } + end end class PhraseClause - attr_reader :prefix, :operator, :phrase + attr_reader :operator, :phrase - def initialize(prefix, operator, phrase) - @prefix = prefix + def initialize(operator, phrase) @operator = Operator.symbol(operator) @phrase = phrase end + + def to_query + { match_phrase: { text: { query: @phrase } } } + end end class PrefixClause - attr_reader :type, :filter, :operator, :term + attr_reader :operator, :prefix, :term def initialize(prefix, operator, term, options = {}) - @negated = operator == '-' - @options = options + @prefix = prefix + @negated = operator == '-' + @options = options @operator = :filter case prefix @@ -116,12 +105,16 @@ class SearchQueryTransformer < Parslet::Transform @type = :range @term = { gte: term, lte: term, time_zone: @options[:current_account]&.user_time_zone || 'UTC' } else - raise Mastodon::SyntaxError + raise "Unknown prefix: #{prefix}" end end - def negated? - @negated + def to_query + if @negated + { bool: { must_not: { @type => { @filter => @term } } } } + else + { @type => { @filter => @term } } + end end private @@ -159,18 +152,26 @@ class SearchQueryTransformer < Parslet::Transform prefix = clause[:prefix][:term].to_s if clause[:prefix] operator = clause[:operator]&.to_s - if clause[:prefix] + if clause[:prefix] && SUPPORTED_PREFIXES.include?(prefix) PrefixClause.new(prefix, operator, clause[:term].to_s, current_account: current_account) + elsif clause[:prefix] + TermClause.new(operator, "#{prefix} #{clause[:term]}") elsif clause[:term] - TermClause.new(prefix, operator, clause[:term].to_s) + TermClause.new(operator, clause[:term].to_s) elsif clause[:shortcode] - TermClause.new(prefix, operator, ":#{clause[:term]}:") + TermClause.new(operator, ":#{clause[:term]}:") elsif clause[:phrase] - PhraseClause.new(prefix, operator, clause[:phrase].is_a?(Array) ? clause[:phrase].map { |p| p[:term].to_s }.join(' ') : clause[:phrase].to_s) + PhraseClause.new(operator, clause[:phrase].is_a?(Array) ? clause[:phrase].map { |p| p[:term].to_s }.join(' ') : clause[:phrase].to_s) else raise "Unexpected clause type: #{clause}" end end - rule(query: sequence(:clauses)) { Query.new(clauses) } + rule(junk: subtree(:junk)) do + nil + end + + rule(query: sequence(:clauses)) do + Query.new(clauses) + end end diff --git a/spec/lib/search_query_parser_spec.rb b/spec/lib/search_query_parser_spec.rb new file mode 100644 index 0000000000..66b0e8f9e2 --- /dev/null +++ b/spec/lib/search_query_parser_spec.rb @@ -0,0 +1,98 @@ +# frozen_string_literal: true + +require 'rails_helper' +require 'parslet/rig/rspec' + +describe SearchQueryParser do + let(:parser) { described_class.new } + + context 'with term' do + it 'consumes "hello"' do + expect(parser.term).to parse('hello') + end + end + + context 'with prefix' do + it 'consumes "foo:"' do + expect(parser.prefix).to parse('foo:') + end + end + + context 'with operator' do + it 'consumes "+"' do + expect(parser.operator).to parse('+') + end + + it 'consumes "-"' do + expect(parser.operator).to parse('-') + end + end + + context 'with shortcode' do + it 'consumes ":foo:"' do + expect(parser.shortcode).to parse(':foo:') + end + end + + context 'with phrase' do + it 'consumes "hello world"' do + expect(parser.phrase).to parse('"hello world"') + end + end + + context 'with clause' do + it 'consumes "foo"' do + expect(parser.clause).to parse('foo') + end + + it 'consumes "-foo"' do + expect(parser.clause).to parse('-foo') + end + + it 'consumes "foo:bar"' do + expect(parser.clause).to parse('foo:bar') + end + + it 'consumes "-foo:bar"' do + expect(parser.clause).to parse('-foo:bar') + end + + it 'consumes \'foo:"hello world"\'' do + expect(parser.clause).to parse('foo:"hello world"') + end + + it 'consumes \'-foo:"hello world"\'' do + expect(parser.clause).to parse('-foo:"hello world"') + end + + it 'consumes "foo:"' do + expect(parser.clause).to parse('foo:') + end + + it 'consumes \'"\'' do + expect(parser.clause).to parse('"') + end + end + + context 'with query' do + it 'consumes "hello -world"' do + expect(parser.query).to parse('hello -world') + end + + it 'consumes \'foo "hello world"\'' do + expect(parser.query).to parse('foo "hello world"') + end + + it 'consumes "foo:bar hello"' do + expect(parser.query).to parse('foo:bar hello') + end + + it 'consumes \'"hello" world "\'' do + expect(parser.query).to parse('"hello" world "') + end + + it 'consumes "foo:bar bar: hello"' do + expect(parser.query).to parse('foo:bar bar: hello') + end + end +end diff --git a/spec/lib/search_query_transformer_spec.rb b/spec/lib/search_query_transformer_spec.rb index 953f9acb2f..17f06d2833 100644 --- a/spec/lib/search_query_transformer_spec.rb +++ b/spec/lib/search_query_transformer_spec.rb @@ -3,16 +3,57 @@ require 'rails_helper' describe SearchQueryTransformer do - describe 'initialization' do - let(:parser) { SearchQueryParser.new.parse('query') } + subject { described_class.new.apply(parser, current_account: nil) } - it 'sets attributes' do - transformer = described_class.new.apply(parser) + let(:parser) { SearchQueryParser.new.parse(query) } - expect(transformer.should_clauses.first).to be_nil - expect(transformer.must_clauses.first).to be_a(SearchQueryTransformer::TermClause) - expect(transformer.must_not_clauses.first).to be_nil - expect(transformer.filter_clauses.first).to be_nil + context 'with "hello world"' do + let(:query) { 'hello world' } + + it 'transforms clauses' do + expect(subject.must_clauses.map(&:term)).to match_array %w(hello world) + expect(subject.must_not_clauses).to be_empty + expect(subject.filter_clauses).to be_empty + end + end + + context 'with "hello -world"' do + let(:query) { 'hello -world' } + + it 'transforms clauses' do + expect(subject.must_clauses.map(&:term)).to match_array %w(hello) + expect(subject.must_not_clauses.map(&:term)).to match_array %w(world) + expect(subject.filter_clauses).to be_empty + end + end + + context 'with "hello is:reply"' do + let(:query) { 'hello is:reply' } + + it 'transforms clauses' do + expect(subject.must_clauses.map(&:term)).to match_array %w(hello) + expect(subject.must_not_clauses).to be_empty + expect(subject.filter_clauses.map(&:term)).to match_array %w(reply) + end + end + + context 'with "foo: bar"' do + let(:query) { 'foo: bar' } + + it 'transforms clauses' do + expect(subject.must_clauses.map(&:term)).to match_array %w(foo bar) + expect(subject.must_not_clauses).to be_empty + expect(subject.filter_clauses).to be_empty + end + end + + context 'with "foo:bar"' do + let(:query) { 'foo:bar' } + + it 'transforms clauses' do + expect(subject.must_clauses.map(&:term)).to contain_exactly('foo bar') + expect(subject.must_not_clauses).to be_empty + expect(subject.filter_clauses).to be_empty end end end From 630e558677d961e74ce82ab5e2a62a0760bbe815 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 1 Sep 2023 10:17:08 +0200 Subject: [PATCH 59/65] Update dependency oj to v3.16.1 (#26749) 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 f1a61c5e09..6dd8c567f8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -482,7 +482,7 @@ GEM nokogiri (1.15.4) mini_portile2 (~> 2.8.2) racc (~> 1.4) - oj (3.16.0) + oj (3.16.1) omniauth (2.1.1) hashie (>= 3.4.6) rack (>= 2.2.3) From 3cf08a8f4bd3f07c984beb4ed9ce8de6c8e71690 Mon Sep 17 00:00:00 2001 From: KMY Date: Fri, 1 Sep 2023 17:30:08 +0900 Subject: [PATCH 60/65] Add translatable_private setting --- app/javascript/mastodon/components/status_content.jsx | 7 ++++++- app/models/account.rb | 5 +++++ app/models/concerns/has_user_settings.rb | 4 ++++ app/models/user_settings.rb | 1 + app/services/translate_status_service.rb | 2 +- app/views/settings/preferences/other/show.html.haml | 6 ++++++ config/locales/simple_form.en.yml | 1 + config/locales/simple_form.ja.yml | 1 + 8 files changed, 25 insertions(+), 2 deletions(-) diff --git a/app/javascript/mastodon/components/status_content.jsx b/app/javascript/mastodon/components/status_content.jsx index f4ae93f80d..55447a6197 100644 --- a/app/javascript/mastodon/components/status_content.jsx +++ b/app/javascript/mastodon/components/status_content.jsx @@ -241,7 +241,12 @@ class StatusContent extends PureComponent { const renderReadMore = this.props.onClick && status.get('collapsed'); const contentLocale = intl.locale.replace(/[_-].*/, ''); const targetLanguages = this.props.languages?.get(status.get('language') || 'und'); - const renderTranslate = this.props.onTranslate && this.context.identity.signedIn && ['public', 'unlisted'].includes(status.get('visibility')) && status.get('search_index').trim().length > 0 && status.get('language') && targetLanguages?.includes(contentLocale); + const renderTranslate = this.props.onTranslate && + this.context.identity.signedIn && + (['public', 'unlisted'].includes(status.get('visibility')) || status.getIn(['account', 'other_settings', 'translatable_private'])) && + status.get('search_index').trim().length > 0 && + status.get('language') && + targetLanguages?.includes(contentLocale); const content = { __html: statusContent ?? getStatusContent(status) }; const spoilerContent = { __html: status.getIn(['translation', 'spoilerHtml']) || status.get('spoilerHtml') }; diff --git a/app/models/account.rb b/app/models/account.rb index d2538bb065..f3655c70d1 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -319,6 +319,10 @@ class Account < ApplicationRecord user&.setting_noai || (settings.present? && settings['noai']) || false end + def translatable_private? + user&.setting_translatable_private || (settings.present? && settings['translatable_private']) || false + end + def public_statuses_count hide_statuses_count? ? 0 : statuses_count end @@ -387,6 +391,7 @@ class Account < ApplicationRecord 'emoji_reaction_must_following' => emoji_reactions_must_following?, 'emoji_reaction_must_follower' => emoji_reactions_must_follower?, 'emoji_reaction_deny_from_all' => emoji_reactions_deny_from_all?, + 'translatable_private' => translatable_private?, } config = config.merge(settings) if settings.present? config diff --git a/app/models/concerns/has_user_settings.rb b/app/models/concerns/has_user_settings.rb index dfb37c3517..17ab1c2c1b 100644 --- a/app/models/concerns/has_user_settings.rb +++ b/app/models/concerns/has_user_settings.rb @@ -99,6 +99,10 @@ module HasUserSettings settings['noai'] end + def setting_translatable_private + settings['translatable_private'] + end + def setting_hide_statuses_count settings['hide_statuses_count'] end diff --git a/app/models/user_settings.rb b/app/models/user_settings.rb index 32bfa563cd..1db8c53f7f 100644 --- a/app/models/user_settings.rb +++ b/app/models/user_settings.rb @@ -12,6 +12,7 @@ class UserSettings setting :theme, default: -> { ::Setting.theme } setting :noindex, default: -> { ::Setting.noindex } setting :noai, default: true + setting :translatable_private, default: false setting :bio_markdown, default: false setting :discoverable_local, default: false setting :hide_statuses_count, default: false diff --git a/app/services/translate_status_service.rb b/app/services/translate_status_service.rb index c2b40433ed..4bc99c8b3c 100644 --- a/app/services/translate_status_service.rb +++ b/app/services/translate_status_service.rb @@ -30,7 +30,7 @@ class TranslateStatusService < BaseService end def permitted? - return false unless @status.distributable? && TranslationService.configured? + return false unless (@status.distributable? || @status.account.translatable_private?) && TranslationService.configured? languages[@status.language]&.include?(@target_language) end diff --git a/app/views/settings/preferences/other/show.html.haml b/app/views/settings/preferences/other/show.html.haml index 99c3e0b2bc..a01bce556c 100644 --- a/app/views/settings/preferences/other/show.html.haml +++ b/app/views/settings/preferences/other/show.html.haml @@ -11,6 +11,12 @@ .fields-group = ff.input :aggregate_reblogs, wrapper: :with_label, recommended: true, label: I18n.t('simple_form.labels.defaults.setting_aggregate_reblogs'), hint: I18n.t('simple_form.hints.defaults.setting_aggregate_reblogs') + .fields-group + = ff.input :noai, wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_noai'), hint: I18n.t('simple_form.hints.defaults.setting_noai') + + .fields-group + = ff.input :translatable_private, wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_translatable_private') + %h4= t 'preferences.posting_defaults' .fields-row diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index 88d9ded9d5..b6a70352b2 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -253,6 +253,7 @@ en: setting_stop_emoji_reaction_streaming: Disable stamp streamings setting_system_font_ui: Use system's default font setting_theme: Site theme + setting_translatable_private: Allow other users translation of your private posts setting_trends: Show today's trends setting_unfollow_modal: Show confirmation dialog before unfollowing someone setting_unsafe_limited_distribution: Send limit posts with unsafe way to other servers diff --git a/config/locales/simple_form.ja.yml b/config/locales/simple_form.ja.yml index 05e27f62a3..28ac8994c4 100644 --- a/config/locales/simple_form.ja.yml +++ b/config/locales/simple_form.ja.yml @@ -263,6 +263,7 @@ ja: setting_stop_emoji_reaction_streaming: スタンプのストリーミングを停止する setting_system_font_ui: システムのデフォルトフォントを使う setting_theme: サイトテーマ + setting_translatable_private: 非公開投稿の翻訳を許可する setting_trends: 本日のトレンドタグを表示する setting_unfollow_modal: フォローを解除する前に確認ダイアログを表示する setting_unsafe_limited_distribution: 安全でない方法で限定投稿を他サーバーに配信する (非推奨) From e5df772adbe8839fde09233d86b71fe60222e5cb Mon Sep 17 00:00:00 2001 From: KMY Date: Fri, 1 Sep 2023 17:44:48 +0900 Subject: [PATCH 61/65] Remove unusing settings from other_settings --- app/models/account.rb | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/app/models/account.rb b/app/models/account.rb index f3655c70d1..c9a36eb4b7 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -388,11 +388,15 @@ class Account < ApplicationRecord 'hide_statuses_count' => hide_statuses_count?, 'hide_following_count' => hide_following_count?, 'hide_followers_count' => hide_followers_count?, - 'emoji_reaction_must_following' => emoji_reactions_must_following?, - 'emoji_reaction_must_follower' => emoji_reactions_must_follower?, - 'emoji_reaction_deny_from_all' => emoji_reactions_deny_from_all?, 'translatable_private' => translatable_private?, } + if Setting.enable_block_emoji_reaction_settings + config = config.merge({ + 'emoji_reaction_must_following' => emoji_reactions_must_following?, + 'emoji_reaction_must_follower' => emoji_reactions_must_follower?, + 'emoji_reaction_deny_from_all' => emoji_reactions_deny_from_all?, + }) + end config = config.merge(settings) if settings.present? config end From bb0edb178f56a488017071e00a994c9033267ef9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 1 Sep 2023 10:48:49 +0200 Subject: [PATCH 62/65] Update dependency pg to v1.5.4 (#26750) 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 6dd8c567f8..4e30c42222 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -519,7 +519,7 @@ GEM parslet (2.0.0) pastel (0.8.0) tty-color (~> 0.5) - pg (1.5.3) + pg (1.5.4) pghero (3.3.3) activerecord (>= 6) posix-spawn (0.3.15) From bd87415996b4b827e41cc2d62bfaa8e36dc694b0 Mon Sep 17 00:00:00 2001 From: KMY Date: Sun, 3 Sep 2023 10:27:24 +0900 Subject: [PATCH 63/65] Add link_preview setting --- app/models/account.rb | 8 ++++++++ app/models/concerns/has_user_settings.rb | 4 ++++ app/models/user_settings.rb | 1 + app/services/fetch_link_card_service.rb | 2 +- app/views/settings/preferences/other/show.html.haml | 3 +++ config/locales/simple_form.en.yml | 1 + config/locales/simple_form.ja.yml | 1 + 7 files changed, 19 insertions(+), 1 deletion(-) diff --git a/app/models/account.rb b/app/models/account.rb index c9a36eb4b7..b94f208635 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -323,6 +323,13 @@ class Account < ApplicationRecord user&.setting_translatable_private || (settings.present? && settings['translatable_private']) || false end + def link_preview? + return user.setting_link_preview if local? && user.present? + return settings['link_preview'] if settings.present? && settings.key?('link_preview') + + true + end + def public_statuses_count hide_statuses_count? ? 0 : statuses_count end @@ -389,6 +396,7 @@ class Account < ApplicationRecord 'hide_following_count' => hide_following_count?, 'hide_followers_count' => hide_followers_count?, 'translatable_private' => translatable_private?, + 'link_preview' => link_preview?, } if Setting.enable_block_emoji_reaction_settings config = config.merge({ diff --git a/app/models/concerns/has_user_settings.rb b/app/models/concerns/has_user_settings.rb index 17ab1c2c1b..abc12cfb44 100644 --- a/app/models/concerns/has_user_settings.rb +++ b/app/models/concerns/has_user_settings.rb @@ -103,6 +103,10 @@ module HasUserSettings settings['translatable_private'] end + def setting_link_preview + settings['link_preview'] + end + def setting_hide_statuses_count settings['hide_statuses_count'] end diff --git a/app/models/user_settings.rb b/app/models/user_settings.rb index 1db8c53f7f..802d706191 100644 --- a/app/models/user_settings.rb +++ b/app/models/user_settings.rb @@ -13,6 +13,7 @@ class UserSettings setting :noindex, default: -> { ::Setting.noindex } setting :noai, default: true setting :translatable_private, default: false + setting :link_preview, default: true setting :bio_markdown, default: false setting :discoverable_local, default: false setting :hide_statuses_count, default: false diff --git a/app/services/fetch_link_card_service.rb b/app/services/fetch_link_card_service.rb index 790cf44548..8323c6cdfe 100644 --- a/app/services/fetch_link_card_service.rb +++ b/app/services/fetch_link_card_service.rb @@ -20,7 +20,7 @@ class FetchLinkCardService < BaseService @status = status @original_url = parse_urls - return if @original_url.nil? || @status.preview_cards.any? + return if @original_url.nil? || @status.preview_cards.any? || !@status.account.link_preview? @url = @original_url.to_s diff --git a/app/views/settings/preferences/other/show.html.haml b/app/views/settings/preferences/other/show.html.haml index a01bce556c..788f8ac854 100644 --- a/app/views/settings/preferences/other/show.html.haml +++ b/app/views/settings/preferences/other/show.html.haml @@ -17,6 +17,9 @@ .fields-group = ff.input :translatable_private, wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_translatable_private') + .fields-group + = ff.input :link_preview, wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_link_preview') + %h4= t 'preferences.posting_defaults' .fields-row diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index b6a70352b2..bf2d957c72 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -242,6 +242,7 @@ en: setting_hide_network: Hide your social graph setting_hide_recent_emojis: Hide recent emojis setting_hide_statuses_count: Hide statuses count + setting_link_preview: Generate post link preview card setting_noai: Set noai meta tags setting_public_post_to_unlisted: Convert public post to public unlisted if not using Web app setting_reduce_motion: Reduce motion in animations diff --git a/config/locales/simple_form.ja.yml b/config/locales/simple_form.ja.yml index 28ac8994c4..a1c5c825a7 100644 --- a/config/locales/simple_form.ja.yml +++ b/config/locales/simple_form.ja.yml @@ -251,6 +251,7 @@ ja: setting_hide_network: 繋がりを隠す setting_hide_recent_emojis: 絵文字ピッカーで最近使用した絵文字を隠す(リアクションデッキのみを表示する) setting_hide_statuses_count: 投稿数を隠す + setting_link_preview: リンクのプレビューを生成する setting_stay_privacy: 投稿時に公開範囲を保存する setting_noai: 自分のコンテンツのAI学習利用に対して不快感を表明する setting_public_post_to_unlisted: サードパーティから公開範囲「公開」で投稿した場合、「ローカル公開」に変更する From 9641e0d2c623fde92be6e996df90e1d6586fd906 Mon Sep 17 00:00:00 2001 From: KMY Date: Sun, 3 Sep 2023 10:29:18 +0900 Subject: [PATCH 64/65] Remove additional emoji reaction setting --- app/models/concerns/has_user_settings.rb | 2 +- app/views/settings/preferences/other/show.html.haml | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/app/models/concerns/has_user_settings.rb b/app/models/concerns/has_user_settings.rb index abc12cfb44..62c617f731 100644 --- a/app/models/concerns/has_user_settings.rb +++ b/app/models/concerns/has_user_settings.rb @@ -68,7 +68,7 @@ module HasUserSettings end def setting_emoji_reaction_streaming_notify_impl2 - settings['emoji_reaction_streaming_notify_impl2'] + false end def setting_unfollow_modal diff --git a/app/views/settings/preferences/other/show.html.haml b/app/views/settings/preferences/other/show.html.haml index 788f8ac854..a66d8cc6f6 100644 --- a/app/views/settings/preferences/other/show.html.haml +++ b/app/views/settings/preferences/other/show.html.haml @@ -51,9 +51,6 @@ .fields-group = ff.input :default_sensitive, wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_default_sensitive'), hint: I18n.t('simple_form.hints.defaults.setting_default_sensitive') - .fields-group - = ff.input :emoji_reaction_streaming_notify_impl2, as: :boolean, wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_emoji_reaction_streaming_notify_impl2'), hint: I18n.t('simple_form.hints.defaults.setting_emoji_reaction_streaming_notify_impl2') - %h4= t 'preferences.public_timelines' .fields-group From 0e0e9e383b364a62471184ec7883d9879ee2638b Mon Sep 17 00:00:00 2001 From: KMY Date: Sun, 3 Sep 2023 10:50:12 +0900 Subject: [PATCH 65/65] Add privacy extra settings page --- .../settings/privacy_extra_controller.rb | 27 ++++++++++++++ .../settings/preferences/other/show.html.haml | 15 ++------ app/views/settings/privacy/show.html.haml | 13 ++----- .../settings/privacy_extra/show.html.haml | 36 +++++++++++++++++++ .../shared/_profile_navigation.html.haml | 1 + config/locales/en.yml | 7 ++++ config/locales/ja.yml | 7 +++- config/routes/settings.rb | 1 + 8 files changed, 84 insertions(+), 23 deletions(-) create mode 100644 app/controllers/settings/privacy_extra_controller.rb create mode 100644 app/views/settings/privacy_extra/show.html.haml diff --git a/app/controllers/settings/privacy_extra_controller.rb b/app/controllers/settings/privacy_extra_controller.rb new file mode 100644 index 0000000000..54cedf2c4b --- /dev/null +++ b/app/controllers/settings/privacy_extra_controller.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +class Settings::PrivacyExtraController < Settings::BaseController + before_action :set_account + + def show; end + + def update + if UpdateAccountService.new.call(@account, account_params.except(:settings)) + current_user.update!(settings_attributes: account_params[:settings]) + ActivityPub::UpdateDistributionWorker.perform_async(@account.id) + redirect_to settings_privacy_extra_path, notice: I18n.t('generic.changes_saved_msg') + else + render :show + end + end + + private + + def account_params + params.require(:account).permit(settings: UserSettings.keys) + end + + def set_account + @account = current_account + end +end diff --git a/app/views/settings/preferences/other/show.html.haml b/app/views/settings/preferences/other/show.html.haml index a66d8cc6f6..7bdce84c23 100644 --- a/app/views/settings/preferences/other/show.html.haml +++ b/app/views/settings/preferences/other/show.html.haml @@ -11,15 +11,6 @@ .fields-group = ff.input :aggregate_reblogs, wrapper: :with_label, recommended: true, label: I18n.t('simple_form.labels.defaults.setting_aggregate_reblogs'), hint: I18n.t('simple_form.hints.defaults.setting_aggregate_reblogs') - .fields-group - = ff.input :noai, wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_noai'), hint: I18n.t('simple_form.hints.defaults.setting_noai') - - .fields-group - = ff.input :translatable_private, wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_translatable_private') - - .fields-group - = ff.input :link_preview, wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_link_preview') - %h4= t 'preferences.posting_defaults' .fields-row @@ -40,16 +31,16 @@ = ff.input :stay_privacy, wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_stay_privacy') .fields-group - = ff.input :'web.enable_login_privacy', wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_enable_login_privacy'), hint: false + = ff.input :public_post_to_unlisted, wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_public_post_to_unlisted'), hint: I18n.t('simple_form.hints.defaults.setting_public_post_to_unlisted') .fields-group = ff.input :disallow_unlisted_public_searchability, wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_disallow_unlisted_public_searchability'), hint: I18n.t('simple_form.hints.defaults.setting_disallow_unlisted_public_searchability') .fields-group - = ff.input :public_post_to_unlisted, wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_public_post_to_unlisted'), hint: I18n.t('simple_form.hints.defaults.setting_public_post_to_unlisted') + = ff.input :default_sensitive, wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_default_sensitive'), hint: I18n.t('simple_form.hints.defaults.setting_default_sensitive') .fields-group - = ff.input :default_sensitive, wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_default_sensitive'), hint: I18n.t('simple_form.hints.defaults.setting_default_sensitive') + = ff.input :'web.enable_login_privacy', wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_enable_login_privacy'), hint: false %h4= t 'preferences.public_timelines' diff --git a/app/views/settings/privacy/show.html.haml b/app/views/settings/privacy/show.html.haml index 0bed511a8c..619429392e 100644 --- a/app/views/settings/privacy/show.html.haml +++ b/app/views/settings/privacy/show.html.haml @@ -21,6 +21,9 @@ .fields-group = ff.input :discoverable_local, wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.discoverable_local'), hint: I18n.t('simple_form.hints.defaults.discoverable_local') + .fields-group + = ff.input :noai, wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_noai'), hint: I18n.t('simple_form.hints.defaults.setting_noai') + .fields-group = f.input :dissubscribable, as: :boolean, wrapper: :with_label, kmyblue: true, hint: t('simple_form.hints.defaults.dissubscribable') @@ -54,15 +57,5 @@ .fields-group = ff.input :show_application, wrapper: :with_label - %h4= t 'privacy.stop_deliver' - - %p.lead= t('privacy.stop_deliver_hint_html') - - .fields-group - = ff.input :reject_public_unlisted_subscription, kmyblue: true, as: :boolean, wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_reject_public_unlisted_subscription') - - .fields-group - = ff.input :reject_unlisted_subscription, kmyblue: true, as: :boolean, wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_reject_unlisted_subscription'), hint: I18n.t('simple_form.hints.defaults.setting_reject_unlisted_subscription') - .actions = f.button :button, t('generic.save_changes'), type: :submit diff --git a/app/views/settings/privacy_extra/show.html.haml b/app/views/settings/privacy_extra/show.html.haml new file mode 100644 index 0000000000..53c11f9cdd --- /dev/null +++ b/app/views/settings/privacy_extra/show.html.haml @@ -0,0 +1,36 @@ +- content_for :page_title do + = t('privacy_extra.title') + +- content_for :heading do + %h2= t('settings.profile') + = render partial: 'settings/shared/profile_navigation' + += simple_form_for @account, url: settings_privacy_extra_path, html: { method: :put } do |f| + = render 'shared/error_messages', object: @account + + %p.lead= t('privacy_extra.hint_html') + + %h4= t('privacy_extra.post_processing') + + %p.lead= t('privacy_extra.post_processing_hint_html') + + = f.simple_fields_for :settings, current_user.settings do |ff| + .fields-group + = ff.input :translatable_private, wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_translatable_private') + + .fields-group + = ff.input :link_preview, wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_link_preview') + + %h4= t 'privacy_extra.stop_deliver' + + %p.lead= t('privacy_extra.stop_deliver_hint_html') + + = f.simple_fields_for :settings, current_user.settings do |ff| + .fields-group + = ff.input :reject_public_unlisted_subscription, kmyblue: true, as: :boolean, wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_reject_public_unlisted_subscription') + + .fields-group + = ff.input :reject_unlisted_subscription, kmyblue: true, as: :boolean, wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_reject_unlisted_subscription'), hint: I18n.t('simple_form.hints.defaults.setting_reject_unlisted_subscription') + + .actions + = f.button :button, t('generic.save_changes'), type: :submit diff --git a/app/views/settings/shared/_profile_navigation.html.haml b/app/views/settings/shared/_profile_navigation.html.haml index 3a657c5bde..fb7e80e023 100644 --- a/app/views/settings/shared/_profile_navigation.html.haml +++ b/app/views/settings/shared/_profile_navigation.html.haml @@ -3,5 +3,6 @@ :ruby primary.item :profile, safe_join([fa_icon('user fw'), t('settings.edit_profile')]), settings_profile_path primary.item :privacy, safe_join([fa_icon('lock fw'), t('privacy.title')]), settings_privacy_path + primary.item :privacy_extra, safe_join([fa_icon('lock fw'), t('privacy_extra.title')]), settings_privacy_extra_path primary.item :verification, safe_join([fa_icon('check fw'), t('verification.verification')]), settings_verification_path primary.item :featured_tags, safe_join([fa_icon('hashtag fw'), t('settings.featured_tags')]), settings_featured_tags_path diff --git a/config/locales/en.yml b/config/locales/en.yml index 7a6b70371d..9ac7bce983 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1619,6 +1619,13 @@ en: 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. stop_deliver: Stop delivering title: Privacy and reach + privacy_extra: + hint_html: These settings are kmyblue original. You will receive additional privacy benefits by doing this setting. + post_processing_hint_html: 投稿された情報に対して、システムが追加で行うことができる操作を制御します。これらには、第三者のサイトへあなたの投稿に関する情報の送信を伴う設定も含まれます。 + post_processing: 投稿の処理 + stop_deliver: 配送停止 + stop_deliver_hint_html: Mastodonの投稿を、他のソフトウェアでは自由に検索することができます。Mastodon内で行ったプライバシーの設定は無視され、あなたの投稿が意図しない人に見つかるおそれがあります。ここでは、他のサーバーやソフトウェアであなたの投稿が見つからないようにする設定が可能です。ただしリスクは伴います。 + title: Privacy extra settings privacy_policy: title: Privacy Policy reactions: diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 1962d9af0d..3a88918add 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -1592,9 +1592,14 @@ ja: 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. + title: Privacy and reach + privacy_extra: + hint_html: これらはkmyblue独自のプライバシー設定項目です。この機能を利用することで、あなたは追加の恩恵を受けることができます。なおこれらの設定の一部は他のサーバーにも送信されますが、kmyblue以外で対応が確認されているソフトウェアは現在確認できていません。他のサーバーではこれらの設定は無視されること、ご了承ください。 + post_processing_hint_html: 投稿された情報に対して、システムが追加で行うことができる操作を制御します。これらには、第三者のサイトへあなたの投稿に関する情報の送信を伴う設定も含まれます。 + post_processing: 投稿の処理 stop_deliver: 配送停止 stop_deliver_hint_html: Mastodonの投稿を、他のソフトウェアでは自由に検索することができます。Mastodon内で行ったプライバシーの設定は無視され、あなたの投稿が意図しない人に見つかるおそれがあります。ここでは、他のサーバーやソフトウェアであなたの投稿が見つからないようにする設定が可能です。ただしリスクは伴います。 - title: Privacy and reach + title: プライバシー追加設定 privacy_policy: title: プライバシーポリシー reactions: diff --git a/config/routes/settings.rb b/config/routes/settings.rb index 888fa9ecb5..64c7a5eb5b 100644 --- a/config/routes/settings.rb +++ b/config/routes/settings.rb @@ -62,6 +62,7 @@ namespace :settings do resource :migration, only: [:show, :create] resource :verification, only: :show resource :privacy, only: [:show, :update], controller: 'privacy' + resource :privacy_extra, only: [:show, :update], controller: 'privacy_extra' namespace :migration do resource :redirect, only: [:new, :create, :destroy]