From 30113c85e0cdadaa2475232bfb3ba8794bb2f810 Mon Sep 17 00:00:00 2001 From: Carlo Date: Thu, 25 Jul 2024 18:21:32 +1000 Subject: [PATCH] Squashed commit of the following: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 6be21ae8ac9b910677e983c25a6154b4ed905823 Author: Claire Date: Wed Jul 24 22:35:39 2024 +0200 Fix double indent for post attachments and metadata in grouped notifications (#2793) commit 0adf31c007cf66474041940bee2b53cdd42c984f Merge: 44caf314b8 2919d8b097 Author: Claire Date: Wed Jul 24 22:34:01 2024 +0200 Merge pull request #2794 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to e507d17520facdba0375791c5530485abe9f59ee commit 2919d8b0979f0da5467105fb311212acf15a24ac Author: Michael Stanclift Date: Tue Jul 23 10:30:45 2024 -0500 [Glitch] Recolor Preferences/Admin UI to better match main design Port 8b7f93cc7fa7a8421ceddeaa79e487360a4ad223 to glitch-soc Signed-off-by: Claire commit d999fc52ba7f7ce10d1320b081231eae37965e71 Merge: 44caf314b8 06f070d86d Author: Claire Date: Wed Jul 24 20:07:37 2024 +0200 Merge commit '06f070d86d448b97c082c038220becaec8a038ce' into glitch-soc/merge-upstream commit 44caf314b8727980dc7bf236e517a30dfe13a37e Merge: 2656381656 e507d17520 Author: Claire Date: Wed Jul 24 20:07:23 2024 +0200 Merge pull request #2791 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to cd0ca4b99473f54464e5134f91b7b1c8d5544011 commit 06f070d86d448b97c082c038220becaec8a038ce Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Wed Jul 24 10:13:09 2024 +0200 fix(deps): update dependency fuzzysort to v3 (#30315) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Renaud Chaput commit e507d17520facdba0375791c5530485abe9f59ee Author: Claire Date: Tue Jul 23 14:11:08 2024 +0200 [Glitch] Widen the clickable area for statuses in grouped notifications Port a8330be93ee825948a17c810af33e28bfa2c56c8 to glitch-soc Signed-off-by: Claire commit 977337f2d245a617b970021379189555e8e1edb9 Author: Nick Schonning Date: Tue Jul 23 02:46:09 2024 -0400 [Glitch] Update Prettier to 3.3.3 Port 9a015a2a157b43ea63d911327248635e629a72c9 to glitch-soc Signed-off-by: Claire commit 838ea5f9cdac103a6f5cc9f63c35315f8985eeb1 Author: Claire Date: Tue Jul 23 08:20:17 2024 +0200 [Glitch] Fix keyboard shortcuts and navigation in grouped notifications Port af06d74574745deb738e6f526f4d74c31760102d to glitch-soc Signed-off-by: Claire commit 68000956f4b43123383f121506a1fbec5a3d2aa2 Merge: 2656381656 cd0ca4b994 Author: Claire Date: Tue Jul 23 19:31:23 2024 +0200 Merge commit 'cd0ca4b99473f54464e5134f91b7b1c8d5544011' into glitch-soc/merge-upstream commit 8b7f93cc7fa7a8421ceddeaa79e487360a4ad223 Author: Michael Stanclift Date: Tue Jul 23 10:30:45 2024 -0500 Recolor Preferences/Admin UI to better match main design (#31034) commit cd0ca4b99473f54464e5134f91b7b1c8d5544011 Author: Adam Niedzielski Date: Tue Jul 23 16:42:31 2024 +0200 Select correct self link when parsing Webfinger response (#31110) commit a8330be93ee825948a17c810af33e28bfa2c56c8 Author: Claire Date: Tue Jul 23 14:11:08 2024 +0200 Widen the clickable area for statuses in grouped notifications (#31111) commit 2656381656350ccc0fd2e3dc4afd605e696c307f Merge: ddc1f7ee44 cbf25634a9 Author: Claire Date: Tue Jul 23 14:03:56 2024 +0200 Merge pull request #2789 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to 55705d8191f31c1089095956fb4124f7505b4bd7 commit 871b6197df0be1be9ea597163b8cac0740a8b9e2 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Tue Jul 23 10:59:18 2024 +0200 chore(deps): update dependency public_suffix to v6.0.1 (#31109) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit bb2e5a4b585875b85f5025a9124b9b476b408c25 Author: Emelia Smith Date: Tue Jul 23 10:12:30 2024 +0200 Add audit logs to Admin::InstancesController (#27386) commit 1b839d2cbab2acf6730c73ee7250c4f436cf8489 Author: Matt Jankowski Date: Tue Jul 23 02:51:57 2024 -0400 Fix `mastodon:stats` decoration of stats rake task (#31104) commit 9a015a2a157b43ea63d911327248635e629a72c9 Author: Nick Schonning Date: Tue Jul 23 02:46:09 2024 -0400 Update Prettier to 3.3.3 (#31106) commit 44bdfe1fed87c77be49b948d9b7ec334558c4c85 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Tue Jul 23 08:42:28 2024 +0200 chore(deps): update dependency opentelemetry-instrumentation-active_job to v0.7.3 (#31107) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit af06d74574745deb738e6f526f4d74c31760102d Author: Claire Date: Tue Jul 23 08:20:17 2024 +0200 Fix keyboard shortcuts and navigation in grouped notifications (#31076) commit cbf25634a9144bb6420fb0350d7ea64bed4f763f Author: Claire Date: Mon Jul 22 21:30:06 2024 +0200 [Glitch] Fix reblogging after refactor Port 55705d8191f31c1089095956fb4124f7505b4bd7 to glitch-soc Signed-off-by: Claire commit 643b1ef3e97684da49879f9ca7e8781b2f1b3b00 Author: Claire Date: Mon Jul 22 18:03:58 2024 +0200 [Glitch] Refactor CW handling in an action Port 9cb94271333ccfe488fa84d49e3351f18594e480 to glitch-soc Signed-off-by: Claire commit f13a231b3980f76fc5b105ac8e430599df19e956 Author: Claire Date: Mon Jul 22 17:45:07 2024 +0200 [Glitch] Refactor code for reblogging and favouriting Port 03dea64b794f3e6cd1e03df72578ed0004a4d84c to glitch-soc Signed-off-by: Claire commit dcfcfdcb14e86efe48ab3fa670cb586b341f4384 Merge: ddc1f7ee44 55705d8191 Author: Claire Date: Mon Jul 22 21:41:31 2024 +0200 Merge commit '55705d8191f31c1089095956fb4124f7505b4bd7' into glitch-soc/merge-upstream commit 55705d8191f31c1089095956fb4124f7505b4bd7 Author: Claire Date: Mon Jul 22 21:30:06 2024 +0200 Fix reblogging after refactor (#31105) commit ddc1f7ee44c3058e7b8430145e88660f4cc9bdc9 Merge: c72b6e03ec 2aac73341a Author: Claire Date: Mon Jul 22 19:38:53 2024 +0200 Merge pull request #2788 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to 80d9bff6df137afc3376f47b62d10a2e3e9456e2 commit 9cb94271333ccfe488fa84d49e3351f18594e480 Author: Claire Date: Mon Jul 22 18:03:58 2024 +0200 Refactor CW handling in an action (#31103) commit 03dea64b794f3e6cd1e03df72578ed0004a4d84c Author: Claire Date: Mon Jul 22 17:45:07 2024 +0200 Refactor code for reblogging and favouriting (#31102) commit 2aac73341a91e61d0b12a2a0272d64500614066e Merge: c72b6e03ec 80d9bff6df Author: Claire Date: Mon Jul 22 17:38:30 2024 +0200 Merge commit '80d9bff6df137afc3376f47b62d10a2e3e9456e2' into glitch-soc/merge-upstream Conflicts: - `app/services/backup_service.rb`: Conflict due to glitch-soc's local-only posts. Ported upstream's changes while keeping glitch-soc's feature. commit 80d9bff6df137afc3376f47b62d10a2e3e9456e2 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jul 22 15:39:37 2024 +0200 fix(deps): update dependency immutable to v4.3.7 (#31100) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit ced5e853c7d7c7f2b849d904964ef92e93ad27c8 Author: Claire Date: Mon Jul 22 10:56:05 2024 +0200 Fix duplicate `orderedItems` in user archive's `outbox.json` (#31099) commit 6e4305de69bb3356d5d0038611052490527d3325 Author: Matt Jankowski Date: Mon Jul 22 04:02:31 2024 -0400 Fix spec descriptions around configurable limit values (#31079) commit 5a60a3b80c8fe1769ba737a286169636476e686c Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon Jul 22 10:01:24 2024 +0200 New Crowdin Translations (automated) (#31087) Co-authored-by: GitHub Actions commit ef796446e5b0827bc73a27d573b930b27efef579 Author: Matt Jankowski Date: Mon Jul 22 03:46:41 2024 -0400 Ignore manifest JS parse/interrupt error on CI (#31080) commit 6ee5d3b5591d96c492035274e4668cfa7891fe70 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jul 22 09:39:56 2024 +0200 fix(deps): update dependency jsdom to v24.1.1 (#31088) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 22d2fba2790e258096334d13e4688ae7810ebb4f Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jul 22 07:39:38 2024 +0000 chore(deps): update definitelytyped types (non-major) (#31095) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 77ec5e11e4385546e9b10c597c0b40002a809082 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jul 22 07:38:52 2024 +0000 chore(deps): update dependency email_spec to v2.3.0 (#31097) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 2774980589fd5d95a2a812527c269a4368e6889e Author: Claire Date: Mon Jul 22 09:37:27 2024 +0200 Fix syntax error in grouped notifications CTE on some PostgreSQL versions (#31098) commit c72b6e03ec6b4042dbf958a979b02cc6870128a9 Merge: 2e63e802b3 95984b729a Author: Claire Date: Fri Jul 19 18:57:05 2024 +0200 Merge pull request #2786 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to 0397df9bef82042221f35e9938ad5b917fa1d4fc commit 95984b729a8465da36c51182e0fe5a8e518475cb Author: Claire Date: Fri Jul 19 17:26:44 2024 +0200 [Glitch] Remove routerHistory parameters from composer actions Port e768b23aa995130c14a7160165eabcf1e8570dfd to glitch-soc Signed-off-by: Claire commit 9f05a06dee264a80827a03569664931f8d443588 Author: Michael Stanclift Date: Fri Jul 19 03:30:26 2024 -0500 [Glitch] Fix double border on column filter on narrow screens Port 784e0885333769b47c8a94fde0c34bb14b1b93bb to glitch-soc Signed-off-by: Claire commit f7598b267bf952392d8125d8a60bcdb977510ddd Merge: 2e63e802b3 0397df9bef Author: Claire Date: Fri Jul 19 17:45:19 2024 +0200 Merge commit '0397df9bef82042221f35e9938ad5b917fa1d4fc' into glitch-soc/merge-upstream commit 0397df9bef82042221f35e9938ad5b917fa1d4fc Author: Matt Jankowski Date: Fri Jul 19 11:32:42 2024 -0400 Resolve `TODO` in `api/v1/admin/domain_*` controllers (#31067) commit 65a8dc7869360bd4e4fb45d876f7a2bd019d16c8 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri Jul 19 17:32:06 2024 +0200 chore(deps): update dependency selenium-webdriver to v4.23.0 (#31073) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 3a00f89aa1f2280b995512cd5f91568e6d349cc6 Author: kyori19 Date: Sat Jul 20 00:31:48 2024 +0900 Respect `Account::DISPLAY_NAME_LENGTH_LIMIT` in account spec correctly (#31075) commit e768b23aa995130c14a7160165eabcf1e8570dfd Author: Claire Date: Fri Jul 19 17:26:44 2024 +0200 Remove routerHistory parameters from composer actions (#31077) commit 2e63e802b32599537d80f524628a5affeb089df5 Author: Claire Date: Fri Jul 19 12:13:50 2024 +0200 Fix inconsistent padding in glitch-soc's grouped notifications (#2784) commit adadfdbc0355d9195815d25ad22fdee96e13ce6c Author: Matt Jankowski Date: Fri Jul 19 04:32:43 2024 -0400 Update `strong_migrations` to version 2.0.0 (#31061) commit 05342529dd5ecdd6a737451f5c3ca55de24af3e9 Author: Matt Jankowski Date: Fri Jul 19 04:31:34 2024 -0400 Reduce factory creation in AP activity move spec (#31064) commit 784e0885333769b47c8a94fde0c34bb14b1b93bb Author: Michael Stanclift Date: Fri Jul 19 03:30:26 2024 -0500 Fix double border on column filter on narrow screens (#31068) commit 8e0aed8ac73dda2138a71a090e1560ace9b9bcf1 Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri Jul 19 10:21:09 2024 +0200 New Crowdin Translations (automated) (#31072) Co-authored-by: GitHub Actions commit d55ecf4145c84c4b4e6a093f01bd84b24d0fc804 Merge: fb29f40a28 7224e24054 Author: Claire Date: Thu Jul 18 20:42:27 2024 +0200 Merge pull request #2782 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to 82344342c1c5adb3f6a4b376559db737a9e982b7 commit 7224e2405413b816b2fbc171a9a9e7b86bae0261 Author: Renaud Chaput Date: Thu Jul 18 16:36:09 2024 +0200 [Glitch] Grouped Notifications UI Port f587ff643f552a32a1c43e103a474a5065cd3657 to glitch-soc Co-authored-by: Eugen Rochko Co-authored-by: Claire Signed-off-by: Claire commit c75fe09e2b1283c600591d76918921a71ceae989 Merge: fb29f40a28 82344342c1 Author: Claire Date: Thu Jul 18 17:56:25 2024 +0200 Merge commit '82344342c1c5adb3f6a4b376559db737a9e982b7' into glitch-soc/merge-upstream commit 82344342c1c5adb3f6a4b376559db737a9e982b7 Author: Matt Jankowski Date: Thu Jul 18 11:45:40 2024 -0400 Add link to org-level contribution guidelines to contributing doc (#31043) commit 848b59c8ae366895eb690a062698bd8f653e5959 Author: Matt Jankowski Date: Thu Jul 18 11:23:46 2024 -0400 Reduce factory creation in `MediaAttachment` model spec (#31058) commit 41b7281b56ea64b13fdf07d5ce7efadcbe65bd1c Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Thu Jul 18 17:23:43 2024 +0200 fix(deps): update dependency use-debounce to v10.0.1 (#31060) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 6e47637dd4f93169ec783c01f4f9b4dfb7cb66ce Author: Claire Date: Thu Jul 18 17:23:40 2024 +0200 Fix grouping across hourly buckets happening in a 12 seconds window instead of 12 hours window (#31062) commit f587ff643f552a32a1c43e103a474a5065cd3657 Author: Renaud Chaput Date: Thu Jul 18 16:36:09 2024 +0200 Grouped Notifications UI (#30440) Co-authored-by: Eugen Rochko Co-authored-by: Claire commit 7d090b2ab6a76676c861f737c3b6922da8c1292b Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu Jul 18 10:00:29 2024 +0200 New Crowdin Translations (automated) (#31055) Co-authored-by: GitHub Actions commit 47ea83d2469e461b82e6d837ea83ad561128fe7a Author: Matt Jankowski Date: Thu Jul 18 04:00:19 2024 -0400 Reduce factory creation in `AP::ProcessStatusUpdateService` spec (#31051) commit 64c7ffdc656135b7986ce92d645f5355f638cfe4 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Thu Jul 18 09:53:36 2024 +0200 chore(deps): update dependency ruby-vips to v2.2.2 (#31050) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 2616fde9e6edfbdbf31efad5d1818ad950ab4d4c Author: Matt Jankowski Date: Thu Jul 18 03:49:44 2024 -0400 Use change-requiring records in admin/reports controller spec (#31052) commit c5f8256801c8c840becf0ea7201bb891adf3c35a Author: Matt Jankowski Date: Thu Jul 18 03:45:59 2024 -0400 Reduce extra factories in `FanOutOnWriteService` spec (#31053) commit fb29f40a288b742f4724d50b9d47b800b43aadbb Merge: d6a2635a77 5e7720d11b Author: Claire Date: Wed Jul 17 22:42:32 2024 +0200 Merge pull request #2781 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream up to aa4d8987a00fe82490fb949b82d3baa33d0acd49 commit 5e7720d11bf0dab1be352be0de32598aec0c2c81 Merge: d6a2635a77 aa4d8987a0 Author: Claire Date: Wed Jul 17 22:20:12 2024 +0200 Merge commit 'aa4d8987a00fe82490fb949b82d3baa33d0acd49' into glitch-soc/merge-upstream commit aa4d8987a00fe82490fb949b82d3baa33d0acd49 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Wed Jul 17 12:42:54 2024 +0200 chore(deps): update dependency faker to v3.4.2 (#31046) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 4957771a8ae36e46cba4b8c4a6278f0e95e5850a Author: Claire Date: Wed Jul 17 11:18:25 2024 +0200 Update rexml to version 3.3.2 (#31048) commit 76c2c5c748ba47c2b7bc13570cd4301516290d90 Author: Matt Jankowski Date: Wed Jul 17 04:09:34 2024 -0400 Reduce extra round trips in `activitypub` controller specs (#31041) commit f5e90f3de3efa52c9f8ea72ffdbf091d5032cc4b Author: Matt Jankowski Date: Wed Jul 17 03:33:08 2024 -0400 Reduce extra round trips in `AP::SynchronizeFollowersService` spec (#31044) commit 81877e79505f387284c7a9de88f631eab758a319 Author: Matt Jankowski Date: Wed Jul 17 03:24:14 2024 -0400 Reduce extra round trips in `AP::FetchRemoteStatusService` spec (#31045) commit 00c110ac7ba0dd82840f1ff32113ed0e616c3470 Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed Jul 17 09:23:07 2024 +0200 New Crowdin Translations (automated) (#31047) Co-authored-by: GitHub Actions commit d6a2635a774248520e1affd58d3317b0dd72ab48 Merge: b7b6f1c89a c546757cd1 Author: Claire Date: Tue Jul 16 18:51:02 2024 +0200 Merge pull request #2780 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to 66430cb25c824cfad0394216d8e7a523533bcf4b commit c546757cd1c93a4b34b232e9f911b06ffe0e326a Merge: b7b6f1c89a 66430cb25c Author: Claire Date: Tue Jul 16 17:54:36 2024 +0200 Merge commit '66430cb25c824cfad0394216d8e7a523533bcf4b' into glitch-soc/merge-upstream commit 66430cb25c824cfad0394216d8e7a523533bcf4b Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue Jul 16 17:24:56 2024 +0200 New Crowdin Translations (automated) (#31038) Co-authored-by: GitHub Actions commit a609940ec9a370a18789ad87532a098fe6e564c9 Author: Adam Niedzielski Date: Tue Jul 16 15:23:26 2024 +0200 Fix test description in hashtag_bar (#30827) commit aa88aca0ad89f24fead6a1c6dbfad9def94bd47e Author: Emelia Smith Date: Tue Jul 16 15:23:08 2024 +0200 Add optional OAuth application to reports (#30539) commit fa54b6121691dfb5d64a42aa6bf07b4d67aa504f Author: Adam Niedzielski Date: Tue Jul 16 15:21:16 2024 +0200 Handle missing links in Webfinger response (#31030) commit c27d194eb27aeedb16e17dfb2a8f2be7c0636851 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Tue Jul 16 15:20:34 2024 +0200 fix(deps): update dependency pino to v9.3.1 (#31032) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit c3a2f9d99309bbe2754be9ea3f5257c434ff34b0 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Tue Jul 16 14:14:25 2024 +0200 chore(deps): update dependency json-schema to v4.3.1 (#31012) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 905921b2efaa7bda5acca1c19056a18186ec24ff Author: Michael Stanclift Date: Tue Jul 16 02:06:19 2024 -0500 Add missing "Update Report" string in audit log (#31033) commit b7b6f1c89a001a004ca97937d8f43a4555159b31 Merge: d329eda295 70969ac64c Author: Claire Date: Mon Jul 15 19:35:20 2024 +0200 Merge pull request #2777 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to 9d0bce40724eb77b7cc3917091b62e4ab159e29e commit 70969ac64c4cf2811be9aa2f8510e3d831f2533c Author: David Roetzel Date: Mon Jul 15 15:42:47 2024 +0200 [Glitch] Move filtered notifications bar in scrollable area Port 9d0bce40724eb77b7cc3917091b62e4ab159e29e to glitch-soc Co-authored-by: Claire Signed-off-by: Claire commit 64b2c712d4318445716a1f3f6e77fd005d07a7d9 Merge: d329eda295 9d0bce4072 Author: Claire Date: Mon Jul 15 18:51:38 2024 +0200 Merge commit '9d0bce40724eb77b7cc3917091b62e4ab159e29e' into glitch-soc/merge-upstream Conflicts: - `app/helpers/theme_helper.rb`: Conflict because upstream refactored theme-related code, and glitch-soc has a different theming system. commit 9d0bce40724eb77b7cc3917091b62e4ab159e29e Author: David Roetzel Date: Mon Jul 15 15:42:47 2024 +0200 Move filtered notifications bar in scrollable area (#30996) Co-authored-by: Claire commit 0b97ec3f7b0922067c1047d621975e65bfe96ad7 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jul 15 15:03:57 2024 +0200 fix(deps): update dependency @babel/core to v7.24.9 (#31029) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 543b59fa14a7e9b55a5a96d2cb0f38391108a561 Author: Matt Jankowski Date: Mon Jul 15 09:03:23 2024 -0400 Clean up `theme_helper` style builders (#30617) commit 91ef4a6fc5d8536378a2d3bc456711bcb95bd8f4 Author: Matt Jankowski Date: Mon Jul 15 06:42:18 2024 -0400 Add assertion about key columns to account key generate spec (#30635) commit 1dd82620712eecc18f1acd72b5a8585d37e254cf Author: Claire Date: Mon Jul 15 11:29:57 2024 +0200 Add optional `filtered` attribute to notification entities in REST API (#31011) commit 17117109adacd5811317b4927594992a9c5ddffb Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon Jul 15 07:44:37 2024 +0000 New Crowdin Translations (automated) (#31018) Co-authored-by: GitHub Actions commit d61b536df30c6368a45fd4750c01322b14011b48 Author: mogaminsk Date: Mon Jul 15 16:38:48 2024 +0900 Add i18n strings for instance favicon and logo settings label (#31016) commit d329eda295dc73a1f2aaf0d412b5ce12314d1fc9 Merge: 54642244ed edec2e9fdf Author: Claire Date: Sun Jul 14 19:40:29 2024 +0200 Merge pull request #2776 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to 00cb4a0313190bfa118966692a649db9c8328094 commit edec2e9fdfdf18ffa5d5591e7ae9d75e94209265 Merge: 54642244ed 00cb4a0313 Author: Claire Date: Sun Jul 14 18:43:35 2024 +0200 Merge commit '00cb4a0313190bfa118966692a649db9c8328094' into glitch-soc/merge-upstream commit 54642244ed0392cc2464ffdb354298549c646f61 Merge: 813f86d6ff 8d2a93b0cb Author: Claire Date: Fri Jul 12 17:14:23 2024 +0200 Merge pull request #2775 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to c929b4cace3f95fe54fdafe449ea7e972c8d61e8 commit 00cb4a0313190bfa118966692a649db9c8328094 Author: Matt Jankowski Date: Fri Jul 12 10:09:16 2024 -0400 Avoid repeated factory creation in media_attachments_vacuum_spec (#31000) commit c953dca1dee71f32b547e68977568cd076a6f7ae Author: Emelia Smith Date: Fri Jul 12 14:23:09 2024 +0200 Streaming: use pgPool.query instead of manually acquiring & releasing a connection (#30964) commit b87c41115e99becdfc8a6a66300b4fc6fe39bf3b Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri Jul 12 14:20:32 2024 +0200 chore(deps): update dependency rubocop-rspec to v3.0.3 (#31009) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 35a437a03f4e1f606afea8953f0be62807da91cc Author: David Roetzel Date: Fri Jul 12 14:09:52 2024 +0200 Destroy `NotificationRequest`s that are dismissed (#31008) commit 8d2a93b0cba756d1fffdbc6f2d2ffa39b571044b Author: Claire Date: Thu Jul 11 21:42:58 2024 +0200 [Glitch] Add setting to disable hover cards Port ad52b04a1c88574ae3be2c56bead1b0638b253fc to glitch-soc Co-authored-by: Eugen Rochko commit 55cf5e0188834680efdc8ea4fa411ddd797ca372 Merge: 813f86d6ff c929b4cace Author: Claire Date: Fri Jul 12 13:41:54 2024 +0200 Merge commit 'c929b4cace3f95fe54fdafe449ea7e972c8d61e8' into glitch-soc/merge-upstream commit c929b4cace3f95fe54fdafe449ea7e972c8d61e8 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri Jul 12 11:29:43 2024 +0200 chore(deps): update dependency pghero to v3.6.0 (#30994) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 9cc0607358dda4e3dd46e7bcee05e6545175f626 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri Jul 12 11:29:10 2024 +0200 chore(deps): update dependency database_cleaner-active_record to v2.2.0 (#31007) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 43e24dbb13f497cf13bf301e40f8790ba5960f2d Author: Matt Jankowski Date: Fri Jul 12 04:30:52 2024 -0400 Use `include_pagination_headers` in more places (#30999) commit 28ad3588e4936f3429e5f062c76c37f50a2f38fb Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri Jul 12 08:25:27 2024 +0000 New Crowdin Translations (automated) (#31006) Co-authored-by: GitHub Actions commit fdad4dc918d0eb8538d79173e86c82fd6d0290a6 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri Jul 12 10:23:04 2024 +0200 fix(deps): update babel monorepo to v7.24.8 (#31002) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit cd1bc94cd2232b2583c6d3d1924fd0ae00f542bc Author: Nick Schonning Date: Fri Jul 12 04:22:31 2024 -0400 Regen RuboCop TODO for 1.65.0 (#31003) commit 73d53827ea3ef1605f97f99bf3cbeeccb30638be Author: Matt Jankowski Date: Fri Jul 12 04:19:15 2024 -0400 Add change assertion to invites destroy spec (#31004) commit bb702e6b2037b5b0f2e76b6f9d390fa0fd7abc54 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri Jul 12 10:18:35 2024 +0200 fix(deps): update dependency sass to v1.77.8 (#31005) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 813f86d6ffaedc0398c7c69e75bbd8af77dd04c6 Merge: 182fee1c45 e26052192d Author: Claire Date: Thu Jul 11 22:57:59 2024 +0200 Merge pull request #2774 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to 8c8bee5a36e0cd0b5d35903f8891896447c3e060 commit ad52b04a1c88574ae3be2c56bead1b0638b253fc Author: Claire Date: Thu Jul 11 21:42:58 2024 +0200 Add setting to disable hover cards (#30931) Co-authored-by: Eugen Rochko commit e26052192d2bc11ef8adb7bb5f9d4d0fcbfc94f4 Author: Renaud Chaput Date: Thu Jul 11 15:43:42 2024 +0200 [Glitch] Change disabled buttons color in light mode to make it more visible Port 8c8bee5a36e0cd0b5d35903f8891896447c3e060 to glitch-soc Signed-off-by: Claire commit db0b12e5dcadf18c266dd2e4baa7e083a5830a3e Merge: 182fee1c45 8c8bee5a36 Author: Claire Date: Thu Jul 11 21:07:03 2024 +0200 Merge commit '8c8bee5a36e0cd0b5d35903f8891896447c3e060' into glitch-soc/merge-upstream commit 8c8bee5a36e0cd0b5d35903f8891896447c3e060 Author: Renaud Chaput Date: Thu Jul 11 15:43:42 2024 +0200 Change disabled buttons color in light mode to make it more visible (#30998) commit 6c375297236ecd1df7a5e82c24ad025b46be46cc Author: Matt Jankowski Date: Thu Jul 11 07:13:55 2024 -0400 Use `module: :auth` to wrap `devise_for` routes config (#30990) commit c244b70dc21f1a41f16588820490082a1e99b7ae Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu Jul 11 10:38:35 2024 +0000 New Crowdin Translations (automated) (#30993) Co-authored-by: GitHub Actions commit 24bdba34132b0a6e193e7246304601a8ad453425 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Thu Jul 11 12:30:55 2024 +0200 chore(deps): update dependency rubocop to v1.65.0 (#30985) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 631a5eec85946848bf0b15562f82260c1f7721d8 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Wed Jul 10 21:59:34 2024 +0200 chore(deps): update dependency charlock_holmes to v0.7.9 (#30992) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 182fee1c454dcd71ecf408ddc2c534bf6ee3a49a Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed Jul 10 18:18:15 2024 +0200 New Crowdin Translations (automated) (#2738) * New Crowdin translations * Fix bogus no.yml * Fix bogus simple_form.no.yml --------- Co-authored-by: GitHub Actions Co-authored-by: Claire commit 5c9c02417a0cde8a0b73d31f5b3f0551f83ab936 Merge: 56e347d149 959ad1d6be Author: Claire Date: Wed Jul 10 18:11:50 2024 +0200 Merge pull request #2772 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to 2ea9336b6855b44126a55106a81e96ea68eaf8ff commit d436696f46814eb4c786e48dec6dd05b4bb5c278 Author: Emelia Smith Date: Wed Jul 10 17:59:18 2024 +0200 Streaming: Fix incorrect type definitions (#30977) commit 959ad1d6be5b84bd55df4e7ad04cc94e824fce5c Author: Claire Date: Wed Jul 10 17:46:33 2024 +0200 Fix deprecation warning in win95 theme commit 0d4a8a53d548aa4db43e52085f85126c2bf543d1 Author: Renaud Chaput Date: Wed Jul 10 14:23:24 2024 +0200 [Glitch] Fix SCSS mixed declarations deprecation Port 182b9248c0e798e4b0fba8339d2817ed2f094b42 to glitch-soc commit 52fb4f16ef561adb79e47e91f803176929d7ace4 Merge: 56e347d149 2ea9336b68 Author: Claire Date: Wed Jul 10 16:58:06 2024 +0200 Merge commit '2ea9336b6855b44126a55106a81e96ea68eaf8ff' into glitch-soc/merge-upstream commit 2ea9336b6855b44126a55106a81e96ea68eaf8ff Author: David Roetzel Date: Wed Jul 10 16:25:39 2024 +0200 Do not pass unknown encoding names to nokogiri. (#30987) commit 36592d10aa497db6c9a9764ee539242cc2cfdec7 Author: Renaud Chaput Date: Wed Jul 10 14:57:25 2024 +0200 Change Sidekiq readiness file to use an environment variable (#30988) commit 182b9248c0e798e4b0fba8339d2817ed2f094b42 Author: Renaud Chaput Date: Wed Jul 10 14:23:24 2024 +0200 Fix SCSS mixed declarations deprecation (#30986) commit 9984fca9a065e49acde0858487bc3cf10a744cea Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed Jul 10 12:40:19 2024 +0200 New Crowdin Translations (automated) (#30983) Co-authored-by: GitHub Actions commit 8dea897a3b2a6be08911515d291eb679dc3cd792 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Wed Jul 10 10:04:52 2024 +0000 chore(deps): update docker.io/ruby docker tag to v3.3.4 (#30980) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit d0137910c61a565cfdaa8cf29d3e15e6345e5066 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Wed Jul 10 12:04:11 2024 +0200 chore(deps): update dependency ruby to v3.3.4 (#30969) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit c9f08f77ed8a262a4db806d814e2701794873a70 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Wed Jul 10 08:55:26 2024 +0200 fix(deps): update dependency sass to v1.77.7 (#30981) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 56e347d1493b81bb8f6c25aef2616cadf327313d Merge: 3e47d01a30 388672ff0d Author: Claire Date: Tue Jul 9 23:20:17 2024 +0200 Merge pull request #2771 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to 967505ee9bcacf0e5189aa06c654ff586c198a46 commit 388672ff0de782350a3b18d5831614dfdefe70a2 Merge: 3e47d01a30 967505ee9b Author: Claire Date: Tue Jul 9 20:39:09 2024 +0200 Merge commit '967505ee9bcacf0e5189aa06c654ff586c198a46' into glitch-soc/merge-upstream commit 967505ee9bcacf0e5189aa06c654ff586c198a46 Author: David Roetzel Date: Tue Jul 9 15:11:34 2024 +0200 Add size limit for all PreviewCard URLs (#30973) commit ef2e48e6dac1ed327fc6ac07b0adf252d10ff607 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Tue Jul 9 14:53:31 2024 +0200 fix(deps): update dependency glob to v10.4.5 (#30972) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 3875bd138d279eb26efce9f446fe91f49cf38f55 Author: Daniel M Brasil Date: Tue Jul 9 09:41:49 2024 -0300 Fix HTTP 500 in `/api/v1/polls/:id/votes` (#25598) commit 7542a134d5fecf82d14dcc1860be87cf6645ec7f Author: Renaud Chaput Date: Tue Jul 9 12:47:08 2024 +0200 Add a file for Sidekiq to signal it is ready to process jobs (#30971) commit 249b4117f9fbdac3888d3807a81c0e83e39d7de5 Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue Jul 9 07:36:13 2024 +0000 New Crowdin Translations (automated) (#30970) Co-authored-by: GitHub Actions commit f47d761e12a16c4338447aa8dbeca8365ee812cc Author: Matt Jankowski Date: Tue Jul 9 03:34:19 2024 -0400 Remove unneeded `controller` option in routes (#30958) commit 7a30c689530c93e8ea473e39cfb2e2ff6d9d2807 Author: Matt Jankowski Date: Tue Jul 9 03:34:15 2024 -0400 Use `scope module: ...` block for `.well-known` routes (#30959) commit 0dd4595704896fecb69315c1617dcb74b1cfaf67 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Tue Jul 9 09:27:13 2024 +0200 fix(deps): update dependency glob to v10.4.4 (#30967) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 3e47d01a3035db72aa8fe4b978d03c671fbd55ec Merge: 69766370fd 80179d53ba Author: Claire Date: Mon Jul 8 22:02:56 2024 +0200 Merge pull request #2770 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to fa8e972722fb8fc056aa348dddaee4005b4a8ac4 commit 80179d53ba825c2c82178a267498311edde077f3 Author: Tianwei Dong Date: Mon Jul 8 09:10:57 2024 +0100 [Glitch] Change to use an unified constant for max media attachments per status Port 36d819bef34279bb36cdfa3ed89711405ad79591 to glitch-soc Co-authored-by: Renaud Chaput Signed-off-by: Claire commit aa8ad92fa423d02991e92cfd571ef7b5393ebbb5 Author: Renaud Chaput Date: Sun Jul 7 18:14:15 2024 +0200 [Glitch] Remove the `title` attribute when hovering a card anchor Port 981395e4d68a1c0cfccbdb8924bc11ac912d1e05 to glitch-soc Signed-off-by: Claire commit 2fa3c3a748a3a647bae2d8fc2d1bf4776871ea8b Author: Renaud Chaput Date: Sun Jul 7 18:13:10 2024 +0200 [Glitch] Add the account hover card for account search results Port 0899c91d4be0e0846caf53a4b065c4904f34d23a to glitch-soc Signed-off-by: Claire commit 6a552329881a896edb27d0eb955baabcb45938da Merge: 69766370fd fa8e972722 Author: Claire Date: Mon Jul 8 19:41:14 2024 +0200 Merge commit 'fa8e972722fb8fc056aa348dddaee4005b4a8ac4' into glitch-soc/merge-upstream commit fa8e972722fb8fc056aa348dddaee4005b4a8ac4 Author: David Roetzel Date: Mon Jul 8 18:04:36 2024 +0200 Fix author names as arrays in linked data. (#30957) commit f1300ad284d8c7877a7406e253cf7558596d9837 Author: Matt Jankowski Date: Mon Jul 8 12:01:08 2024 -0400 Rename jobs/attachments rspec tag names (#29762) commit 79b0e192d9fb06dbf203e05e6f621dc3ef4d8c73 Author: Matt Jankowski Date: Mon Jul 8 04:16:00 2024 -0400 Move test migrations paths check to workflow level (#30702) commit 36d819bef34279bb36cdfa3ed89711405ad79591 Author: Tianwei Dong Date: Mon Jul 8 09:10:57 2024 +0100 Change to use an unified constant for max media attachments per status (#29073) Co-authored-by: Renaud Chaput commit 1a37862a7606058026b1e55b767f38a6f82da504 Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon Jul 8 10:03:44 2024 +0200 New Crowdin Translations (automated) (#30940) Co-authored-by: GitHub Actions commit d41b43ed4fff8ccbee5eac62064c5def14f88973 Author: Claire Date: Mon Jul 8 09:41:50 2024 +0200 Limit attachments to `MEDIA_ATTACHMENTS_LIMIT` when returning posts through the API (#30932) commit fd3bfc0710999923c722222579395e9a3d9e3c73 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jul 8 07:22:28 2024 +0000 fix(deps): update dependency postcss-preset-env to v9.6.0 (#30944) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit c29fdadefdaae5a68f6bea85d6ae3b529b6ab7e7 Author: Matt Jankowski Date: Mon Jul 8 03:21:49 2024 -0400 Use `scope module: ...` for more API routes (#30935) commit bd285cdd02a079b6c1412be04cd28cf759fd0d9d Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jul 8 09:16:47 2024 +0200 fix(deps): update dependency glob to v10.4.3 (#30941) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit bd8481784870b04cd4fda20fa18fdeeb7a07430d Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jul 8 07:15:48 2024 +0000 chore(deps): update dependency irb to v1.14.0 (#30947) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 5c3ec727ecff6fe74b12ae533388dbc28b5061fe Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jul 8 09:11:29 2024 +0200 chore(deps): update dependency typescript to v5.5.3 (#30953) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit c5883e099937971e30eb17f6da3e5e8800523cfa Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jul 8 09:11:15 2024 +0200 chore(deps): update dependency @testing-library/dom to v10.3.1 (#30954) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 981395e4d68a1c0cfccbdb8924bc11ac912d1e05 Author: Renaud Chaput Date: Sun Jul 7 18:14:15 2024 +0200 Remove the `title` attribute when hovering a card anchor (#30948) commit 0899c91d4be0e0846caf53a4b065c4904f34d23a Author: Renaud Chaput Date: Sun Jul 7 18:13:10 2024 +0200 Add the account hover card for account search results (#30949) commit 69766370fd65bb7a48dddfd247e0b22f72409f4f Merge: 05cfe04415 a99ae90d76 Author: Claire Date: Sun Jul 7 15:22:37 2024 +0200 Merge pull request #2768 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to 63ba69810eca80fc2d10114a79f2988c1b75892f commit 1d35626dc7f8422e7b2da9a5e3560fa8f6aa0a25 Author: Matt Jankowski Date: Sun Jul 7 05:39:31 2024 -0400 Limit CI push triggers to `main` and `stable-*` branches (#30934) commit a99ae90d76d91285c0336411742fa88618af8775 Author: Claire Date: Sat Jul 6 09:22:24 2024 +0200 [Glitch] Fix overflow behavior on profile fields in hover cards Port 63ba69810eca80fc2d10114a79f2988c1b75892f to glitch-soc Signed-off-by: Claire commit aca1decf541ed7ac60176e2f0cf33ee4a481685f Author: Claire Date: Fri Jul 5 15:40:53 2024 +0200 [Glitch] Fix right-to-left text in preview cards Port 8f5694d79e531b94784697d92bed24d003d77353 to glitch-soc Signed-off-by: Claire commit 11dd51ef44b14d483b49f7bebed845c1ee85a107 Merge: 05cfe04415 63ba69810e Author: Claire Date: Sat Jul 6 21:02:42 2024 +0200 Merge commit '63ba69810eca80fc2d10114a79f2988c1b75892f' into glitch-soc/merge-upstream Conflicts: - `.env.production.sample`: Upstream and glitch-soc had different comments, some comments got updated upstream. Updated them in glitch-soc accordingly. commit 63ba69810eca80fc2d10114a79f2988c1b75892f Author: Claire Date: Sat Jul 6 09:22:24 2024 +0200 Fix overflow behavior on profile fields in hover cards (#30928) commit 8f5694d79e531b94784697d92bed24d003d77353 Author: Claire Date: Fri Jul 5 15:40:53 2024 +0200 Fix right-to-left text in preview cards (#30930) commit 97eddb5906640a79a1cba20823ce10e986f7f317 Author: David Roetzel Date: Fri Jul 5 15:28:52 2024 +0200 Fix details extraction when no title exists. (#30933) commit 016c1e4e788890f0c81a47640f76de136a0a8f32 Author: David Roetzel Date: Fri Jul 5 13:54:38 2024 +0200 Improve handling of encoding problems when creating link previews (#30929) commit 05f0d510052fb56478986c474192abc7cea3e775 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri Jul 5 13:32:29 2024 +0200 chore(deps): update dependency sidekiq-scheduler to v5.0.5 (#30918) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit a16c2c99b576b6815c9fefede9acc0be0d60d54d Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri Jul 5 11:51:55 2024 +0200 fix(deps): update dependency cssnano to v7.0.4 (#30927) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 81547845ac73f860df2c86594fe0bf346745ce0e Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri Jul 5 11:09:40 2024 +0200 New Crowdin Translations (automated) (#30925) Co-authored-by: GitHub Actions commit 8c375d8a5c899b735950a7a88670a1bb2b7adcd2 Author: Matt Jankowski Date: Fri Jul 5 04:57:54 2024 -0400 Use `scope module: ...` for settings/2FA routes (#30919) commit 8de5df225edb89ef13f5ea2697876018953a97d9 Author: Claire Date: Fri Jul 5 10:54:45 2024 +0200 Change instructions to use `bundle exec rails` instead of `rake` (#30917) commit 05cfe04415084995ccc01b6c737edb39c9dd8411 Merge: 58f027a019 e61a7794f8 Author: Claire Date: Thu Jul 4 17:28:51 2024 +0200 Merge pull request #2765 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to df9e26158d9787859b24bdc276af478abf05e1af commit e61a7794f8c58827bccf02a265fd3e35a489ac32 Merge: 58f027a019 df9e26158d Author: Claire Date: Thu Jul 4 17:12:14 2024 +0200 Merge commit 'df9e26158d9787859b24bdc276af478abf05e1af' into glitch-soc/merge-upstream Conflicts: - `lib/sanitize_ext/sanitize_config.rb`: Conflict because glitch-soc has a different list of allowed tags. Added upstream's new allowed tags while keeping ours. - `spec/requests/api/v1/timelines/public_spec.rb`: Conflict because of glitch-soc's default settings. Updated accordingly. commit df9e26158d9787859b24bdc276af478abf05e1af Author: Claire Date: Thu Jul 4 16:59:54 2024 +0200 Bump version to v4.3.0-alpha.5 (#30920) commit d3a056adfd0eca4fff57dde65ee9d95ce7c9bb3e Author: Claire Date: Thu Jul 4 16:45:52 2024 +0200 Merge pull request from GHSA-xjvf-fm67-4qc3 commit 502cf75b160c76f963a179d46498e3ea1a9fefca Author: Claire Date: Thu Jul 4 16:26:49 2024 +0200 Merge pull request from GHSA-58x8-3qxw-6hm7 * Fix insufficient permission checking for public timeline endpoints Note that this changes unauthenticated access failure code from 401 to 422 * Add more tests for public timelines * Require user token in `/api/v1/statuses/:id/translate` and `/api/v1/scheduled_statuses` commit 395f17ca17b27f9e722425a4d76ef1b02bcebea8 Author: Claire Date: Thu Jul 4 16:11:28 2024 +0200 Merge pull request from GHSA-vp5r-5pgw-jwqx * Fix streaming sessions not being closed when revoking access to an app * Add tests for GHSA-7w3c-p9j8-mq3x commit b73014761807f3171b7ecb46052e9aa618b9c029 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Thu Jul 4 15:46:14 2024 +0200 fix(deps): update dependency ws to v8.18.0 (#30914) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 528661a091bbef5b5359bfacd1478231a1cb7d10 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Thu Jul 4 15:46:08 2024 +0200 fix(deps): update dependency pino-http to v10.2.0 (#30913) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 8331f9e379220847020aed9cd0a8a1d6ab0e7d43 Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu Jul 4 10:46:27 2024 +0200 New Crowdin Translations (automated) (#30916) Co-authored-by: GitHub Actions commit 58f027a0190c10053b71ed23023bc97aa32cef6f Merge: 71375e984f 70ff7a7c69 Author: Claire Date: Wed Jul 3 22:56:52 2024 +0200 Merge pull request #2763 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to 9be77fc0dbb01c1a8a54cd3da97e16c7941df367 commit 70ff7a7c6943b64c005d6abe91491a7125e53486 Merge: 71375e984f 9be77fc0db Author: Claire Date: Wed Jul 3 22:10:41 2024 +0200 Merge commit '9be77fc0dbb01c1a8a54cd3da97e16c7941df367' into glitch-soc/merge-upstream commit 47f0faebc9cb197ea7b4cf8d191df0a1ec926f59 Author: Emelia Smith Date: Wed Jul 3 22:05:59 2024 +0200 Implement HTML ruby tags for east-asian languages (#30897) commit 9be77fc0dbb01c1a8a54cd3da97e16c7941df367 Author: David Roetzel Date: Wed Jul 3 15:36:42 2024 +0200 Revert "Add system check for missing database indexes" (#30909) commit 20c749bd45286fbf0aca5610562e5dc6f2c616dd Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Wed Jul 3 11:14:15 2024 +0200 chore(deps): update dependency rubocop-rspec to v3.0.2 (#30902) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit f99159d1eb671d72138edc42d11cd58472c33aec Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Wed Jul 3 10:46:51 2024 +0200 fix(deps): update dependency webpack-merge to v6 (#30891) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 6270281037c1f0991bfbf8d195280be3f5733bf3 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Wed Jul 3 08:05:19 2024 +0000 chore(deps): update dependency doorkeeper to v5.7.1 (#30053) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 1dbffc30f12d20f3c5f038c72b06967480f82129 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Wed Jul 3 08:04:38 2024 +0000 chore(deps): update opentelemetry-ruby (non-major) (#30903) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 5651c16d11a3bb35e44c260b0c18afcd451fd5aa Author: Matt Jankowski Date: Wed Jul 3 03:47:40 2024 -0400 Limit `browser` version to enforce ruby 3.1 support (#30766) commit dd85e3bcc5e04a11775cbdd9cb1f7d3577ddd9d7 Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed Jul 3 07:30:30 2024 +0000 New Crowdin Translations (automated) (#30901) Co-authored-by: GitHub Actions commit ba7e7a6368f4e6097a7c6ee7145c5ff43e906517 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Wed Jul 3 09:21:05 2024 +0200 chore(deps): update opentelemetry-ruby (non-major) (#30898) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 2e295bd5e7d3e7fefd4d4f03279f0dd0f3e5427d Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Wed Jul 3 07:20:48 2024 +0000 chore(deps): update dependency aws-sdk-s3 to v1.156.0 (#30899) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit ebd8e1bbb6465c78f6542fe7f09938fdb768dbb7 Author: David Roetzel Date: Wed Jul 3 09:19:54 2024 +0200 Add system check for missing database indexes (#30888) commit 1fc14e324bf103e379cf73ffceebbf46472cccde Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue Jul 2 10:41:54 2024 +0200 New Crowdin Translations (automated) (#30890) Co-authored-by: GitHub Actions commit 71375e984f47e9754576113e223c268489d75f11 Merge: 6d6064d2c0 4d4f7ede4f Author: Claire Date: Mon Jul 1 23:53:33 2024 +0200 Merge pull request #2761 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to d3f504245cab5a9a0e89262e0a1398d035dffac9 commit 4d4f7ede4f10c9d10e480f525b989700181b4864 Author: Claire Date: Mon Jul 1 21:21:22 2024 +0200 Revert "Temporarily disable hover cards" This reverts commit 935b955b156f6313e1a4555dbb7b0661c2de1e0a. commit 4c5067e3a45a446491481b370702885bc07bc77c Author: Eugen Rochko Date: Mon Jul 1 16:45:48 2024 +0200 [Glitch] Add timeline of public posts about a trending link in web UI Port 20fa9ce4845f1b6c8a7223f08409091808fa9bc0 to glitch-soc Signed-off-by: Claire commit a70b1141d6d3039ab43366561037ea28a2747d6f Author: Eugen Rochko Date: Mon Jul 1 20:10:22 2024 +0200 [Glitch] Fix missing confirmation when unfollowing from hover card in web UI Port d3f504245cab5a9a0e89262e0a1398d035dffac9 to glitch-soc Signed-off-by: Claire commit dcfd39991b78d308d6a92ebb8c6e33c860747541 Author: Eugen Rochko Date: Mon Jul 1 17:52:01 2024 +0200 [Glitch] Change hover cards to not appear until the mouse stops in web UI Port b728c0e8ce9ac3a74f116bedff85e36dd7cc6a1e to glitch-soc Signed-off-by: Claire commit 92dcc502786f75755ed596cea53273a31e240b4d Merge: d270165be3 d3f504245c Author: Claire Date: Mon Jul 1 20:45:13 2024 +0200 Merge commit 'd3f504245cab5a9a0e89262e0a1398d035dffac9' into glitch-soc/merge-upstream commit d3f504245cab5a9a0e89262e0a1398d035dffac9 Author: Eugen Rochko Date: Mon Jul 1 20:10:22 2024 +0200 Fix missing confirmation when unfollowing from hover card in web UI (#30879) commit b728c0e8ce9ac3a74f116bedff85e36dd7cc6a1e Author: Eugen Rochko Date: Mon Jul 1 17:52:01 2024 +0200 Change hover cards to not appear until the mouse stops in web UI (#30850) commit 20fa9ce4845f1b6c8a7223f08409091808fa9bc0 Author: Eugen Rochko Date: Mon Jul 1 16:45:48 2024 +0200 Add timeline of public posts about a trending link in web UI (#30840) commit d270165be3b3ec7f442ec8a4c5f511168da7397a Merge: 6d6064d2c0 aeefe5b2be Author: Claire Date: Mon Jul 1 12:05:39 2024 +0200 Merge commit 'aeefe5b2bea6e0fb511f029c2aacdefa7bd41eb8' into glitch-soc/merge-upstream commit aeefe5b2bea6e0fb511f029c2aacdefa7bd41eb8 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jul 1 09:03:38 2024 +0000 chore(deps): update eslint (non-major) (#30883) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit aefb4c027b035bc3022343157d31117e7ae531b4 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jul 1 08:35:19 2024 +0000 chore(deps): update dependency rubocop-rails to v2.25.1 (#30876) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 7756db65519136d92b04b8709681f62a971836f7 Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon Jul 1 08:34:38 2024 +0000 New Crowdin Translations (automated) (#30873) Co-authored-by: GitHub Actions commit ed15ae075c00b72388d06f1d62b87a6ed2028e57 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jul 1 08:27:03 2024 +0000 fix(deps): update dependency @reduxjs/toolkit to v2.2.6 (#30875) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 4c701463b4717acfdf37d5992bf1d729c2221011 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jul 1 08:26:08 2024 +0000 chore(deps): update dependency aws-sdk-s3 to v1.155.0 (#30871) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 2f1df842f8ba3ec064a560685f51489aee3a5ecf Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jul 1 10:25:52 2024 +0200 chore(deps): update dependency test-prof to v1.3.3.1 (#30872) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 3c1e1685c73fa69dec719cb0bf2847de6df31dd1 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jul 1 10:21:55 2024 +0200 fix(deps): update dependency postcss to v8.4.39 (#30877) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 9c7d56db9a30e35d54974ea9257c2b48545b5217 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jul 1 10:21:40 2024 +0200 fix(deps): update dependency postcss-preset-env to v9.5.15 (#30878) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 8142c7aa3eb2e0705c32e862fd7db000b898bc38 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jul 1 10:21:15 2024 +0200 chore(deps): update definitelytyped types (non-major) (#30882) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 6d6064d2c0242c6b923b79db05fefa3d8c581827 Author: Aria Date: Sun Jun 30 22:27:38 2024 +0200 fix(collapsing): fix and simplify post collapsing CSS (#2757) commit a396985c140961b2c9834102d4a63308a0ea27b5 Merge: 1eb69c5c65 935b955b15 Author: Claire Date: Sun Jun 30 22:25:48 2024 +0200 Merge pull request #2760 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to 5d4dbbcc67c98007d417cbe67b5a2261889304dc commit 935b955b156f6313e1a4555dbb7b0661c2de1e0a Author: Claire Date: Sun Jun 30 21:48:30 2024 +0200 Temporarily disable hover cards commit 412e5ddcbf50a5866b368623726d76e52e0102d0 Author: Eugen Rochko Date: Fri Jun 28 00:01:40 2024 +0200 [Glitch] Fix follow button in hover cards not working when signed out in web UI Port ea6c455e81f9f01a64adf123d0a4f820c6e67f97 to glitch-soc Signed-off-by: Claire commit 98185247b85cb2fa6b0dc9c5f5be7d22f3db7a24 Author: Eugen Rochko Date: Wed Jun 26 21:33:38 2024 +0200 [Glitch] Add hover cards in web UI Port e89317d4c1da991b728b6d4a21671ed33f057cc4 Co-authored-by: Renaud Chaput Signed-off-by: Claire commit 4179f5fcf32a2aaa83c1eb564f60196722825669 Author: Eugen Rochko Date: Thu Jun 27 15:17:18 2024 +0200 [Glitch] Change `author_account` to be `authors` in REST API Port 096057b845f27fd6090915b22c8688a6eeb22e28 to glitch-soc Signed-off-by: Claire commit d612daee97d95c67009f7e6e3be25f1a2a5aa352 Author: Eugen Rochko Date: Wed Jun 26 21:46:28 2024 +0200 [Glitch] Convert `` to Typescript Port 3939352e92f4be13b773ee243bbb6ad54d6b5bd1 to glitch-soc Signed-off-by: Claire commit 8160a655a528856f87b8d0174bce54c78a7af4be Author: Renaud Chaput Date: Wed Jun 26 20:04:50 2024 +0200 [Glitch] Convert `` to Typescript / function component Port 863c470a2bc4e13a5b8df4d66a1322f4b84e2db2 to glitch-soc Signed-off-by: Claire commit 1ac4e64a3ba51360dfc62f63e95c157a36c65e61 Author: Renaud Chaput Date: Tue Jun 25 23:57:22 2024 +0200 [Glitch] Change light mode to apply CSS variables to the body Port 8c0ff6498e090a2919e8f8104339796ed2d3d212 to glitch-soc Signed-off-by: Claire commit d2aea85e6c945c98193f495c7308ddda5bffa75d Merge: 1eb69c5c65 5d4dbbcc67 Author: Claire Date: Sun Jun 30 11:25:40 2024 +0200 Merge commit '5d4dbbcc67c98007d417cbe67b5a2261889304dc' into glitch-soc/merge-upstream commit 5d4dbbcc67c98007d417cbe67b5a2261889304dc Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Sat Jun 29 22:51:46 2024 +0200 chore(deps): update dependency charlock_holmes to v0.7.8 (#30870) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit ba6a558a7088b811b63a90d20b82069eee7dfaa1 Author: Claire Date: Sat Jun 29 00:41:27 2024 +0200 Simplify color extraction code using `bandunfold` (#30869) commit 1bccba14082f380232a363d036b6b2e92104ffc6 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri Jun 28 13:39:32 2024 +0200 chore(deps): update dependency @testing-library/react to v16 (#30533) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Renaud Chaput commit a5134f2695659ccb1c40b28b1f691e2dc932a5fb Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri Jun 28 10:33:57 2024 +0200 New Crowdin Translations (automated) (#30867) Co-authored-by: GitHub Actions commit ea6c455e81f9f01a64adf123d0a4f820c6e67f97 Author: Eugen Rochko Date: Fri Jun 28 00:01:40 2024 +0200 Fix follow button in hover cards not working when signed out in web UI (#30864) commit 0f3fef6fda5819824457b9c1cdc41cb3d5ca976e Author: Eugen Rochko Date: Thu Jun 27 23:34:34 2024 +0200 Change search modifiers to be case-insensitive (#30865) commit 3225954865c49ce7a336b73b2bc0c5ff2b707746 Author: Michael Stanclift Date: Thu Jun 27 11:46:20 2024 -0500 Fix browser window color on light theme (#30861) commit bc3737f0c3c4cc0af500413db53fb5443ad02b69 Author: Matt Jankowski Date: Thu Jun 27 12:27:42 2024 -0400 Add detail about running version on vips error failure (#30858) commit 03bbb74b0ccc5f56bb3856efb1892ae8e0872a38 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Thu Jun 27 16:27:32 2024 +0000 fix(deps): update dependency prom-client to v15.1.3 (#30852) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 836c0477ac63ea61b955bfb900cf52ec29554e40 Author: Matt Jankowski Date: Thu Jun 27 12:03:26 2024 -0400 Use vips setting instead of env var in media processing spec (#30859) commit b15a3614dc7466e983e1394a12a16874a812e672 Author: Claire Date: Thu Jun 27 17:25:27 2024 +0200 Stub `Vips::Error` when not using libvips (#30857) commit ff08d99d4dceebd720e16e4a40118cbd6941b0ca Author: David Roetzel Date: Thu Jun 27 16:41:03 2024 +0200 Catch encoding errors when creating link previews. (#30853) commit 42adb6eaee3250e3557403ce52513e3d31b3ab80 Author: David Roetzel Date: Thu Jun 27 16:40:19 2024 +0200 Add size limit for link preview URLs (#30854) commit 096057b845f27fd6090915b22c8688a6eeb22e28 Author: Eugen Rochko Date: Thu Jun 27 15:17:18 2024 +0200 Change `author_account` to be `authors` in REST API (#30846) commit 6d1c1fd684d0f20691cba552b209b15d0107dfe4 Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu Jun 27 10:00:04 2024 +0200 New Crowdin Translations (automated) (#30851) Co-authored-by: GitHub Actions commit f6390c3326b016e1a52057573839a5608ba317ea Author: Matt Jankowski Date: Thu Jun 27 03:42:57 2024 -0400 Use flatware to parallelize CI specs (#30284) commit ad53b0ab65cd9eba6d3078a3980c467428e79371 Author: Matt Jankowski Date: Thu Jun 27 03:16:59 2024 -0400 Rely on built-in ruby private IP detection (#30848) commit 3939352e92f4be13b773ee243bbb6ad54d6b5bd1 Author: Eugen Rochko Date: Wed Jun 26 21:46:28 2024 +0200 Convert `` to Typescript (#30849) commit e89317d4c1da991b728b6d4a21671ed33f057cc4 Author: Eugen Rochko Date: Wed Jun 26 21:33:38 2024 +0200 Add hover cards in web UI (#30754) Co-authored-by: Renaud Chaput commit 863c470a2bc4e13a5b8df4d66a1322f4b84e2db2 Author: Renaud Chaput Date: Wed Jun 26 20:04:50 2024 +0200 Convert `` to Typescript / function component (#30829) commit 51f581e03e1b2611eceddf5010ef736680e1f62b Author: Matt Jankowski Date: Wed Jun 26 09:51:44 2024 -0400 Fix `Rails/ReversibleMigration` cop for `remove` (#30833) commit 528a7f57fa8a31d1a901c247cc55b214e2dc1af5 Author: Matt Jankowski Date: Wed Jun 26 09:51:11 2024 -0400 Fix `Rails/ReversibleMigration` cop for `change_column` (#30835) commit 7a84b76bb1716b131c35d9569bfcef3b32d73e60 Author: Claire Date: Wed Jun 26 15:44:08 2024 +0200 Drop favicon.ico generation (#30375) commit 2b43c05a6a1c38a7480119a0bd12fefa8b5589c6 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Wed Jun 26 15:42:25 2024 +0200 chore(deps): update dependency aws-sdk-s3 to v1.154.0 (#30838) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 8c0ff6498e090a2919e8f8104339796ed2d3d212 Author: Renaud Chaput Date: Tue Jun 25 23:57:22 2024 +0200 Change light mode to apply CSS variables to the body (#30839) commit a40831b3636fbca1e6d6b096e3d3cdd66569baf9 Author: Eugen Rochko Date: Tue Jun 25 22:37:48 2024 +0200 Fix account search results (#30803) commit 1eb69c5c6592f48a99c7239d3cb6d24dd1df90b9 Merge: 9aee910cc1 7d89d1f186 Author: Claire Date: Tue Jun 25 19:41:01 2024 +0200 Merge pull request #2758 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to 2c7eed1fa1e7af72dd03a041a60f2cfd42e913e0 commit 07d222665b9974a97c78d2a500a55555ebedd640 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Tue Jun 25 17:25:11 2024 +0000 chore(deps): update dependency typescript to v5.5.2 (#30815) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 7d89d1f1866f5e35e04b48d268f0397731794e83 Author: Claire Date: Tue Jun 25 18:53:03 2024 +0200 [Glitch] Fix API requests after #30818 Port 2c7eed1fa1e7af72dd03a041a60f2cfd42e913e0 to glitch-soc commit 85e6efd351ca7882cb6416fc63a287cd6ddd2077 Merge: 3a20290915 2c7eed1fa1 Author: Claire Date: Tue Jun 25 19:06:59 2024 +0200 Merge commit '2c7eed1fa1e7af72dd03a041a60f2cfd42e913e0' into glitch-soc/merge-upstream commit 2c7eed1fa1e7af72dd03a041a60f2cfd42e913e0 Author: Claire Date: Tue Jun 25 18:53:03 2024 +0200 Fix API requests after #30818 (#30837) commit 3a202909157af2f07fee13113a6c55ba3d5a6ff2 Author: Renaud Chaput Date: Tue Jun 25 15:45:41 2024 +0200 [Glitch] Change `apiRequest` to accept both `params` and `data` Port 547e97945df0abc68dc473ed60d2faeb2feb2b06 commit 6f2771cb32cdcbd217e69d8e1baa424d93a7d9a3 Merge: 9aee910cc1 845fe1c693 Author: Claire Date: Tue Jun 25 17:57:39 2024 +0200 Merge commit '845fe1c6936a7b386fd74ae567c19600a88e795a' into glitch-soc/merge-upstream commit 845fe1c6936a7b386fd74ae567c19600a88e795a Author: Renaud Chaput Date: Tue Jun 25 16:05:24 2024 +0200 Add the Interlingua locale (#30828) commit 8ef59729a10fd77121507dcf9ef5138ff9037d39 Author: Matt Jankowski Date: Tue Jun 25 09:57:40 2024 -0400 Ignore intermittent chrome/manifest/icon interaction failure (#30793) commit 547e97945df0abc68dc473ed60d2faeb2feb2b06 Author: Renaud Chaput Date: Tue Jun 25 15:45:41 2024 +0200 Change `apiRequest` to accept both `params` and `data` (#30818) commit 309274839dd446d334ae2ea5c6e033debe56e4ed Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Tue Jun 25 09:56:38 2024 +0200 chore(deps): update dependency aws-sdk-s3 to v1.153.0 (#30824) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 30ae5952d228b31af58534d76a8d78bf27a171f9 Author: Emelia Smith Date: Tue Jun 25 09:46:53 2024 +0200 Fix: Ensure "With Media" is highlighted from Admin Accounts page (#30812) commit 052c90b8de2164b8003c29f445f165c7e802fd25 Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue Jun 25 09:45:58 2024 +0200 New Crowdin Translations (automated) (#30825) Co-authored-by: GitHub Actions commit 9aee910cc1653781331a19044bc5e625533676ac Merge: be3d60c36c 21ca03581a Author: Claire Date: Mon Jun 24 21:21:37 2024 +0200 Merge pull request #2754 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to 6527d5039141fe4a80645147b581d76952a64f39 commit 21ca03581a987972b8df20cd7aa8787d587b54dc Merge: be3d60c36c 6527d50391 Author: Claire Date: Mon Jun 24 19:39:42 2024 +0200 Merge commit '6527d5039141fe4a80645147b581d76952a64f39' into glitch-soc/merge-upstream commit 6527d5039141fe4a80645147b581d76952a64f39 Author: Matt Jankowski Date: Mon Jun 24 10:50:37 2024 -0400 Disable `Rails/BulkChangeTable` cop (#30820) commit 39d80e84be660e6d3eb121ee8f1067bd87cc3783 Author: Matt Jankowski Date: Mon Jun 24 10:47:14 2024 -0400 Remove `lockfileMaintenance` setting (#30799) commit f6e466058a5a70eba5001c7ad3a80d86c07eb25d Author: Tim Rogers Date: Mon Jun 24 09:41:04 2024 -0500 Added check for STATSD_ADDR setting to emit a warning and proceed rather than crashing if the address is unreachable (#30691) commit 8827cd597e695c0368dfdce582755eda7f667272 Author: Claire Date: Mon Jun 24 15:11:10 2024 +0200 Fix `/admin/accounts/:account_id/statuses/:id` for edited posts with media attachments (#30819) commit 61722b1b1fb36ff5c3d6c470981f5fc6648e2d14 Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon Jun 24 12:46:53 2024 +0200 New Crowdin Translations (automated) (#30808) Co-authored-by: GitHub Actions commit 1af6313ced5b39041cb8c480b1f0c65155429238 Author: Essem Date: Mon Jun 24 05:36:26 2024 -0500 Fix CMD syntax in streaming Dockerfile (#30795) commit 54cc204473302eda7e6e7e75b343a14859524ab1 Author: Essem Date: Mon Jun 24 05:29:00 2024 -0500 Use WebSocketServer instead of WebSocket.Server in streaming (#30788) commit b3710098a8edcb5cc317a280758b2a772ea722ef Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jun 24 12:18:51 2024 +0200 chore(deps): update dependency opentelemetry-instrumentation-faraday to v0.24.5 (#30797) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 6d14cfbf298eec6e2ffcd4ad69a118cdd168b3a1 Author: Nick Schonning Date: Mon Jun 24 06:18:36 2024 -0400 Unset Rails/UnusedIgnoredColumns (#30800) commit 3f81e7dcc8afbb86e48c36773fe2bc7018b44379 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jun 24 12:16:24 2024 +0200 chore(deps): update dependency @types/http-link-header to v1.0.6 (#30814) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit be3d60c36cacf16fa910c67e23878298210771c6 Merge: 1090611529 3b4607991d Author: Claire Date: Sun Jun 23 12:33:13 2024 +0200 Merge pull request #2753 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to 4743657ba24e83c376e9f477fbf49114e6f09a57 commit 3b4607991d763007f5aff308754b51990e0ad09c Merge: 1090611529 4743657ba2 Author: Claire Date: Sat Jun 22 20:59:23 2024 +0200 Merge commit '4743657ba24e83c376e9f477fbf49114e6f09a57' into glitch-soc/merge-upstream commit 4743657ba24e83c376e9f477fbf49114e6f09a57 Author: Michael Stanclift Date: Fri Jun 21 15:26:39 2024 -0500 Fix Docker buildx warnings about casing and undefined variables (#30798) commit 637de635054d42a0ae43035c2658c6941498f918 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri Jun 21 21:37:22 2024 +0200 chore(deps): update dependency public_suffix to v6 (#30738) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 93741f6a707329fb3f4c1b46bfc979fa99dd16d7 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri Jun 21 18:15:33 2024 +0200 fix(deps): update dependency glob to v10.4.2 (#30761) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 8fd5b59f8ff74d08514a0b8f563c9e23ad278814 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri Jun 21 16:15:09 2024 +0000 chore(deps): update dependency devise-two-factor to v5.1.0 (#30760) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit f898214dea0b855a7b47de7fd6a151146f8efad4 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri Jun 21 18:14:41 2024 +0200 chore(deps): update opentelemetry-ruby (non-major) (#30771) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit abbda3dc26713d7b510a86dd2dac5ed2d20424cb Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri Jun 21 18:14:20 2024 +0200 chore(deps): update dependency node to 20.15 (#30782) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 253a9f766aca839804d231c7988aede71d667893 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri Jun 21 18:13:53 2024 +0200 chore(deps): update dependency addressable to v2.8.7 (#30791) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 929b9fdaff1e6d4223efd8f00bd0b53fae1c7ce1 Author: Matt Jankowski Date: Fri Jun 21 11:34:13 2024 -0400 Remove exclusion for `Rails/LexicallyScopedActionFilter` cop (#30697) commit 348ccf206ee245309d8e44855667f92c4fc06b7d Author: Matt Jankowski Date: Fri Jun 21 11:33:55 2024 -0400 Fix `Style/ClassEqualityComparison` cop (#30058) commit 72484a194fb5f52cf2512a95045fc6bd2d3e2ef4 Author: Matt Jankowski Date: Fri Jun 21 11:32:49 2024 -0400 Remove `CacheBuster` default options (#30718) commit 109061152986248d933b3ecf2c21fae9a1872b33 Merge: 1a88f6d97d 2f994bb34a Author: Claire Date: Fri Jun 21 17:05:45 2024 +0200 Merge pull request #2751 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to bb2d77b4a07e95e7d96df080f2d6994c1422b0c0 commit 4651c0cb39c1a1e4feb6d8fc2b53de622eeb7373 Author: Matt Jankowski Date: Fri Jun 21 10:43:12 2024 -0400 Fix `Rails/ReversibleMigrationMethodDefinition` cop (#30794) commit 2cab1c7b09f64cae8128fa33645137fe55daf075 Author: David Roetzel Date: Fri Jun 21 14:51:10 2024 +0200 Improve encoding detection for link cards (#30780) commit 4e6db5e284988e77b9c2bec5c100b302f2294b74 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri Jun 21 11:38:26 2024 +0000 chore(deps): update yarn to v4.3.1 (#30790) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 2c65a1b0e58ef4aa0fddd1b1cb1fa0d51237b189 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri Jun 21 13:37:47 2024 +0200 chore(deps): update dependency selenium-webdriver to v4.22.0 (#30786) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 5b938e6e20ce9956812834031c6fd8c7dfa5b184 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri Jun 21 13:37:15 2024 +0200 chore(deps): update dependency @types/uuid to v10 (#30787) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 2f994bb34a4d61f3529dd8910e7195b8c1d063ab Author: Renaud Chaput Date: Fri Jun 21 00:39:06 2024 +0200 [Glitch] Fix error when deleting a status Port 7d12522ed71193decc2a9aeacc8cf921b09d3654 to glitch-soc Signed-off-by: Claire commit 6300273664f27606e36ff312dd0e22e7e74ab29c Merge: 8ae61fdee5 9e932fa1dd Author: Claire Date: Fri Jun 21 12:02:42 2024 +0200 Merge commit '9e932fa1ddaea569ca52fe663eb4bb13a5a43e0a' into glitch-soc/merge-upstream commit 9e932fa1ddaea569ca52fe663eb4bb13a5a43e0a Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri Jun 21 11:14:44 2024 +0200 New Crowdin Translations (automated) (#30789) Co-authored-by: GitHub Actions commit 7d12522ed71193decc2a9aeacc8cf921b09d3654 Author: Renaud Chaput Date: Fri Jun 21 00:39:06 2024 +0200 Fix error when deleting a status (#30784) commit 8ae61fdee58706c98a8f4178ad726b81633a839e Author: Renaud Chaput Date: Thu Jun 20 13:56:52 2024 +0200 [Glitch] Convert `disconnectTimeline` and `timelineDelete` actions to Typescript Port 1c6593277696c6f4698684860f7c6d6189f9b371 to glitch-soc Signed-off-by: Claire commit fd867adffed42bc64aeab1b4a1e961520757c005 Merge: 1a88f6d97d bb2d77b4a0 Author: Claire Date: Thu Jun 20 18:36:13 2024 +0200 Merge commit 'bb2d77b4a07e95e7d96df080f2d6994c1422b0c0' into glitch-soc/merge-upstream commit 1a88f6d97d38813f0d9a29792ed9a7ca8cfc1c09 Merge: 7a29b1ed46 c97e798d8c Author: Claire Date: Thu Jun 20 18:35:43 2024 +0200 Merge pull request #2750 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to 27529247b289a0e78d2deb97626ddb60baf04d86 commit bb2d77b4a07e95e7d96df080f2d6994c1422b0c0 Author: Claire Date: Thu Jun 20 17:54:50 2024 +0200 Change `/api/v2_alpha/notifications` to only return historical data in pages (#30781) commit 6ab6146c0be04271d9da1dc57b842e8998fbbfb9 Author: Nick Schonning Date: Thu Jun 20 11:30:49 2024 -0400 Remove --no-exclude-limit for RuboCop ToDo (#30427) commit f723370c6982d914695378ef70949b22a8bb235d Author: Claire Date: Thu Jun 20 15:44:49 2024 +0200 Fix missing `account_warning` delegation in `NotificationGroup` (#30779) commit c97e798d8cc36c22e7a622628a97fb07954db993 Author: Renaud Chaput Date: Thu Jun 20 13:42:10 2024 +0200 [Glitch] Improve `createdataLoadingThunk` Port 27529247b289a0e78d2deb97626ddb60baf04d86 to glitch-soc Signed-off-by: Claire commit 04e57efa556275c4289616db8e0192c7522e2559 Merge: cabd7c21fc 27529247b2 Author: Claire Date: Thu Jun 20 13:57:08 2024 +0200 Merge commit '27529247b289a0e78d2deb97626ddb60baf04d86' into glitch-soc/merge-upstream commit 1c6593277696c6f4698684860f7c6d6189f9b371 Author: Renaud Chaput Date: Thu Jun 20 13:56:52 2024 +0200 Convert `disconnectTimeline` and `timelineDelete` actions to Typescript (#30777) commit 27529247b289a0e78d2deb97626ddb60baf04d86 Author: Renaud Chaput Date: Thu Jun 20 13:42:10 2024 +0200 Improve `createdataLoadingThunk` (#30778) commit 7889e983fbe7e29f3f91784cfa2117e620514ad7 Author: Claire Date: Thu Jun 20 13:05:25 2024 +0200 Add `group_key` attribute to `NotificationSerializer` (#30776) Co-authored-by: Renaud Chaput commit a0910cd49ca0f455ed6616deb429b41dc55e2207 Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu Jun 20 11:03:28 2024 +0200 New Crowdin Translations (automated) (#30772) Co-authored-by: GitHub Actions commit cb7121e5a9ad4f0fa0a2d4a6058b3889570ca76e Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Thu Jun 20 09:42:28 2024 +0200 chore(deps): update dependency rspec-rails to v6.1.3 (#30770) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 7a29b1ed466e617ce867658bd15b8c9da807fe13 Merge: 0c2b1f56ef cabd7c21fc Author: Claire Date: Thu Jun 20 08:37:18 2024 +0200 Merge pull request #2749 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to 2cda1dd542b20a47245cb8d28a4f6f8750c2284c commit cabd7c21fc02a359cf550387efd3dea43949c8f6 Merge: 0c2b1f56ef 2cda1dd542 Author: Claire Date: Wed Jun 19 19:37:37 2024 +0200 Merge commit '2cda1dd542b20a47245cb8d28a4f6f8750c2284c' into glitch-soc/merge-upstream commit 2cda1dd542b20a47245cb8d28a4f6f8750c2284c Author: Claire Date: Wed Jun 19 18:59:37 2024 +0200 Fix compatibility with Redis < 6.2 again (#30412) commit 0c2b1f56ef6f0c48330076498741849b79d8b18c Merge: 3bc513c06b 52e34a6bd6 Author: Claire Date: Wed Jun 19 17:28:25 2024 +0200 Merge pull request #2748 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to 5f4d231e980665c0946297909df508269fb25dc6 commit 84a31319e9900260b54c05fdeec804e182d06573 Author: Matt Jankowski Date: Wed Jun 19 09:46:52 2024 -0400 Add `match_json_values` and use in AP worker specs (#30720) commit 53776cd58f98e93797ebc9fb34f02ccdb6dad01f Author: Nick Schonning Date: Wed Jun 19 09:42:36 2024 -0400 Enable passing ESLint rules (#30726) commit 52e34a6bd6971f378bcb481481a9278922f6b4b8 Merge: 3bc513c06b 5f4d231e98 Author: Claire Date: Wed Jun 19 11:59:06 2024 +0200 Merge commit '5f4d231e980665c0946297909df508269fb25dc6' into glitch-soc/merge-upstream commit 5f4d231e980665c0946297909df508269fb25dc6 Author: Matt Jankowski Date: Wed Jun 19 05:34:24 2024 -0400 Use rubocop `DisplayCopNames` and `UseCache` defaults (true) (#30750) commit 49b323c13ddfcaad6c4ad1de74f712f44cfef0bb Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Wed Jun 19 11:31:56 2024 +0200 fix(deps): update dependency cssnano to v7.0.3 (#30764) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 8098d27f84028c226729c76f1ebdeadec881b1c5 Author: Claire Date: Wed Jun 19 11:31:30 2024 +0200 Stop calling Webpacker in full-stack tests (#30763) commit 556d4097804838efed16e4ac6cb57db3b4b50216 Author: Matt Jankowski Date: Wed Jun 19 05:08:04 2024 -0400 Enable renovate `lockFileMaintenance` setting (#30732) commit 4e7e31538feb329abf1be454121fc5fdb8e16bd3 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Wed Jun 19 10:45:51 2024 +0200 chore(deps): update opentelemetry-ruby (non-major) (#30755) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit a8b3d2e4e4e244f6dd44a2f9fe971279511534ac Author: Matt Jankowski Date: Wed Jun 19 04:45:47 2024 -0400 Consolidate time periods methods into base measure (#30757) commit 80743e0e7f091bfaa5b63148751e7842832a5fa0 Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed Jun 19 10:45:40 2024 +0200 New Crowdin Translations (automated) (#30762) Co-authored-by: GitHub Actions commit be19b94dea1c18802702cc8efc21ba1dfa51e6b9 Author: Matt Jankowski Date: Tue Jun 18 17:34:17 2024 -0400 Unpluralize mistakenly changed privacy template (#30759) commit 3bc513c06ba6375b69a67ad4fb94ac1bc36238af Merge: 18d9601464 af0a1a8774 Author: Claire Date: Tue Jun 18 19:25:49 2024 +0200 Merge pull request #2747 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to 58ace2e45e16a69977267d03874568c11043f04c commit af0a1a8774e5a74d48d9c3aff503d93700b4ccd0 Author: Renaud Chaput Date: Tue Jun 18 15:23:30 2024 +0200 [Glitch] Convert notifications policies frontend code to Typescript Port d558dfd77dc4f64d3a633efcfc0683ee603a1520 to glitch-soc Signed-off-by: Claire commit b0c979af49056a8c311b20a6f43d1b5a1edd28a3 Merge: 18d9601464 58ace2e45e Author: Claire Date: Tue Jun 18 18:20:36 2024 +0200 Merge commit '58ace2e45e16a69977267d03874568c11043f04c' into glitch-soc/merge-upstream commit 58ace2e45e16a69977267d03874568c11043f04c Author: Claire Date: Tue Jun 18 18:04:58 2024 +0200 Fix SQL error in admin measures API (#30753) commit d97fcd0cbb394ac5acaf281dbd1575cbd0fcaf2a Author: Michael Stanclift Date: Tue Jun 18 09:51:51 2024 -0500 Build ffmpeg from source in Dockerfile (#30569) commit d558dfd77dc4f64d3a633efcfc0683ee603a1520 Author: Renaud Chaput Date: Tue Jun 18 15:23:30 2024 +0200 Convert notifications policies frontend code to Typescript (#29868) commit 50db95b9a194756108e640d1054449bff3b9831d Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue Jun 18 12:39:36 2024 +0000 New Crowdin Translations (automated) (#30746) Co-authored-by: GitHub Actions commit 689ba28b07679dfe2d3ac2c22bdab832eb6b1a9d Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Tue Jun 18 12:24:14 2024 +0000 chore(deps): update docker/dockerfile docker tag to v1.8 (#30736) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 81f95cf08ecab324c8d9fce20a6a8a4ef2634fc6 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Tue Jun 18 12:20:43 2024 +0000 fix(deps): update dependency sass to v1.77.6 (#30745) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 7db3509a1fc929be788bf11e43391ada043cc29e Author: Matt Jankowski Date: Tue Jun 18 08:20:23 2024 -0400 Remove comment for ruby-core-extracted gem (#30740) commit 238dd23214eef7bcb1fe317717fd5107c530155c Author: Matt Jankowski Date: Tue Jun 18 08:16:37 2024 -0400 Remove already configured excludes from .rubocop.yml (#30741) commit 38c6825edaa0a8c6520b2d1720f9b369fc63cba6 Author: Matt Jankowski Date: Tue Jun 18 08:16:16 2024 -0400 Remove unused `Extractor#extract_cashtags_with_indices` method (#30742) commit 18d9601464524dabc4a451524a535d0f9a3cb65e Merge: 68c9fa8fcc eccec92496 Author: Claire Date: Mon Jun 17 22:53:03 2024 +0200 Merge pull request #2744 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to d5f02adad716520b6b9014553bc730dcef5b2f50 commit eccec924965d1b18b315f025f38bb1563adb351f Author: Eugen Rochko Date: Fri Jun 14 15:04:20 2024 +0200 [Glitch] Change sidebar text in web UI Port b9fd7571aedbfda524ab48ba15c03bd3936b8b2c to glitch-soc Signed-off-by: Claire commit 395b9011ee3679c1194a32ba12735b212cc7650e Merge: f0dba9af6f d5f02adad7 Author: Claire Date: Mon Jun 17 18:30:28 2024 +0200 Merge commit 'd5f02adad716520b6b9014553bc730dcef5b2f50' into glitch-soc/merge-upstream Conflicts: - `app/helpers/application_helper.rb`: Not a real conflict, just upstream adding a method textually adjacent to glitch-soc only code. Ported upstream's change. commit f0dba9af6f1d87f5da7685f430929d9a7fadb198 Author: Marcin Mikołajczak Date: Thu Jun 13 21:46:45 2024 +0200 [Glitch] LanguageDropdown: remove unused function Port a243963e934123e17519711ce0378eaa7b5f8204 to glitch-soc Signed-off-by: marcin mikołajczak Signed-off-by: Claire commit 8089fa6935cef4a5e8a14e762e33edae54e9417e Merge: fd3697723c a7264a2b42 Author: Claire Date: Mon Jun 17 18:14:14 2024 +0200 Merge commit 'a7264a2b42631bd876d114b96f689492e2908a8d' into glitch-soc/merge-upstream Conflicts: - `app/views/layouts/application.html.haml`: Conflict because of glitch-soc's different theming system. Ported upstream's change. commit d5f02adad716520b6b9014553bc730dcef5b2f50 Author: Michael Stanclift Date: Mon Jun 17 07:28:01 2024 -0500 Add option to use native Ruby driver for Redis (#30717) commit d7b76173219d88d5ad52097ecb4bf6abbd59b24a Author: Matt Jankowski Date: Mon Jun 17 08:20:57 2024 -0400 Use `class_names` in admin/account_moderation_notes helper (#30719) commit 35d52d7914a3ebd176ba73121728812154f57ec9 Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon Jun 17 14:13:23 2024 +0200 New Crowdin Translations (automated) (#30723) Co-authored-by: GitHub Actions commit fd3697723ccec26198c92f170767481d239ac4f2 Author: Eugen Rochko Date: Thu Jun 13 15:04:16 2024 +0200 [Glitch] Add author links on the explore page in web UI Port ed6d24330ba2f80b99428cb8ee19e5d8400ebd16 to glitch-soc Signed-off-by: Claire commit 454dc407f4d912bb4124ff2954f1faa8516b1b77 Author: Eugen Rochko Date: Wed Jun 12 15:10:51 2024 +0200 [Glitch] Fix a few visual glitches with link previews in web UI Port 99842434677ef3a01f5c7700d3b67ba5e72cd1a1 to glitch-soc Signed-off-by: Claire commit 677f73f7938a48badfd957c3f19834a8cca2c4d3 Merge: 68c9fa8fcc 3a191b3797 Author: Claire Date: Mon Jun 17 13:41:58 2024 +0200 Merge commit '3a191b3797dde1daf79cd748a14b87240532d543' into glitch-soc/merge-upstream commit 68c9fa8fccd8e0063f09611f01244cd89a10c127 Merge: 69225367e5 f214813919 Author: Claire Date: Mon Jun 17 13:38:38 2024 +0200 Merge pull request #2742 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to d818ddd6870094e89e58ef61f37da4cb73935856 commit f195c466350754a1e34810947faafeb9e6ae6a26 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jun 17 10:22:05 2024 +0000 chore(deps): update dependency irb to v1.13.2 (#30727) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit f287462f760bbc2402772e120148687565a39cc5 Author: Matt Jankowski Date: Mon Jun 17 06:21:29 2024 -0400 Fix repeated Delete/Undo assertion in remove status service spec (#30715) commit c739b7f85173b62b93ab4f5be1b47f543c92bcd5 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jun 17 09:13:07 2024 +0000 fix(deps): update dependency ws to v8.17.1 (#30733) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 04d6cde39316f88df6f9877adedf4693a319881a Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jun 17 11:13:07 2024 +0200 chore(deps): update devdependencies (non-major) (#30735) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 43bbdea421853fa251d6d73da244d26eef07ecdc Author: Renaud Chaput Date: Mon Jun 17 11:00:26 2024 +0200 Fix invalid `mask-icon` when a custom instance icon is configured (#30734) commit 5addffb604bde2bad17903f5404234d194f4856d Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jun 17 08:57:49 2024 +0000 chore(deps): update dependency public_suffix to v5.1.1 (#30725) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit dd5fc5329e9e926ecc819a1e7c75390e220c9bb6 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jun 17 10:56:33 2024 +0200 chore(deps): update dependency memory_profiler to v1.0.2 (#30737) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit e80710fae6fecf4ef98373c6e49ede361a605852 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jun 17 08:44:58 2024 +0000 chore(deps): update dependency rubocop-performance to v1.21.1 (#30731) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit a777f7e3cc3cc936c7876c1d006e1954158d1e27 Author: Michael Stanclift Date: Fri Jun 14 11:10:16 2024 -0500 Restore short Ruby version on admin dashboard (#30711) commit 2b10b0e027cbab1ab66c3ad2c11b189ba4e7c041 Author: Matt Jankowski Date: Fri Jun 14 11:49:08 2024 -0400 Reduce docker service container health check wait times (#30703) commit 4a5442edaa5d598eea969ac023dc394761f38d7b Author: Michael Stanclift Date: Fri Jun 14 10:36:57 2024 -0500 Add ffmpeg and ImageMagick versions to admin dashboard (#30710) commit 09dca8ba3d47b07be8230185ff5068bdcd492ad1 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri Jun 14 15:24:26 2024 +0200 chore(deps): update dependency fog-openstack to v1.1.3 (#30671) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit b9fd7571aedbfda524ab48ba15c03bd3936b8b2c Author: Eugen Rochko Date: Fri Jun 14 15:04:20 2024 +0200 Change sidebar text in web UI (#30696) commit 8eb27c60e117f9fbfe33a0b9bde6dd4c1015ef4f Author: Claire Date: Fri Jun 14 12:33:06 2024 +0200 Add `most_recent_notification_id` to `NotificationGroup` (#30707) commit b5d1d4826656db3103711a200a04cb1f2fa7da83 Author: Matt Jankowski Date: Fri Jun 14 05:54:22 2024 -0400 Convert `form_for` -> `form_with` in views (#30700) commit 980034e2e14a8a27156009b88ef7d7d58aef5d14 Author: Matt Jankowski Date: Fri Jun 14 05:50:50 2024 -0400 Fix `Style/NilLambda` cop in paperclip initializer (#30695) commit 222ab80557cfe3dac1b520bfc3a49f3b1bb88c55 Author: Matt Jankowski Date: Fri Jun 14 05:50:33 2024 -0400 Fix `Style/GlobalStdStream` cop in environments/* files (#30694) commit ab8474fd7fb321d235f3a3ebe277baed6da9cd62 Author: Matt Jankowski Date: Fri Jun 14 05:49:49 2024 -0400 Fix (relax) remaining `RSpec/*` cops (#30693) commit 8d5ed19c6deded7b82a0023d078681e8203951a5 Author: Matt Jankowski Date: Fri Jun 14 05:49:10 2024 -0400 Migrate `form_tag` to `form_with` in admin and auth views (#30692) commit a7264a2b42631bd876d114b96f689492e2908a8d Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri Jun 14 11:08:17 2024 +0200 New Crowdin Translations (automated) (#30704) Co-authored-by: GitHub Actions commit e1f8cd5b0fe2509e507d4f03de05e0ef6ddd28cc Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri Jun 14 10:14:00 2024 +0200 chore(deps): update dependency aws-sdk-s3 to v1.152.3 (#30701) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 3d9f00ae167a40835a571a97ea5afcc85ec6e396 Author: Emelia Smith Date: Fri Jun 14 09:54:09 2024 +0200 Fix unsafe URLs in audit log resulting from domain blocks (#27139) Co-authored-by: Claire commit a243963e934123e17519711ce0378eaa7b5f8204 Author: Marcin Mikołajczak Date: Thu Jun 13 21:46:45 2024 +0200 LanguageDropdown: remove unused function (#30346) Signed-off-by: marcin mikołajczak commit 179f7b11bac81479a518504873c980b04d6ca6e5 Author: Michael Stanclift Date: Thu Jun 13 10:58:34 2024 -0500 Build libvips from source in Dockerfile (#30571) commit a66f6e10056333a3ca3466895ef5f8967b1f4a27 Author: Matt Jankowski Date: Thu Jun 13 11:07:02 2024 -0400 Add binstub for `brakeman` (#30493) commit f8ce61d6705699fc509a6677e8df847af77ebac1 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Thu Jun 13 16:37:54 2024 +0200 chore(deps): update dependency nokogiri to v1.16.6 (#30689) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 271a8e99e2666dfb90a8a57c8ef6563279bc406d Author: Matt Jankowski Date: Thu Jun 13 10:37:49 2024 -0400 Update merge conflict rebase action version (silences node version warning) (#30690) commit f0ca874b09e29feda0db3eb50aece86e95192575 Author: Louis Brauer Date: Thu Jun 13 16:37:43 2024 +0200 Include crossorigin in inert css (#30687) commit 3a191b3797dde1daf79cd748a14b87240532d543 Author: Matt Jankowski Date: Thu Jun 13 10:27:17 2024 -0400 Add `rubocop` binstub, simplify configuration (#30407) commit 45abddb302a44adafdcc0479cc93dea4d8fb4b64 Author: Claire Date: Thu Jun 13 16:10:34 2024 +0200 Fix pagination attributes not being returned in ungroupable-only pages (#30688) commit dd587d29b68ee8548cd91697ba85b1ee274845d5 Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu Jun 13 15:30:07 2024 +0200 New Crowdin Translations (automated) (#30684) Co-authored-by: GitHub Actions commit 8889816a51df17e2e78cdcaa17bda0780393bd0d Author: Matt Jankowski Date: Thu Jun 13 09:23:32 2024 -0400 Use stock ruby environment on CI lint tasks (#30657) commit 3b7c50abca213353f6e210837fda0f21baf1be20 Author: Matt Jankowski Date: Thu Jun 13 09:15:32 2024 -0400 Remove bundler-audit ignore config (#30672) commit 474dda70272b9e406fb4a22b1f66caf797c2f8b2 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Thu Jun 13 15:15:01 2024 +0200 chore(deps): update dependency aws-sdk-s3 to v1.152.2 (#30680) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 64fc17352bec11684cf617b10ebc5a11eb7ec924 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Thu Jun 13 15:13:06 2024 +0200 chore(deps): update dependency sanitize to v6.1.1 (#30683) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit ed6d24330ba2f80b99428cb8ee19e5d8400ebd16 Author: Eugen Rochko Date: Thu Jun 13 15:04:16 2024 +0200 Add author links on the explore page in web UI (#30521) commit 37f53542fe1c36c6126932cbb3840f6d4659104e Author: Claire Date: Thu Jun 13 14:42:40 2024 +0200 Fix limit handling in grouped notifications CTE (#30685) commit fe740455767a361798df3a21791f9db8e2056f7e Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Thu Jun 13 10:26:17 2024 +0200 chore(deps): update dependency ruby to v3.3.3 (#30667) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit b379dc156e9a2292f2e21f80543c0b80d4087688 Author: Matt Jankowski Date: Thu Jun 13 04:26:09 2024 -0400 Update parser to version 3.3.3.0 (#30676) commit fc2f49cfbcbe996abeb267592bcf39d60d2995ae Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Thu Jun 13 10:26:00 2024 +0200 chore(deps): update docker.io/ruby docker tag to v3.3.3 (#30679) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 7ad5a3a2b728229704e29819b3b87bc0ccdc473f Author: Renaud Chaput Date: Thu Jun 13 10:21:50 2024 +0200 Disable `consistent-return` eslint rule for Typescript files (#30675) commit bf56e982a9c211396efea16f2ee596102b36db3f Author: Claire Date: Wed Jun 12 15:50:38 2024 +0200 Fix notifications from limited users being outright dropped (#30559) commit a5a15846756dd62e01bf7eb64fdf3b8fafc3ba69 Author: Sujay Date: Wed Jun 12 19:18:30 2024 +0530 Update README.md (#30626) commit 99842434677ef3a01f5c7700d3b67ba5e72cd1a1 Author: Eugen Rochko Date: Wed Jun 12 15:10:51 2024 +0200 Fix a few visual glitches with link previews in web UI (#30670) commit 19f1c081e161bf8ca3325f48f7fe0194827de56a Author: Matt Jankowski Date: Wed Jun 12 08:59:32 2024 -0400 Update `rubocop-rspec` to version 3.0.1 (#30655) commit 54ab70dfcf39e13c055b99a4fc4aea721781af32 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Wed Jun 12 14:42:04 2024 +0200 chore(deps): update yarn to v4.3.0 (#30644) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 0a7249c7c687775c7ab6ef495b259cedff5f25ca Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Wed Jun 12 14:41:14 2024 +0200 fix(deps): update dependency pino to v9.2.0 (#30659) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 47f97e113a1047c067948f385b5179fa0489180f Author: Matt Jankowski Date: Wed Jun 12 07:39:16 2024 -0400 Update the bundler-audit vulnerability DB when running (#30658) commit 9321a454de78dc57d4382f6f366f282a111d2b31 Author: Matt Jankowski Date: Wed Jun 12 07:38:20 2024 -0400 Combine CI migration tests (#30661) commit dff48ff705b8193702cdef149f8cd8748365d48f Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Wed Jun 12 13:04:54 2024 +0200 fix(deps): update dependency sass to v1.77.5 (#30665) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit ced463360e39b92689144e366b6f3a9ceabf1bf7 Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed Jun 12 12:48:31 2024 +0200 New Crowdin Translations (automated) (#30666) Co-authored-by: GitHub Actions commit 1dfd51628416598d2386621b6229a4f169cd360e Author: Claire Date: Wed Jun 12 09:28:28 2024 +0200 Fix duplicate `@context` attribute in user export (#30653) commit cec8e34b250c368ec6c4a5acb75eed311aa901bf Author: Matt Jankowski Date: Tue Jun 11 16:29:00 2024 -0400 Remove unused CI env vars (#30660) commit f214813919309b0b8bda628835029e204d56dd31 Author: Claire Date: Tue Jun 11 19:54:27 2024 +0200 Adapt settings spec to glitch-soc commit 4daed855e5de6d3739e41bb4853ace0cc4ca9405 Merge: 69225367e5 d818ddd687 Author: Claire Date: Tue Jun 11 19:46:11 2024 +0200 Merge commit 'd818ddd6870094e89e58ef61f37da4cb73935856' into glitch-soc/merge-upstream commit d818ddd6870094e89e58ef61f37da4cb73935856 Author: Matt Jankowski Date: Tue Jun 11 11:36:21 2024 -0400 Extract `SIGN_COUNT_LIMIT` constant in `WebauthnCredential` class (#30636) commit 921b0db5440cc6e0bc990d6f0186c43aaa887fe9 Author: Claire Date: Tue Jun 11 17:29:45 2024 +0200 Add `noindex` meta tag and `rel=canonical` link to redirect interstitials (#30651) commit 978601a0ae556c4e214df8f6d73181c2a6359531 Author: Matt Jankowski Date: Tue Jun 11 11:29:41 2024 -0400 Extract permitted params constant in v1/admin/tags (#30652) commit 62d070c438a2cccb6af486a02d8c6839d642c827 Author: Matt Jankowski Date: Tue Jun 11 09:59:56 2024 -0400 Check both before/after state in `AccountDomainBlock` spec (#30640) commit b124dff1748797e54256e1c8161d18513b921458 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Tue Jun 11 15:58:40 2024 +0200 chore(deps): update opentelemetry-ruby (non-major) (#30648) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 328d3a87f5749b5b9ea2c17289fc7a53dbaa6d7b Author: Claire Date: Tue Jun 11 15:58:10 2024 +0200 Fix libvips color extraction when multiple maxima differ only on blue component (#30632) commit f48f39a7679667da51171a77a0e1bcbc7512cd36 Author: David Roetzel Date: Tue Jun 11 14:54:37 2024 +0200 Fix cutoff of instance name (#30598) commit 410370eecdcc6ad7aeac30c48957d3b044e7cabe Author: Matt Jankowski Date: Tue Jun 11 05:40:47 2024 -0400 Extract `PERMITTED_PARAMS` constant from `admin/domain_blocks` controller (#30380) commit 665f6f09a07fa9d1d813e8343f1687b369e7f3dc Author: Matt Jankowski Date: Tue Jun 11 04:50:51 2024 -0400 Add expired/revoked scopes for doorkeeper models via extension modules (#29936) commit 1622f7aeb9e911d43296caef45e17181652c9c0e Author: Matt Jankowski Date: Tue Jun 11 03:48:42 2024 -0400 Remove duplicate fabricator validity checks (#29667) commit 88cfc4056de1f7ab86011eb80b904cd9cd6dc754 Author: Matt Jankowski Date: Tue Jun 11 03:42:15 2024 -0400 Extract method to generate series of days in measure sql classes (#29928) commit edf6d64eebdf4c1651f09c0e314d46b7436b46df Author: Matt Jankowski Date: Tue Jun 11 03:36:46 2024 -0400 Use correct params in `settings/preferences/appearance` spec (#30379) commit b2496177e00af2b9ce73b378233b2ef3de14cbe4 Author: Matt Jankowski Date: Tue Jun 11 03:35:30 2024 -0400 Use correct params in `v1/admin/domain_allows` spec (#30378) commit 0dabda9beec11706fbef8cbf8a141266cc69590c Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue Jun 11 09:14:52 2024 +0200 New Crowdin Translations (automated) (#30646) Co-authored-by: GitHub Actions commit cfd4823b65cc91e758ac9d6d97e367b19ca35691 Author: Matt Jankowski Date: Tue Jun 11 02:57:09 2024 -0400 Use fabricator in follow_spec (#30642) commit ef23abcf617813901e34c5dd9587ef7c88fd754d Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Tue Jun 11 08:55:30 2024 +0200 chore(deps): update dependency aws-sdk-s3 to v1.152.1 (#30643) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 69225367e501e455262853270c9090695509798e Merge: 1b08c43fcd be68f8f4af Author: Claire Date: Tue Jun 11 08:26:22 2024 +0200 Merge pull request #2740 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to 9cc4040308a758d4b77961f4da79cf63a044fffe commit 0e1110c947caf31ae650c73ef35adedebc16b28a Author: Matt Jankowski Date: Mon Jun 10 16:08:04 2024 -0400 Use `SECRET_KEY_BASE_DUMMY` feature as placeholder during asset compilation (#30505) commit be68f8f4af41765ebfdfefc5e249dc0464428471 Merge: 1b08c43fcd 9cc4040308 Author: Claire Date: Mon Jun 10 18:20:08 2024 +0200 Merge commit '9cc4040308a758d4b77961f4da79cf63a044fffe' into glitch-soc/merge-upstream commit 9cc4040308a758d4b77961f4da79cf63a044fffe Author: Matt Jankowski Date: Mon Jun 10 11:23:55 2024 -0400 Extract `COMMENT_SIZE_LIMIT` constant in `AP::Activity::Flag` class (#30637) commit 9bf2e2eda0ffea6382e161f7ebb43d73aaf658ca Author: Matt Jankowski Date: Mon Jun 10 11:23:17 2024 -0400 Extract `TEXT_LENGTH_LIMIT` constant in `Appeal` class (#30638) commit 28921a12fe0033c7231f42e95a2be80628844bb4 Author: Matt Jankowski Date: Mon Jun 10 11:22:26 2024 -0400 Update macOS local dev setup instructions (#30641) commit 3e3f3d75805ec4209e0b12984626a5be0a9ba2e5 Author: Matt Jankowski Date: Mon Jun 10 11:04:01 2024 -0400 Match report validation spec to extracted constant (#30633) commit 92b3004bf31d91c94efae4957234a36aef10da59 Author: Matt Jankowski Date: Mon Jun 10 11:03:41 2024 -0400 Reference constants from account validation specs (#30634) commit 28f9a8f2ecabb0c087e27522217b78da732611c2 Author: Daniel M Brasil Date: Mon Jun 10 11:52:33 2024 -0300 Add Specs for Scheduled Status Model Validations (#30585) commit f0f144e96da62718e849a8dd5cd55ddbc03763ab Author: Yamagishi Kazutoshi Date: Mon Jun 10 23:47:59 2024 +0900 Add `customManagers:dockerfileVersions` to renovate.json5 (#30607) commit bb27321781778d4d849dd0a4c2f16747f85f1a3d Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon Jun 10 16:29:30 2024 +0200 New Crowdin Translations (automated) (#30608) Co-authored-by: GitHub Actions commit 589365ba52b5e982f31c7acbb0a264bc378e061b Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jun 10 16:29:26 2024 +0200 chore(deps): update dependency rubocop-capybara to v2.21.0 (#30611) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit a6e0e167a71025b27719666906cfb5511734134e Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jun 10 16:29:11 2024 +0200 fix(deps): update dependency uuid to v10 (#30624) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit dd4a976122ac1da57ac011f84d71e168ad911cfe Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jun 10 16:08:02 2024 +0200 chore(deps): update devdependencies (non-major) (#30628) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 452872412dd5a3af0ca9186726bf5a5fb8038856 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jun 10 16:07:35 2024 +0200 chore(deps): update dependency @types/lodash to v4.17.5 (#30627) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 2dca6ec77ad8be8674cde103578c416095a3522b Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jun 10 16:05:57 2024 +0200 chore(deps): update dependency oj to v3.16.4 (#30620) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit bfd674d819327b4af3053ec35aea96f0c9e36428 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jun 10 16:04:44 2024 +0200 chore(deps): update dependency httplog to '~> 1.7.0' (#30613) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 801f9feec3d23be013751a3c468356a1c3c6ddf7 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jun 10 15:52:57 2024 +0200 chore(deps): update dependency concurrent-ruby to v1.3.3 (#30605) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 77c2216e47c8ffba4dde91c1a300cf924a8e5c05 Author: Daniel M Brasil Date: Mon Jun 10 10:33:48 2024 -0300 fix: Return HTTP 422 when scheduled status time is less than 5 minutes (#30584) commit 0cf91213c93e87ce775453ae20a3d9a7f9b4e8d0 Author: Matt Jankowski Date: Mon Jun 10 02:32:20 2024 -0400 Opt in to remaining Rails 7.1 defaults (#30332) Co-authored-by: Claire commit 1b08c43fcdbab724386051c6254c20345bd3a63e Merge: 4c55a6ee73 57959642e3 Author: Claire Date: Sun Jun 9 18:57:25 2024 +0200 Merge pull request #2735 from glitch-soc/i18n/crowdin/translations New Crowdin Translations (automated) commit 57959642e3fb278b55f8321156fb54e8bdba6a29 Author: Claire Date: Sun Jun 9 18:33:41 2024 +0200 Fix bogus translations commit 33b3330dc767f1765d777cb62a7d96830b3385c3 Author: GitHub Actions Date: Sun Jun 9 04:29:04 2024 +0000 New Crowdin translations commit 827e36ff9ee22ec58c64322c0a9d78eaa2dd4875 Author: Matt Jankowski Date: Sat Jun 8 13:10:06 2024 -0400 Fix `Capybara/NegationMatcher` cop in spec/system (#30616) commit 4c55a6ee739e5c7fad4914cd078219345023bec7 Merge: e65958b592 ac3d761c78 Author: Claire Date: Sat Jun 8 14:41:10 2024 +0200 Merge pull request #2730 from mayafri/fixes/collapsed-toots-gradient light theme: fix gradient for collapsed toots commit e65958b5929352d623a168907aa9aea26d7c1e2d Merge: 905e9fab97 82fcb55680 Author: Claire Date: Sat Jun 8 14:19:21 2024 +0200 Merge pull request #2733 from ClearlyClaire/glitch-soc/fixes/crowdin-workflow Fix crowdin upload workflow not triggering on glitch-soc source string changes commit 82fcb55680a31797a8e9a4f8c51c97b4ba78dbe9 Author: Claire Date: Sat Jun 8 13:49:02 2024 +0200 Fix crowdin upload workflow not triggering on glitch-soc source string changes commit 905e9fab973f3e1df486a1c75706db9fa3d4b4bd Merge: 49f292d09a 01a9b37c20 Author: Claire Date: Sat Jun 8 13:42:34 2024 +0200 Merge pull request #2696 from glitch-soc/i18n/crowdin/translations New Crowdin Translations (automated) commit 01a9b37c209439b674fda283bc65d94466f20fb6 Author: Claire Date: Sat Jun 8 13:28:41 2024 +0200 Fix bogus translations commit 6952af137d17f65e65963e4d9ba129060fad9d3d Author: Matt Jankowski Date: Sat Jun 8 06:33:28 2024 -0400 Install from nvmrc during devcontainer Dockerfile build (#30603) commit c1a84f1b5b85e98c78847ddf03d1490300bcdc9d Author: Matt Jankowski Date: Sat Jun 8 06:32:39 2024 -0400 Case correction `Github` -> `GitHub` (#30446) Co-authored-by: Igor commit 49f292d09a4f100b21c7f27025e3a36f9fab3a14 Merge: b2e7af830b 7277d2f130 Author: Claire Date: Sat Jun 8 11:02:26 2024 +0200 Merge pull request #2732 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to 496c10542bd39ca86a85d4de81778c134ea4383c commit aab5b10c385168a6e47b985675f9e72ff020e8d1 Author: GitHub Actions Date: Sat Jun 8 04:29:18 2024 +0000 New Crowdin translations commit 521b43393350be16fbd1aa003607480c2442f3eb Author: Matt Jankowski Date: Fri Jun 7 16:18:02 2024 -0400 Doc updates for Docker/devcontainers/codespace (#30582) commit 7277d2f1302a940dc5063a8b6697eedc752b52c6 Merge: b2e7af830b 496c10542b Author: Claire Date: Fri Jun 7 20:30:51 2024 +0200 Merge commit '496c10542bd39ca86a85d4de81778c134ea4383c' into glitch-soc/merge-upstream commit 496c10542bd39ca86a85d4de81778c134ea4383c Author: Claire Date: Fri Jun 7 19:42:43 2024 +0200 Fix division by zero on some video/GIF files (#30600) commit 82be5d033f9a5e9335d4efee6008439c7770f102 Author: Claire Date: Fri Jun 7 17:39:41 2024 +0200 Improve handling of libvips failures (#30597) commit 80cd001e0aa876b690c6862e2f9cbb945074f2ff Author: Claire Date: Fri Jun 7 16:32:29 2024 +0200 Fix linting issue (#30595) commit 4f6cc547d0a7828d036d22f320b9c078e492a9c4 Author: Matt Jankowski Date: Fri Jun 7 09:55:55 2024 -0400 Align root/vscode user dynamic for codespaces with non-codespaces config (#30593) commit 773283ffb9d227d7768d3c32a1a4bf556f0fb0a3 Author: Isa S Date: Fri Jun 7 15:54:55 2024 +0200 Make S3's retry limit a ENV variable (#23215) commit 9e9613b2864062ce4174ae02db3f94629ebdca0e Author: Claire Date: Fri Jun 7 15:45:11 2024 +0200 Fix `mentions.account_id` and `mentions.status_id` not having `NOT NULL` database constraints (#30591) commit 37e4d96b70b46fb0994af23eefd6a77498895ba3 Author: Matt Jankowski Date: Fri Jun 7 08:39:53 2024 -0400 Restore `verbose` option to media remove cli (#30536) commit 299ae9bf922401751dc2a4dd50739a0391e0863a Author: Victor Dyotte Date: Fri Jun 7 08:29:30 2024 -0400 Add `S3_KEY_PREFIX` environment variable (#30181) commit bc01b328a10cdf93e098fd016feb26b01cc58bdb Author: Matt Jankowski Date: Fri Jun 7 08:21:38 2024 -0400 Dont include peer dirs in devcontainer compose config (#30592) commit 3d058f898a8e029b8e0d007f4528b2ae878b8fc4 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri Jun 7 12:37:50 2024 +0200 chore(deps): update dependency rubocop-rspec to v2.31.0 (#30588) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit a5e3b814a207365edfcf1f625c1594774f936ab4 Author: Matt Jankowski Date: Fri Jun 7 06:00:51 2024 -0400 Remove Status/ivar/shapes regression check from test env (#30580) commit 3dfc7267e20aab8e5e72adffbf1ef4773811c068 Author: Matt Jankowski Date: Fri Jun 7 06:00:27 2024 -0400 Rename deprecated config option to `enable_reloading` in dev env (#30577) commit c1b0c1a5e40c277b4b1f036fa882d90f0882cd67 Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri Jun 7 11:59:30 2024 +0200 New Crowdin Translations (automated) (#30586) Co-authored-by: GitHub Actions commit ce07394ed5e9e5728db7da59910fbd83bc4a38ea Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri Jun 7 11:53:59 2024 +0200 chore(deps): update dependency aws-sdk-s3 to v1.152.0 (#30572) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 1408733386219e1588c14d2fbf9f3c926513a5a3 Author: Claire Date: Fri Jun 7 11:27:59 2024 +0200 Fix Mastodon relying on ImageMagick even with `MASTODON_USE_LIBVIPS` (#30590) commit 8041fa174b7c90c1c130342aede2d556e8f56e82 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri Jun 7 09:39:01 2024 +0200 chore(deps): update opentelemetry-ruby (non-major) (#30555) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit ac3d761c7811d39534a829825c073e033b250867 Author: Maya Friedrichs <_@maya.sh> Date: Fri Jun 7 00:23:18 2024 +0200 Remove gradient for collapsed toots This gradient is already set in `components.scss` with the new background commit 3495f0d9ba37ec10189ce1df60921f15554224d5 Author: Matt Jankowski Date: Thu Jun 6 16:33:28 2024 -0400 Use corepack yarn in `bin/setup` (#30573) commit 94d8d1094f32fcdd2372533efde9ad0e129020fc Author: Matt Jankowski Date: Thu Jun 6 16:29:16 2024 -0400 Provide richer failure information in `bin/setup` (#30581) commit b2e7af830bed1d632cdefa31dbf2d035b94775c2 Merge: 2a34c9a01e 578b0eae7d Author: Claire Date: Thu Jun 6 19:54:29 2024 +0200 Merge pull request #2727 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to 5652ca613582df03e5b838626078981414f3b897 commit 12823908bbc101dc3106ae0fd1b804ef164390ac Author: Matt Jankowski Date: Thu Jun 6 10:19:55 2024 -0400 Adjust devcontainers welcome message to be less codespaces-specific (#30566) commit 04ebbe3077e7f39025428bfa596ada2d21be6dfb Author: Matt Jankowski Date: Thu Jun 6 10:19:37 2024 -0400 Add `sidekiq_inline` to appeal service spec (#30562) commit 07cc94e05fa89794714fb0434529657dfa992bca Author: Matt Jankowski Date: Thu Jun 6 10:19:22 2024 -0400 Use `sidekiq_inline` in requests/api/v1/admin/account_actions spec (#30563) commit 9b9b0e25b6839d162d96a19407611e9fc8192c81 Author: Matt Jankowski Date: Thu Jun 6 10:14:33 2024 -0400 Use `sidekiq_inline` in requests/api/v1/reports spec (#30564) commit a662c6d1d82fbc0bb27a2d0a55c1a1c028c16dea Author: Matt Jankowski Date: Thu Jun 6 10:12:58 2024 -0400 Use `sidekiq_inline` in admin/account_action model spec (#30565) commit 1ffc293b86fa373beada17fbe789b0e729781e07 Author: Claire Date: Thu Jun 6 16:12:06 2024 +0200 Add missing `moderation_warning` notification support to grouped notifications API (#30576) commit 578b0eae7d411a7b717adaf2ec280c4b1c33c265 Author: Claire Date: Thu Jun 6 12:51:39 2024 +0200 Fix /api/v1/timelines/link specs for glitch-soc default settings commit 30b00ca2b5c7992314697344d0d9e714a6360cea Merge: 2a34c9a01e 5652ca6135 Author: Claire Date: Thu Jun 6 12:27:26 2024 +0200 Merge commit '5652ca613582df03e5b838626078981414f3b897' into glitch-soc/merge-upstream commit 5652ca613582df03e5b838626078981414f3b897 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Thu Jun 6 11:27:54 2024 +0200 fix(deps): update babel monorepo to v7.24.7 (#30561) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit cd4b00810d49bb95b6421c84d48a6e075a18486c Author: Fabio Leandro Janiszevski Date: Thu Jun 6 06:00:09 2024 -0300 Clear the docker setup - Deprecate post-create.sh and use bin/setup (#30502) commit a729104a4159106f959bcc9b3ab438d2876ce9a5 Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu Jun 6 10:53:28 2024 +0200 New Crowdin Translations (automated) (#30575) Co-authored-by: GitHub Actions commit 2f0a34ac00f2d3cc561cd4fe3edbcf2bd62c35a8 Author: Matt Jankowski Date: Thu Jun 6 04:49:31 2024 -0400 Run as root in devcontainer from vscode (#30574) commit a2505e861150abda0e692ffe86178393d701bc93 Author: Eugen Rochko Date: Thu Jun 6 10:43:04 2024 +0200 Add timeline of public posts about a trending link to REST API (#30381) commit d72714e5ce5a7146665ad833f760dba82ad7a0cd Author: Matt Jankowski Date: Thu Jun 6 03:50:31 2024 -0400 Remove deprecated version value from `.devcontainer/docker-compose.yml` (#30567) commit 2fdd782f21a0d07b5c658c0e0f467c5b5622988a Author: Matt Jankowski Date: Thu Jun 6 03:50:15 2024 -0400 Fix empty `aria-hidden` attribute value in logo resources area (#30570) commit e02d23b5499318432981b16d8968e109ebeca18c Author: Emelia Smith Date: Thu Jun 6 09:30:10 2024 +0200 Change `read:me` scope to `profile` scope (#30357) Co-authored-by: Claire commit 569b7d2f25da120473937ab5719eba5ab0e314e1 Author: Matt Jankowski Date: Wed Jun 5 19:54:59 2024 -0400 Clarify the purpose of separate Docker resources (#30568) commit 3c435f9ba0d3a1a0a07722718eee26cf10ff55b6 Author: Eugen Rochko Date: Thu Jun 6 01:52:46 2024 +0200 Change counters to be displayed on profile timelines in web UI (#30525) commit 4655be0da6c0f9a58f4d09a32189cbe5619c42d1 Author: Emelia Smith Date: Wed Jun 5 21:16:47 2024 +0200 Fix add validation to webpush subscription keys (#30542) commit 5f15a892fa4f01ef9bcf223ec6798b8a9d9945ed Author: Eugen Rochko Date: Wed Jun 5 21:15:39 2024 +0200 Add support for libvips in addition to ImageMagick (#30090) Co-authored-by: Claire commit 20e490ba7e996033c549e6d1de7826b86ac2988d Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Wed Jun 5 15:06:03 2024 +0200 fix(deps): update dependency cssnano to v7.0.2 (#30560) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit eef2cc054faaa808cb014d644317fbc398f6c75f Author: Emelia Smith Date: Wed Jun 5 10:06:06 2024 +0200 Add url validation to Web::PushSubscription endpoints (#30540) commit 048f9b9d45b1d313de1d427956a2d354273a5d85 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Wed Jun 5 09:56:52 2024 +0200 chore(deps): update dependency pghero to v3.5.0 (#30393) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit e4e3875452c13dd76d9aee5e33e7d1e59629a1ff Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed Jun 5 09:52:25 2024 +0200 New Crowdin Translations (automated) (#30543) Co-authored-by: GitHub Actions commit f3893ae65de540fac9a6aed5bd6bc50affaf5d26 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Wed Jun 5 07:23:19 2024 +0000 chore(deps): update dependency rubocop-rspec to v2.30.0 (#30529) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 1d3b75d124ddcf7bf1148a2a0cacc0b8f82d6340 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Wed Jun 5 07:22:58 2024 +0000 fix(deps): update dependency pg to v8.12.0 (#30549) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit f40f3cb82e2bf18670e25a1d1675a6f8a202257d Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Wed Jun 5 09:22:02 2024 +0200 chore(deps): update dependency rails to v7.1.3.4 (#30551) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit e5984c95ebdae71b8323dd0c984cb7096d7f3d75 Author: Filippo Giunchedi Date: Tue Jun 4 22:28:05 2024 +0200 Add libvirt provider parameters to Vagrant (#28102) Co-authored-by: Filippo Giunchedi commit 7d9a8c959692fb7121d154412312a7f8e3005186 Author: Michael Stanclift Date: Tue Jun 4 12:30:22 2024 -0500 Set Devcontainer to Ruby 3.3 Bookworm (#30548) commit 9ab7e66caeb68df565b47f024ad69a7d29a49e8c Author: Nick Schonning Date: Tue Jun 4 13:29:08 2024 -0400 Cleanup leftover Nanobox references (#30550) commit d4e094987e530fb0e0fe35e57b8dd00bb919a770 Author: Matt Jankowski Date: Mon Jun 3 11:16:46 2024 -0400 Use bundler version 2.5.11 (#30508) commit 91b6502d827e1eea28e18d30930c2b31be89cdd7 Author: Shlee Date: Mon Jun 3 19:16:11 2024 +1000 Revert "Revert "Change default ruby version to 3.3.2 (#30478)"" (#30516) commit 249cbc449c301aef2a21117138d140efb17b0d96 Author: Matt Jankowski Date: Mon Jun 3 05:15:58 2024 -0400 Use existing config access to `local_domain` value (#30509) commit 974335e4144eab90a8c5eb91da55d2f8385c68c6 Author: Claire Date: Mon Jun 3 10:35:59 2024 +0200 Add experimental server-side notification grouping (#29889) commit db49b0e5e92e1bb54a579b407b1bf9bcee6d4e4e Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jun 3 09:35:11 2024 +0200 chore(deps): update eslint (non-major) (#30527) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 6e92a9b73e9093a85679841081d60a143261050d Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Jun 3 09:35:06 2024 +0200 chore(deps): update devdependencies (non-major) (#30526) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit aa9b80f57d1fb1f1b75abb28db3f915829f6b9f9 Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon Jun 3 09:34:33 2024 +0200 New Crowdin Translations (automated) (#30517) Co-authored-by: GitHub Actions commit 469de923aa568dd96a6358445fc98870f7f08755 Author: Matt Jankowski Date: Mon Jun 3 03:16:29 2024 -0400 Update `current_user` override mode description in controllers (#30515) commit 4d3748ac447c7e43fcfcc36ffcd4f97afeeead46 Author: Matt Jankowski Date: Mon Jun 3 03:16:01 2024 -0400 Fix rack attack `match_type` value typo in logging config (#30514) commit d326ad0ed9a2e874213c9313f25b973638e4b94d Author: Renaud Chaput Date: Fri May 31 17:18:51 2024 +0200 Revert "Change default ruby version to 3.3.2 (#30478)" (#30506) commit e20a57909e4d39401f410ca1811adf2357092687 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri May 31 13:29:37 2024 +0000 chore(deps): update dependency propshaft to v0.9.0 (#30382) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 64d69eb95b7f149d10c03059f8c79b24499f461d Author: Shlee Date: Fri May 31 23:26:43 2024 +1000 Change default ruby version to 3.3.2 (#30478) commit 4d047b95aed493bc29e36b6958bfe362607507c6 Author: Matt Jankowski Date: Fri May 31 05:54:11 2024 -0400 Use more direct attribute handling in `User` fabricator (#30495) commit a22865a352cca312a50556fd38ce2d5764ecc4dc Author: Matt Jankowski Date: Fri May 31 05:35:56 2024 -0400 Add `:email` to filter parameter logging config (#30492) commit dac4eba46b918e7be1153c7acf6b6f62ca644f59 Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri May 31 11:26:52 2024 +0200 New Crowdin Translations (automated) (#30499) Co-authored-by: GitHub Actions commit 543fa2691626174b1dbed3af13e2e3c0e9e2294a Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri May 31 11:26:40 2024 +0200 fix(deps): update dependency sass to v1.77.4 (#30496) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 9533a8632b5059f7e089f020c0e2fe00c798f640 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri May 31 11:26:31 2024 +0200 chore(deps): update dependency ruby to v3.3.2 (#30480) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit ced700743670372677affb7b7da811d04abbdf77 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri May 31 11:08:31 2024 +0200 chore(deps): update dependency rubocop to v1.64.1 (#30500) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 85d9053b36674ebf1b4fdefa0028d5784b1845c7 Author: Matt Jankowski Date: Thu May 30 10:56:48 2024 -0400 Move `pagination_params` into `API::BaseController` (#28845) commit a0b525e50b0e53a0def7d5f4abea68737ff327f1 Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu May 30 16:54:51 2024 +0200 New Crowdin Translations (automated) (#30477) Co-authored-by: GitHub Actions commit 00f4d9ddea4cb417a26ab547813b586a24c91e55 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Thu May 30 16:43:35 2024 +0200 chore(deps): update dependency node to 20.14 (#30459) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit a1430b710507d676716a62d042babdb3f6159c4a Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Thu May 30 14:42:13 2024 +0000 chore(deps): update dependency concurrent-ruby to v1.3.1 (#30473) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit ad3e200bf7aa34ac7618d37532ced6a939a3e3bf Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Thu May 30 16:41:29 2024 +0200 fix(deps): update dependency sass to v1.77.3 (#30476) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 2a34c9a01e921b7e5771e11a83c6187ca3db5f31 Merge: 521bccb476 b8271f20c5 Author: Claire Date: Thu May 30 16:00:17 2024 +0200 Merge pull request #2721 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to 7f808ff6e9148f1cfe1e16d000e2405b6e31f243 commit b8271f20c513f0558b3c0a842d7a5f2f28fa2795 Merge: 521bccb476 7f808ff6e9 Author: Claire Date: Thu May 30 15:41:31 2024 +0200 Merge commit '7f808ff6e9148f1cfe1e16d000e2405b6e31f243' into glitch-soc/merge-upstream commit 7f808ff6e9148f1cfe1e16d000e2405b6e31f243 Author: Claire Date: Thu May 30 15:34:46 2024 +0200 Bump version to v4.3.0-alpha.4 (#30482) commit 73a78cc19d0bff68425678c6b4c0ee0fc0a0f528 Author: Claire Date: Thu May 30 14:56:18 2024 +0200 Fix rate-limiting incorrectly triggering a session cookie on most endpoints (#30483) commit 3fa0dd0b88bae1aeb505195044951eb9eebe90f1 Author: Claire Date: Thu May 30 14:24:29 2024 +0200 Merge pull request from GHSA-c2r5-cfqr-c553 * Add hardening monkey-patch to prevent IP spoofing on misconfigured installations * Remove rack-attack safelist commit 16249946aea0db8a74748909d65c94742482dcb7 Author: Claire Date: Thu May 30 14:14:04 2024 +0200 Merge pull request from GHSA-q3rg-xx5v-4mxh commit 3ea4275ae3b7dc2b75e7a2db09b13576b49cec7a Author: Claire Date: Thu May 30 14:03:13 2024 +0200 Merge pull request from GHSA-5fq7-3p3j-9vrf commit 521bccb47616966ef49e7ef964eea34b3cb7a347 Merge: 60c2310fd8 4069fae10d Author: Claire Date: Thu May 30 12:10:09 2024 +0200 Merge pull request #2720 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to d20a5c3ec9ed40a991245fe32d0acb6187dd48c4 commit 4069fae10d548ddfb7d030890224b868982f57fd Author: Eugen Rochko Date: Wed May 29 01:34:33 2024 +0200 [Glitch] Add support for `fediverse:creator` OpenGraph tag Port 128987ededcbcdf73529d98a4f11c747b2bbe892 to glitch-soc Signed-off-by: Claire commit 2e3d6e451faeb8ee248a309c294f797586551bc6 Author: Renaud Chaput Date: Mon May 27 11:24:59 2024 +0200 [Glitch] Enable stricter Typescript options Port 3750e8050cb4a5707e76dfb8f49687cc0984f67f to glitch-soc Signed-off-by: Claire commit 6b4c182806b141d432f4e25a194e15aacb421128 Author: Renaud Chaput Date: Mon May 27 11:00:40 2024 +0200 [Glitch] Fix `createDataLoadingThunk` to allow actions without arguments Port 6a75e1c8c82a1625867ea69be3d0c55697448f4e to glitch-soc Signed-off-by: Claire commit c827a98f197122e97aede071e93060d3a0d37990 Merge: 60c2310fd8 d20a5c3ec9 Author: Claire Date: Wed May 29 17:03:24 2024 +0200 Merge commit 'd20a5c3ec9ed40a991245fe32d0acb6187dd48c4' into glitch-soc/merge-upstream Conflicts: - `yarn.lock`: Not a real conflict, just a line adjacent to a glitch-soc only dependency getting updated. Updated dependencies as upstream did. commit d20a5c3ec9ed40a991245fe32d0acb6187dd48c4 Author: Emelia Smith Date: Wed May 29 16:00:05 2024 +0200 Fix: remove broken OAuth Application vacuuming & throttle OAuth Application registrations (#30316) Co-authored-by: Claire commit 6eea83211c049e416d24f394039a74bc60450cd7 Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed May 29 13:12:23 2024 +0200 New Crowdin Translations (automated) (#30464) Co-authored-by: GitHub Actions commit 41729313e23bc4305cf0e7536d49af2490477c32 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Wed May 29 11:34:36 2024 +0200 chore(deps): update dependency faker to v3.4.1 (#30463) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 36fe8f85667717e78740a9fed3c2bf116a96da1e Author: Claire Date: Wed May 29 11:19:17 2024 +0200 Change `ids` param to `id` in `/api/v1/statuses` and `/api/v1/accounts` for consistency (#30465) commit 5d7d23999ca0fffc3012d84b89fc9d3e66099115 Author: Claire Date: Wed May 29 10:15:06 2024 +0200 Fix leaking Elasticsearch connections in Sidekiq processes (#30450) commit 128987ededcbcdf73529d98a4f11c747b2bbe892 Author: Eugen Rochko Date: Wed May 29 01:34:33 2024 +0200 Add support for `fediverse:creator` OpenGraph tag (#30398) commit 4a77e477ee50f69160cecec25a68ee88b53dfcf8 Author: Matt Jankowski Date: Tue May 28 10:11:31 2024 -0400 Consolidate account scopes for `LOWER` (index using) username/domain queries (#30451) commit 32c30bf0fdc8c0d57f4e272a7827daa39faa6313 Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue May 28 10:05:37 2024 +0200 New Crowdin Translations (automated) (#30452) Co-authored-by: GitHub Actions commit ed99923138311fa07d4185a9132c72e618fd21fd Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon May 27 11:57:19 2024 +0200 chore(deps): update eslint (non-major) (#30444) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit c61e356475cf5df85f067a951abf404b93795f19 Author: Matt Jankowski Date: Mon May 27 05:49:44 2024 -0400 Add `Status::MEDIA_ATTACHMENTS_LIMIT` configuration constant (#30433) commit 87156f57b5b7b71be8a40e9cc568a87583b55144 Author: Nick Schonning Date: Mon May 27 05:41:45 2024 -0400 Enable Style/StringConcatenation (#30428) commit 0ef5dc2b2047361c79fde8a3ee3c4683d7541034 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon May 27 11:40:37 2024 +0200 fix(deps): update dependency jsdom to v24.1.0 (#30431) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 15480643e11b32536d9da736ad5cf357ccfb8405 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon May 27 11:36:59 2024 +0200 chore(deps): update dependency @types/react to v18.3.3 (#30441) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit e5c3dc33a29d9f104b7101fb872da52114a38112 Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon May 27 11:35:45 2024 +0200 New Crowdin Translations (automated) (#30421) Co-authored-by: GitHub Actions commit 1034f13f57ec98f316e2b356957d01992371b59d Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon May 27 11:25:55 2024 +0200 chore(deps): update devdependencies (non-major) (#30442) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 3750e8050cb4a5707e76dfb8f49687cc0984f67f Author: Renaud Chaput Date: Mon May 27 11:24:59 2024 +0200 Enable stricter Typescript options (#30435) commit 564ebfefcf1deb79b38422dfadbc9d5023eca4b6 Author: Matt Jankowski Date: Mon May 27 05:20:28 2024 -0400 Remove hard reference from status pin validator spec (#30432) commit 404e203d41bc47e78a2265368b6caaad084dbb16 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon May 27 11:19:44 2024 +0200 chore(deps): update dependency simple_form to v5.3.1 (#30416) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 6a75e1c8c82a1625867ea69be3d0c55697448f4e Author: Renaud Chaput Date: Mon May 27 11:00:40 2024 +0200 Fix `createDataLoadingThunk` to allow actions without arguments (#30439) commit 60c2310fd879885755c620b060828e3d6a560e0b Merge: ef01546957 1a2a28eb4a Author: Claire Date: Sat May 25 19:26:23 2024 +0200 Merge pull request #2719 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to ccb6aeddacbab950d7d7f1b0d2b64212d7aa99eb commit a5c808e9b033eeb605dcf6b36dc14ddb1127db7b Author: Julius Rajala Date: Fri May 24 19:39:03 2024 +0300 Fix issue with post-create scripts failing on local docker (#28402) commit 1a2a28eb4af996b6277de11da7b217de903ab508 Author: Claire Date: Fri May 24 17:13:34 2024 +0200 Fix rubocop warnings commit e947f1f2ed005ec764a1ddbc53965cece533a62f Author: Renaud Chaput Date: Fri May 24 10:25:42 2024 +0200 [Glitch] Fix a leftover argument to `api()` Port 8ea2726376ed9507072a8e2ec07fdfc219264dad to glitch-soc Signed-off-by: Claire commit d76106da129056bc2731d647e7d47cb5ca478b0f Merge: ef01546957 ccb6aeddac Author: Claire Date: Fri May 24 17:08:21 2024 +0200 Merge commit 'ccb6aeddacbab950d7d7f1b0d2b64212d7aa99eb' into glitch-soc/merge-upstream commit ccb6aeddacbab950d7d7f1b0d2b64212d7aa99eb Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri May 24 16:44:03 2024 +0200 fix(deps): update babel monorepo to v7.24.6 (#30415) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 33350cde96187c7356eadfe19a0d602045b0dcbb Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri May 24 16:44:00 2024 +0200 chore(deps): update dependency webmock to v3.23.1 (#30414) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit acc77c3836974473e7c6a423cbd1138479ae197a Author: Renaud Chaput Date: Fri May 24 15:13:23 2024 +0200 Add instrumentation to the search services (#30350) commit 8394a150d787bb9334993ef2ba1e79c9d213be78 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri May 24 11:01:42 2024 +0200 chore(deps): update dependency rubocop to v1.64.0 (#30404) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 9b5055d34dfd079a76493467236d5b4c1496a9a7 Author: Matt Jankowski Date: Fri May 24 04:36:21 2024 -0400 Fix `Style/SuperArguments` cop (#30406) commit 9305caf1fd5aaeba5c4d980a282c5ca415a7de5c Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri May 24 08:27:11 2024 +0000 fix(deps): update dependency glob to v10.4.1 (#30411) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 54351d01f209447448c57782a034e07968b56a59 Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri May 24 08:26:38 2024 +0000 New Crowdin Translations (automated) (#30410) Co-authored-by: GitHub Actions commit 52a7d053ffc82572d460974b6dde3c6ed776e592 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri May 24 10:26:07 2024 +0200 fix(deps): update dependency postcss-preset-env to v9.5.14 (#30409) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 8ea2726376ed9507072a8e2ec07fdfc219264dad Author: Renaud Chaput Date: Fri May 24 10:25:42 2024 +0200 Fix a leftover argument to `api()` (#30405) commit ef0154695739b0776dc9df64f777ad69f1fe4156 Merge: 6f884b6305 e32bfad88a Author: Claire Date: Thu May 23 22:41:09 2024 +0200 Merge pull request #2718 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to b6fd14f0e2842eca269ef8962e3c5bd560a76357 commit e32bfad88a76a1acd42e56c0ad2f83cdfe535aff Author: Renaud Chaput Date: Thu May 23 20:22:42 2024 +0200 [Glitch] Fix `createDataLoadingThunk` and related actions Port b6fd14f0e2842eca269ef8962e3c5bd560a76357 to glitch-soc Signed-off-by: Claire commit 8d6058b40a8953e16338b57f5ba0e17fc07a1bd2 Author: Renaud Chaput Date: Thu May 23 11:50:13 2024 +0200 [Glitch] Proposal: a modern & typed way of writing Redux actions doing API requests Port 10ec421dd4e0da987e69a3dd7f4f696f9c5878e0 to glitch-soc Signed-off-by: Claire commit 51631c785f3cc396bd70939d9131a1431b9f4e39 Merge: c465ef7560 b6fd14f0e2 Author: Claire Date: Thu May 23 20:30:23 2024 +0200 Merge commit 'b6fd14f0e2842eca269ef8962e3c5bd560a76357' into glitch-soc/merge-upstream Conflicts: - `app/lib/activitypub/parser/status_parser.rb`: Glitch-soc had changes to adjacent lines. Ported upstream's changes. commit b6fd14f0e2842eca269ef8962e3c5bd560a76357 Author: Renaud Chaput Date: Thu May 23 20:22:42 2024 +0200 Fix `createDataLoadingThunk` and related actions (#30408) commit c465ef75602d1b9c92d640de9971a2798355585f Author: Renaud Chaput Date: Thu May 23 09:30:48 2024 +0200 [Glitch] Fix some API calls that should not use an API token Port 15d307075479cf93ea199be0f25820003ddbe27c to glitch-soc Signed-off-by: Claire commit 0e8633f6c7208066cbb97b55a2ec1053ef0124dc Merge: 6f884b6305 3a862439df Author: Claire Date: Thu May 23 20:11:12 2024 +0200 Merge commit '3a862439dfc989c6c5741e007c2f4e0335fffe33' into glitch-soc/merge-upstream commit 133d98fb25e623745326945b3800173c27519d57 Author: Claire Date: Thu May 23 19:28:18 2024 +0200 Normalize language code of incoming posts (#30403) commit 10ec421dd4e0da987e69a3dd7f4f696f9c5878e0 Author: Renaud Chaput Date: Thu May 23 11:50:13 2024 +0200 Proposal: a modern & typed way of writing Redux actions doing API requests (#30270) commit 3a862439dfc989c6c5741e007c2f4e0335fffe33 Author: Matt Jankowski Date: Thu May 23 04:26:58 2024 -0400 Remove unused account record in api/v2/admin/accounts spec (#30397) commit 5b5a35cf96de51b5ef44f69dcde1e3dc2acb9dd6 Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu May 23 10:26:29 2024 +0200 New Crowdin Translations (automated) (#30402) Co-authored-by: GitHub Actions commit 15d307075479cf93ea199be0f25820003ddbe27c Author: Renaud Chaput Date: Thu May 23 09:30:48 2024 +0200 Fix some API calls that should not use an API token (#30401) commit 6f884b63055f5477733bf956641a10ee438f8af6 Merge: 65db9dec2e 3e9298370d Author: Claire Date: Wed May 22 22:04:05 2024 +0200 Merge pull request #2717 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to 2c5ab8f647841ea8075ece50ccc9e12c21af8720 commit 3e9298370dafb0e7c7a1bc34e524266e96fd50b5 Author: Renaud Chaput Date: Wed May 22 16:45:18 2024 +0200 [Glitch] Remove the access token from Redux & context Port 2c5ab8f647841ea8075ece50ccc9e12c21af8720 to glitch-soc Signed-off-by: Claire commit 22d12229b260c57d598ddd276c4354c7dc83b702 Merge: 65db9dec2e 2c5ab8f647 Author: Claire Date: Wed May 22 21:05:19 2024 +0200 Merge commit '2c5ab8f647841ea8075ece50ccc9e12c21af8720' into glitch-soc/merge-upstream commit 2c5ab8f647841ea8075ece50ccc9e12c21af8720 Author: Renaud Chaput Date: Wed May 22 16:45:18 2024 +0200 Remove the access token from Redux & context (#30275) commit 2c75cf85991bd0c22eaabe4ccd3bfb658ec59d32 Author: Michael Stanclift Date: Wed May 22 04:05:33 2024 -0500 Add "Warning preset" link to admin navigation (#26199) commit a2b4c29c8fc8b7db163afffe1987fc4a41b574cb Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed May 22 09:57:51 2024 +0200 New Crowdin Translations (automated) (#30394) Co-authored-by: GitHub Actions commit d9d4ba1b6f2756e819344b384d731c7722a931b5 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Wed May 22 09:47:49 2024 +0200 fix(deps): update dependency glob to v10.3.16 (#30392) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 6e67ca73f3b32bbac226b77f78acce52c525307b Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Wed May 22 09:35:27 2024 +0200 fix(deps): update dependency axios to v1.7.2 (#30372) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 65db9dec2eec25403708f110c8a3be9df37bc165 Merge: 40a3a3f3d8 dc35563f65 Author: Claire Date: Tue May 21 20:04:34 2024 +0200 Merge pull request #2716 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to cd0c5479362260082dbe1cbc42e364017853bbfc commit dc35563f65e3c843b847c6d58797937200e27233 Author: David Lapshin Date: Tue May 21 18:24:51 2024 +0300 [Glitch] Fix announcements icon rotating like settings one Port cd0c5479362260082dbe1cbc42e364017853bbfc to glitch-soc Signed-off-by: Claire commit 5ab111554e10f971b376e0a20f0c3259c4892912 Merge: 40a3a3f3d8 cd0c547936 Author: Claire Date: Tue May 21 17:45:21 2024 +0200 Merge commit 'cd0c5479362260082dbe1cbc42e364017853bbfc' into glitch-soc/merge-upstream commit 40a3a3f3d8cc43ff201801a0fdbbef54c9e05c0b Merge: e853355f24 edf6ca56e3 Author: Claire Date: Tue May 21 17:44:40 2024 +0200 Merge pull request #2715 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to 89f89d738f5840c80ff938f8bf6734cdafe0fa83 commit cd0c5479362260082dbe1cbc42e364017853bbfc Author: David Lapshin Date: Tue May 21 18:24:51 2024 +0300 Fix announcements icon rotating like settings one (#30388) commit 32223863a51472d929c57d22dbffc5d9c9fafa79 Author: Claire Date: Tue May 21 15:17:34 2024 +0200 Add coverage to `/admin/accounts/:id` (#30386) commit edf6ca56e369ebc7997f4f67a411afacf5e33911 Author: Claire Date: Tue May 21 13:00:07 2024 +0200 Fix rubocop error and cleanup `Status.as_direct_timeline` a little commit d3136e6d581920d7e20b8cf71e5575bf95654af4 Merge: e853355f24 89f89d738f Author: Claire Date: Tue May 21 12:06:38 2024 +0200 Merge commit '89f89d738f5840c80ff938f8bf6734cdafe0fa83' into glitch-soc/merge-upstream commit 89f89d738f5840c80ff938f8bf6734cdafe0fa83 Author: Claire Date: Tue May 21 10:56:08 2024 +0200 Revert "Allow unblocking email addresses from any matching account (#29305)" (#30385) commit eda2bdfc7abeb3f67d982ac009856489089ed7d7 Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue May 21 10:48:36 2024 +0200 New Crowdin Translations (automated) (#30383) Co-authored-by: GitHub Actions commit e853355f245765d7d77a3c6e39acd06e19ec0283 Merge: 7b3eef4cb1 20fdf8e22c Author: Claire Date: Mon May 20 20:23:13 2024 +0200 Merge pull request #2714 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to 0a2110b9af52005798251dc9d245a66dd5dd20fa commit 0663c7d78d7de406ed199f61fd0cdb55b14b8f1f Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon May 20 19:14:10 2024 +0200 fix(deps): update formatjs monorepo (#30359) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 8c925dec793476b0f516aab901c7802d8e04f844 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon May 20 19:04:21 2024 +0200 chore(deps): update dependency rubocop-rails to v2.25.0 (#30341) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 20fdf8e22caa6526d519d95bcbdf6ecef76ea9c0 Merge: 7b3eef4cb1 0a2110b9af Author: Claire Date: Mon May 20 17:47:48 2024 +0200 Merge commit '0a2110b9af52005798251dc9d245a66dd5dd20fa' into glitch-soc/merge-upstream commit 7b3eef4cb1b1deaf2a5508e07b67ee36f7727fb3 Merge: 93a617236e ca5955ed76 Author: Claire Date: Mon May 20 17:27:55 2024 +0200 Merge pull request #2713 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to de4815afda0809bf999519aabda1cd14c67278da commit 0a2110b9af52005798251dc9d245a66dd5dd20fa Author: Matt Jankowski Date: Mon May 20 11:00:09 2024 -0400 Add coverage for custom filters (#30347) commit 00cf8d37480b053b179e1caa12c5e9fc04813a4b Author: Claire Date: Mon May 20 16:59:27 2024 +0200 Change older Paperclip database migrations for consistency (#30204) commit 2bcbeed95143448625eccbbf3a3245a1eec26dce Author: Claire Date: Mon May 20 16:59:23 2024 +0200 Add some error handling to OTP secret migration (#30344) commit ca5955ed76ebec90fa87983017904a7b2b0c56a3 Author: Renaud Chaput Date: Sun May 19 19:07:32 2024 +0200 [Glitch] Use a modern React context for identity in the app Port a178ba7cd5fa10b018ecaf3c8e3dd5f298a08818 to glitch-soc Signed-off-by: Claire commit e46321e63d4dd59102e28d3f54813efbb0227eb8 Merge: 93a617236e de4815afda Author: Claire Date: Mon May 20 12:17:36 2024 +0200 Merge commit 'de4815afda0809bf999519aabda1cd14c67278da' into glitch-soc/merge-upstream commit de4815afda0809bf999519aabda1cd14c67278da Author: Claire Date: Mon May 20 12:06:51 2024 +0200 Add more tests for self-destruct mode (#30374) commit def6b686ff3ea8e4e77075a812bd463a3bf325c3 Author: Matt Jankowski Date: Mon May 20 05:37:36 2024 -0400 Fix `Rails/WhereRange` cop (#30343) commit 70608f824e4bdd197d179c70efc82effcefc0c6b Author: Matt Jankowski Date: Mon May 20 04:03:39 2024 -0400 Add coverage for `AdminMailer#auto_close_registrations` (#30349) commit 9658d3e5804ab1e2180a70b6b19386592731fd78 Author: Renaud Chaput Date: Mon May 20 10:01:04 2024 +0200 Use the job class as span name for Sidekiq root spans (#30353) commit 0ce22859a5f989593b04cc7701521655a2f85480 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon May 20 09:56:28 2024 +0200 fix(deps): update dependency @rails/ujs to v7.1.3 (#30356) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 8b75d18371edb1830de72b83737f94d9024b32b4 Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon May 20 09:41:38 2024 +0200 New Crowdin Translations (automated) (#30358) Co-authored-by: GitHub Actions commit 814d00cf4b8942b87db17b2bc2877f25d7e83f96 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon May 20 09:40:37 2024 +0200 chore(deps): update dependency @formatjs/cli to v6.2.12 (#30370) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 778bd96a52a6c608f78b07f80764046a2eac61b3 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon May 20 09:40:20 2024 +0200 chore(deps): update dependency @types/lodash to v4.17.4 (#30371) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 990a0c19a9205fdd8b3e6c0082cc8b80725de144 Author: Renaud Chaput Date: Mon May 20 09:29:27 2024 +0200 Fix a warning when running JS Tests because of FakeIdentityContext using deprecated context API (#30368) commit 0f07e1cd4cf04049eda34d4dfd98c12fafc5e344 Author: Nick Schonning Date: Sun May 19 15:37:49 2024 -0400 Fix yarn.lock diff (#30366) commit 0a343b9a91bc11fd61090fea027431d1e6b94479 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Sun May 19 19:15:06 2024 +0200 fix(deps): update react monorepo to v18.3.1 (#30074) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit a178ba7cd5fa10b018ecaf3c8e3dd5f298a08818 Author: Renaud Chaput Date: Sun May 19 19:07:32 2024 +0200 Use a modern React context for identity in the app (#30098) commit 6282b6da7753b0feaafd9d15e12bbc8dd6958c8f Author: Joshua Byrd Date: Mon May 20 02:30:05 2024 +1000 Fix og:image requests when html in a web page is over 1.megabyte (#30362) commit 93a617236e9b0c457703e1df60f2338aac77f900 Merge: 9668ac5acd 57fb2cf948 Author: Claire Date: Fri May 17 18:05:32 2024 +0200 Merge pull request #2712 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to 12472e7f407c42bcff6ee204b9f1887b5824734f commit 2da2a1dae984f4083d1cc2f55642811c696955e6 Author: Emelia Smith Date: Fri May 17 15:46:12 2024 +0200 Support multiple redirect_uris when creating OAuth 2.0 Applications (#29192) commit 57fb2cf948dd080ce877447f051ea87ee30ec707 Merge: 9668ac5acd 12472e7f40 Author: Claire Date: Fri May 17 12:33:41 2024 +0200 Merge commit '12472e7f407c42bcff6ee204b9f1887b5824734f' into glitch-soc/merge-upstream commit 9668ac5acd620b8b64d97db7042daaedbc2dea3e Merge: 87b5cfc60e 7b078b46a2 Author: Claire Date: Fri May 17 12:32:59 2024 +0200 Merge pull request #2711 from ClearlyClaire/glitch-soc/merge-upstream Port upstream changes up to b2388be71eb0031ef9e47c492b1c038231cd8bc0 commit 12472e7f407c42bcff6ee204b9f1887b5824734f Author: Claire Date: Fri May 17 11:28:40 2024 +0200 Add emphasis on ActiveRecord Encryption configuration values being secret (#30340) commit a627219b25f1787cbee0174e37e36e440489eb66 Author: Jeong Arm Date: Fri May 17 18:18:54 2024 +0900 Fix moderation action logs (#30342) commit bff7769f5f9a4f3995038ad759c1b48a636d303b Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri May 17 10:41:35 2024 +0200 New Crowdin Translations (automated) (#30336) Co-authored-by: GitHub Actions commit a6d12299f22e0318f0bea8b4a0192e6c07398b70 Author: Matt Jankowski Date: Fri May 17 04:29:13 2024 -0400 Remove duplicate method def `ApplicationHelper#instance_presenter` (#30331) commit fc166d07f0b5472866e1e13a0c12d78a0c7bbcfb Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri May 17 10:28:22 2024 +0200 chore(deps): update dependency rails to v7.1.3.3 (#30334) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 3286ad5226ca220a40f12353df2237c4f822af1d Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri May 17 10:28:01 2024 +0200 chore(deps): update dependency selenium-webdriver to v4.21.1 (#30335) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit f7f5b9dadd9e2cee98bf8a7d41193844a37c662b Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri May 17 08:27:45 2024 +0000 fix(deps): update dependency @rails/ujs to v7.1.3-3 (#30337) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 226d7a7badf0d03f2c2a57fd4da72889a3563d28 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri May 17 10:27:03 2024 +0200 fix(deps): update dependency sass to v1.77.2 (#30338) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 87b5cfc60e1dc34c12860d0e52931ef7e44d3874 Merge: 19ed3d9441 2810231180 Author: Claire Date: Thu May 16 21:30:31 2024 +0200 Merge pull request #2710 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to b2388be71eb0031ef9e47c492b1c038231cd8bc0 commit 7b078b46a2951f9c8548c26528a46abc4e5e6f3c Author: Claire Date: Thu May 16 15:01:01 2024 +0200 [Glitch] Fix Web UI trying to save user settings when logged out Port 66906a1bc1fb3934dc101e1d8d7ec4a9ce54a12e to glitch-soc Signed-off-by: Claire commit 061464a563eb05538adaa992a02a8d17d99af099 Author: David Lapshin Date: Thu May 16 10:33:29 2024 +0300 [Glitch] Fix incorrect element selector from #30221 Port 94493cff925ee9b9cb4ebc7cc20081ab20521b85 to glitch-soc Signed-off-by: Claire commit 28102311800b35d7422e395278d568aae89f4074 Merge: 19ed3d9441 b2388be71e Author: Claire Date: Thu May 16 17:49:28 2024 +0200 Merge commit 'b2388be71eb0031ef9e47c492b1c038231cd8bc0' into glitch-soc/merge-upstream Conflicts: - `app/controllers/activitypub/collections_controller.rb`: Upstream renamed a helper method everywhere. There was one glitch-soc line involving changes because of the local-only post feature. Ported upstream's change. commit b2388be71eb0031ef9e47c492b1c038231cd8bc0 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Thu May 16 15:45:17 2024 +0200 chore(deps): update dependency selenium-webdriver to v4.21.0 (#30325) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 66906a1bc1fb3934dc101e1d8d7ec4a9ce54a12e Author: Claire Date: Thu May 16 15:01:01 2024 +0200 Fix Web UI trying to save user settings when logged out (#30324) commit 1b6eb2c7f0425a20f9bd823419138bf8adfa18f4 Author: Matt Jankowski Date: Thu May 16 05:56:48 2024 -0400 Enable YJIT when available (#30310) commit 283a891e9290fc9fdbfd082f3bde48863f1c6f45 Author: Renaud Chaput Date: Thu May 16 11:28:10 2024 +0200 Allow to customise the OTEL service name prefix (#30322) commit 65e82211cdaffa3132832dc42756913d668985c3 Author: Matt Jankowski Date: Thu May 16 04:03:46 2024 -0400 Rename `cache_*` methods to `preload_*` in controller concern (#30209) commit f0d6dc4519cc0311583f139834fbbbcd64e82d7a Author: Emelia Smith Date: Thu May 16 09:59:46 2024 +0200 Fix: Mark redirect uris field in Development > Application form as required (#30311) commit 356bbbaa7f903b7849af1bb78a7954c250c00d46 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Thu May 16 09:57:19 2024 +0200 fix(deps): update dependency @reduxjs/toolkit to v2.2.5 (#30320) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit cdb042ae860c79d47920f30a3ba8b7625e7de56d Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu May 16 09:50:19 2024 +0200 New Crowdin Translations (automated) (#30319) Co-authored-by: GitHub Actions commit c9ee1437c0a12bea5fbafb7efbb8e87e4eb6fe0e Author: Matt Jankowski Date: Thu May 16 03:43:35 2024 -0400 Use ruby language constants to build version string in software version dimension (#30309) commit 60b423b3f72feea31e0d22b02b948848819ad601 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Thu May 16 09:43:31 2024 +0200 chore(deps): update dependency rspec-sidekiq to v5 (#30314) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 94493cff925ee9b9cb4ebc7cc20081ab20521b85 Author: David Lapshin Date: Thu May 16 10:33:29 2024 +0300 Fix incorrect element selector from #30221 (#30307) commit ca560c10958d3ad96736c974c778380c2adacef2 Author: Matt Jankowski Date: Wed May 15 09:57:13 2024 -0400 Disable `Style/RedundantFetchBlock` cop (#30207) commit d5d3a0fc57ff712061a3bd18736d68851f04f86c Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Wed May 15 15:38:51 2024 +0200 fix(deps): update dependency pino to v9.1.0 (#30283) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 5fd56512de244263b4b0df998b8a83c303c3d1c5 Author: Emelia Smith Date: Wed May 15 15:38:36 2024 +0200 Improve Report Notes and Account Moderation Notes (#30288) commit c2ca3d152f1dda0f4f5d2455ae9c550779a2c10e Author: Claire Date: Wed May 15 15:11:13 2024 +0200 Fix off-by-one in `tootctl media` commands (#30306) commit 4e085dff52f88a4bb81f4f6cbe4c7a37ebfb2390 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Wed May 15 15:05:05 2024 +0200 chore(deps): update dependency aws-sdk-s3 to v1.151.0 (#30287) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 19ed3d944104cd48096ddf9fbb26ac6bbf63879a Merge: 5ed6622a00 47ce5f4ca9 Author: Claire Date: Wed May 15 12:10:10 2024 +0200 Merge pull request #2709 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to 1bf661cddbc614d4076e9d9e855575fc29e976c0 commit 85c625d31974e411666812468ddfd7760ab67d4a Author: Jason Punyon Date: Wed May 15 05:38:16 2024 -0400 Fix repetitive database queries from #30040 (#30259) commit 6beead38678d6a25adc94ee82ed07974e3e20147 Author: Matt Jankowski Date: Wed May 15 05:33:36 2024 -0400 Move `simplecov` config into `rails_helper` (#30302) commit aad5e841b59691f001132a9cf96487db8389c77e Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed May 15 10:53:57 2024 +0200 New Crowdin Translations (automated) (#30290) Co-authored-by: GitHub Actions commit 78a8263f73ed8b07a1528e716f28858e0d817603 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Wed May 15 10:34:58 2024 +0200 fix(deps): update dependency postcss-preset-env to v9.5.13 (#30286) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 7f7eba875376a44e01d4446902888e6afdd88908 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Wed May 15 10:34:50 2024 +0200 chore(deps): update dependency letter_opener_web to v3 (#30296) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 40639510f88442f9e21f9400931038cce7a0518c Author: Renaud Chaput Date: Wed May 15 10:27:34 2024 +0200 Retain unconfirmed users longer (1 week) (#30285) commit 44e855db7830ab803820a9534f543702b9e9dca9 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Wed May 15 08:26:22 2024 +0000 chore(deps): update dependency nokogiri to v1.16.5 [security] (#30289) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 508e93eb649fb490ea98904e2f64b372ec2ff610 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Wed May 15 10:25:50 2024 +0200 chore(deps): update dependency fog-openstack to v1.1.1 (#30295) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 38a330f96328091fe39dd212ec053d5df3e2e36e Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Wed May 15 10:25:34 2024 +0200 fix(deps): update dependency core-js to v3.37.1 (#30293) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 47ce5f4ca9cec9f77e05c7b341275689674175ae Author: Renaud Chaput Date: Tue May 14 20:15:42 2024 +0200 [Glitch] Fix missing prop warning for `` Port 1bf661cddbc614d4076e9d9e855575fc29e976c0 to glitch-soc Signed-off-by: Claire commit 160823716ab0fe57c629f470d7218218a78a37d4 Author: David Lapshin Date: Mon May 13 12:19:42 2024 +0300 [Glitch] Add active animation to header settings button Port cb93c1edf08865b1ac528a9a4cb747dab3d57e8d to glitch-soc Signed-off-by: Claire commit 666760f4506835431a728564248311c9d97ce9d7 Merge: 5ed6622a00 1bf661cddb Author: Claire Date: Tue May 14 20:47:14 2024 +0200 Merge commit '1bf661cddbc614d4076e9d9e855575fc29e976c0' into glitch-soc/merge-upstream Conflicts: - `package.json`: Upstream fixed a command we have modified in glitch-soc. Updated as upstream did. commit 1bf661cddbc614d4076e9d9e855575fc29e976c0 Author: Renaud Chaput Date: Tue May 14 20:15:42 2024 +0200 Fix missing prop warning for `` (#30291) commit b5b84fad65f927a1bf55538be4a4763199724a6e Author: Claire Date: Tue May 14 19:54:28 2024 +0200 Fix OpenSearch compatibility issue (#30278) commit 3a7aec2807089a004db90851c66db0a007a18a48 Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon May 13 13:30:41 2024 +0200 New Crowdin Translations (automated) (#30254) Co-authored-by: GitHub Actions commit 13fb54920b1c1e8dd59798dd9fc3466c5a446898 Author: Nick Schonning Date: Mon May 13 05:54:15 2024 -0400 Enable Style/IfUnlessModifier RuboCop (#30260) commit 9ec7c1f89256cf3c658a67c3cf8b956fd4dab265 Author: Nick Schonning Date: Mon May 13 05:42:47 2024 -0400 Fix i18n:extract flags (#30261) commit 6e1b8b33f55de9fdfcd4ce3a8fcc965c1b5c6601 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon May 13 11:42:08 2024 +0200 Update opentelemetry-ruby (non-major) (#30262) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit b429c9b8a7848097a1c86edda465629a11267696 Author: Jeen Broekstra Date: Mon May 13 21:40:14 2024 +1200 fix(bin/dev): makes conditional for launching overmind POSIX-compliant (#30271) commit c66fdb3dff7f9313ff610a6b6e97ee22e3b3c7e1 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon May 13 11:39:06 2024 +0200 Update dependency immutable to v4.3.6 (#30276) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit cb93c1edf08865b1ac528a9a4cb747dab3d57e8d Author: David Lapshin Date: Mon May 13 12:19:42 2024 +0300 Add active animation to header settings button (#30221) commit f66c9faca02018a3aa6140506a15d685b89dfed2 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon May 13 11:11:55 2024 +0200 Update dependency sass to v1.77.1 (#30252) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 123108b1ccf3e516be80f92f816def1ede77ee11 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon May 13 11:11:39 2024 +0200 Update dependency postcss-preset-env to v9.5.12 (#30256) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 5e7d88a85d400423bb21986a6a6dbef0d89135c5 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon May 13 09:10:53 2024 +0000 Update dependency glob to v10.3.15 (#30263) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 471728d6ddb2bbc3579adde36942cbee622a3930 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon May 13 11:10:26 2024 +0200 Update DefinitelyTyped types (non-major) (#30272) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit ab4efa3bf89358a110f91af87055e1fc5d610d94 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon May 13 11:10:09 2024 +0200 Update dependency @testing-library/react to v15.0.7 (#30273) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 807cf354fcf2706bd24890acb875fa85b097164a Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon May 13 11:09:39 2024 +0200 Update dependency eslint-plugin-jsdoc to v48.2.4 (#30274) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 5ed6622a00fd4668c5588498596f0aaec457cf66 Merge: 3286daa807 f65a6d50f1 Author: Claire Date: Sun May 12 21:35:25 2024 +0200 Merge pull request #2706 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to 1959365c2f410aa82874c5c05ab92c4eca4c4055 commit f65a6d50f1f9f48e50ea693c8b36dcb8dbb9f232 Author: Chee Aun Date: Fri May 10 17:19:27 2024 +0800 [Glitch] Fix typo Port c36a8786c10c36e5181c9c53d848fa8e7b24b692 to glitch-soc Signed-off-by: Claire commit f35ba6963d4b874c8d5be2ccf05a9b77407dcb0c Merge: 3286daa807 1959365c2f Author: Claire Date: Sat May 11 22:10:56 2024 +0200 Merge commit '1959365c2f410aa82874c5c05ab92c4eca4c4055' into glitch-soc/merge-upstream commit 1959365c2f410aa82874c5c05ab92c4eca4c4055 Author: Claire Date: Fri May 10 22:00:25 2024 +0200 Add missing `on_delete: :cascade` on `notification_policies` (#30251) commit 346530732cce54c3e690486aca256bc0aae26d17 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri May 10 21:19:47 2024 +0200 Update dependency utf-8-validate to v6.0.4 (#30248) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 9920f41c0fd8ad0030d2818c8271aa3cf24b4391 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri May 10 21:18:53 2024 +0200 Update opentelemetry-ruby (non-major) (#30249) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit d09b02efb653e59488cac530db8ae2757ad0cd02 Author: Renaud Chaput Date: Fri May 10 18:33:10 2024 +0200 Group Ruby OTEL packages in Renovate PRs (#30242) commit 482d1087c57553f551cf495f62d9b7fccf649271 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri May 10 16:19:41 2024 +0200 Update dependency opentelemetry-instrumentation-faraday to v0.24.3 (#30237) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit af71f236a2e4565619871bfb72d64ca39411d365 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri May 10 15:16:05 2024 +0200 Update dependency opentelemetry-instrumentation-excon to v0.22.2 (#30236) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit d933e6b6aeda9fad6af712e084cdb5c25bdc2cbe Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri May 10 15:16:02 2024 +0200 Update dependency opentelemetry-instrumentation-concurrent_ruby to v0.21.3 (#30235) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit ded11eca4fe2d89d986663d6f6a8dd5284e4604a Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri May 10 15:15:54 2024 +0200 Update dependency pundit to v2.3.2 (#30222) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 68b9fe824d6cc8154efe46829fa0fcd26a5b9a5d Author: Renaud Chaput Date: Fri May 10 14:40:20 2024 +0200 Add OpenTelemetry instrumentation (#30130) Co-authored-by: Juliano Costa Co-authored-by: Robb Kidd commit 0d397db5dd803fab2b7ddda9ae0dd5c26f4880a6 Author: Matt Jankowski Date: Fri May 10 08:36:09 2024 -0400 Consolidate system specs into single directory, use rspec tags for configuration (#30206) commit 164b09bfcc7d2b8c3619411ee06f530256d9fe4b Author: Joshua Young Date: Fri May 10 22:34:32 2024 +1000 Update README.md setup steps (#30063) commit e20f2e7300d326bd637bec691607ad4c0e70dc8f Author: Matt Jankowski Date: Fri May 10 08:34:20 2024 -0400 Update i18n to version 1.14.5 (#30198) commit f3f63107f263db86021565dad79be497db9e5257 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri May 10 11:59:15 2024 +0200 Update dependency @reduxjs/toolkit to v2.2.4 (#30223) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit fa43a6c8355ae53c0609999e1891023626ab4217 Author: Matt Jankowski Date: Fri May 10 05:43:59 2024 -0400 Use more accurate `redirect_uri` in oauth spec (#30212) commit 040aaf3a48022edab19ac42980a6c5a991156ec9 Author: Matt Jankowski Date: Fri May 10 05:42:01 2024 -0400 Use `default: ...` assignment for Devise config, fixes `Style/ClassVars` cop (#30214) commit c9557bdd3bc7c67f6513295b0ab633cfca8cbfdd Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri May 10 11:34:48 2024 +0200 New Crowdin Translations (automated) (#30215) Co-authored-by: GitHub Actions commit 3a5a1b2e5838d8915bd2d08e5d3ea363d66b611e Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri May 10 09:25:07 2024 +0000 Update dependency node to 20.13 (#30211) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 1aa3976f280efed1ae4c72c1ac58e3e4ff9061f1 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri May 10 11:23:45 2024 +0200 Update dependency pino-http to v10.1.0 (#30199) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 0a4a93038fa08e0f64f3b1f267853f38f41cd0cf Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri May 10 09:22:47 2024 +0000 Update Yarn to v4.2.2 (#30220) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit c36a8786c10c36e5181c9c53d848fa8e7b24b692 Author: Chee Aun Date: Fri May 10 17:19:27 2024 +0800 Fix typo (#30224) commit 6ccee2600bf8920131f9b4ad5706cf632262556b Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri May 10 11:19:06 2024 +0200 Update dependency rubocop to v1.63.5 (#30225) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 6819bcc4b6772075a8fd45b995b9e1bf92ef7868 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri May 10 11:18:52 2024 +0200 Update dependency glob to v10.3.14 (#30230) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 5a3062f723abefe4ec49898256e1d81b01fbf6f4 Author: Renaud Chaput Date: Fri May 10 10:00:02 2024 +0200 Pass the CodeCov token from the secret to the action (#30219) commit 3286daa807b9861e62b6de5b0b586c0c097987f8 Merge: e9cca1cc09 21c904b0f6 Author: Claire Date: Tue May 7 21:10:52 2024 +0200 Merge pull request #2704 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to d8c428472356abd70aaf1f514b99114464ee7f61 commit 21c904b0f6acf8effc530db76222224a61a617bf Merge: f7dadc9f0b d8c4284723 Author: Claire Date: Tue May 7 20:30:17 2024 +0200 Merge commit 'd8c428472356abd70aaf1f514b99114464ee7f61' into glitch-soc/merge-upstream commit d8c428472356abd70aaf1f514b99114464ee7f61 Author: Claire Date: Tue May 7 20:15:17 2024 +0200 Ensure custom favicon is converted to PNG and ICO (#30208) commit c9ccba7045f1127be0d89bf941b9ba381e2cb722 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Tue May 7 14:43:11 2024 +0200 Update dependency sass to v1.77.0 (#30200) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit f7dadc9f0b85c3368aa5dcaa66f0fe112651e96a Merge: 016d194274 5cd13ee4f1 Author: Claire Date: Tue May 7 12:13:02 2024 +0200 Merge commit '5cd13ee4f19c112ea855063c2495e2874746f23a' into glitch-soc/merge-upstream commit 5cd13ee4f19c112ea855063c2495e2874746f23a Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Tue May 7 11:39:20 2024 +0200 Update dependency aws-sdk-s3 to v1.149.1 (#30196) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 8540004f7b473df47e49d8dc5397ff590245553a Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Tue May 7 09:39:04 2024 +0000 Update dependency dotenv to v3.1.2 (#30197) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit ed556db3953d7585cc78a92597f1e3dca9cc2b53 Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue May 7 11:36:16 2024 +0200 New Crowdin Translations (automated) (#30201) Co-authored-by: GitHub Actions commit 96fb6e491ffa526e800b5c3d1835022a90930c88 Author: Claire Date: Tue May 7 10:46:05 2024 +0200 Revert "Migrate paperclip `_file_size` columns to bigint (#29263)" (#30203) commit 996292cd55e661f3390792b60b130150b1f4ff40 Author: Claire Date: Tue May 7 10:41:53 2024 +0200 Fix `db:encryption:init` requiring ActiveRecord encryption variables to be set (#30202) commit 616789454707be00b334070646491b5e028d3be6 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon May 6 19:14:46 2024 +0200 Update dependency pino-http to v10 (#30191) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 016d194274d5d5c52e2c1410f260993fb17aef52 Merge: e9cca1cc09 2fe1b8d169 Author: Claire Date: Mon May 6 17:53:51 2024 +0200 Merge commit '2fe1b8d1695d8faa452a69872fde94ccc4611576' into glitch-soc/merge-upstream Conflicts: - `app/helpers/application_helper.rb`: Not a real conflict, upstream added helpers right next to glitch-soc only helpers. Added upstream's helpers. - `spec/models/status_spec.rb`: Not a real conflict, upstream added specs right next to glitch-soc only specs. Added upstream's tests. commit 2fe1b8d1695d8faa452a69872fde94ccc4611576 Author: Claire Date: Mon May 6 17:19:15 2024 +0200 Add API to get multiple accounts and statuses (#27871) Co-authored-by: noellabo commit bc24c4792d0bef744ff1d39e8eb543b1b6aa98c2 Author: Fawaz Farid Date: Mon May 6 18:06:52 2024 +0300 Allow admins to configure instance favicon and logo (#30040) commit b152f936c1361cc82e21c853335557c3ffa80409 Author: Matt Jankowski Date: Mon May 6 11:05:12 2024 -0400 Migrate paperclip `_file_size` columns to bigint (#29263) Co-authored-by: Claire commit 05126d106fd972e4baf5a1cec857e44a451b90a9 Author: Fawaz Farid Date: Mon May 6 16:31:39 2024 +0300 Redirect back after site upload deletion (#30141) commit 116f01ec7d1e0793fc6c1749867d660d7c19a5b7 Author: Emelia Smith Date: Mon May 6 15:17:56 2024 +0200 Implement RFC 8414 for OAuth 2.0 server metadata (#29191) commit 30ef9fccf0c603ba917191ddbefdd497523d3d67 Author: Claire Date: Mon May 6 14:47:19 2024 +0200 Fix hashtag matching pattern matching some link anchors (#30190) commit 8e4fea77e311399e4bcfff729aa06fed4e82e57c Author: Claire Date: Mon May 6 14:41:14 2024 +0200 Fix race condition in `POST /api/v1/push/subscription` (#30166) commit dbaa4ed891f5eb97e74600ddd4e38a9be40f9180 Author: Matt Jankowski Date: Mon May 6 07:50:45 2024 -0400 Use `chewy` which relaxes ES version reqs (#30157) commit e5062b713588cbdc7249a65311a2e59a08bf9731 Author: Claire Date: Mon May 6 11:52:34 2024 +0200 Fix post deletion not being deferred when those are part of an account warning (#30163) commit 4f0d18168c39a52250b8be07558675716bf292ee Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon May 6 10:46:43 2024 +0200 Update DefinitelyTyped types (non-major) (#30184) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 00c34070ae3679116f4962b5608b53fa95a61e1b Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon May 6 10:46:22 2024 +0200 Update eslint (non-major) (#30186) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 86f17e4b32eb5da3dfcd82c4be72d529d8a72565 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon May 6 10:46:17 2024 +0200 Update devDependencies (non-major) (#30185) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 9be2c02e52b9c3534fa1bd16ade00a135034d2cb Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon May 6 10:36:29 2024 +0200 New Crowdin Translations (automated) (#30169) Co-authored-by: GitHub Actions commit a96b82802380f2220d7e2a059ca3c773c9ce3472 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon May 6 10:26:33 2024 +0200 Update dependency postcss-preset-env to v9.5.11 (#30171) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit d544b83f917773749f9664be4bca4eec4078a2b6 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon May 6 10:26:28 2024 +0200 Update formatjs monorepo (#30175) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit e4841ca82b58f33ec42742b40211f38fef1e7338 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon May 6 10:26:12 2024 +0200 Update dependency irb to v1.13.1 (#30177) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit e9cca1cc09811653d6faf0127c2a8ddab1b9915e Merge: e7b09486ed c59f6ef5b8 Author: Claire Date: Sun May 5 18:32:37 2024 +0200 Merge pull request #2701 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to b7902225d698a107df2cf8b4ca221caad38fa464 commit 2f73e486b7e107763e92b47b8659e152f363d988 Author: Tim Rogers Date: Sat May 4 21:24:10 2024 -0500 Switched HTMLEntities to the expanded flavor which supports a larger … (#30173) commit c59f6ef5b8789f9b7879ef5d3491231f3a36cb4a Author: Renaud Chaput Date: Thu May 2 14:02:13 2024 +0200 [Glitch] Convert `entrypoints/two_factor_authentication` to Typescript Port 9e260014c72fa83740d70d2d603e836f86e64b55 to glitch-soc Signed-off-by: Claire commit b6ada33ad4d98015df27878352955a4d5bc7d630 Author: mogaminsk Date: Thu May 2 18:40:18 2024 +0900 [Glitch] Fix word breaking in filtered notifications badge Port 616e2f26668d578ae81043a3836e881178d3e806 to glitch-soc Signed-off-by: Claire commit 3789d9f8255df2043863aa990bff6fa8bf441595 Merge: 4b82dc84f5 b7902225d6 Author: Claire Date: Sat May 4 16:28:30 2024 +0200 Merge commit 'b7902225d698a107df2cf8b4ca221caad38fa464' into glitch-soc/merge-upstream Conflicts: - `spec/validators/status_length_validator_spec.rb`: Upstream refactored tests to stub `StatusLengthValidator::MAX_CHARS` while glitch-soc had custom code to read from `MAX_TOOT_CHARS`. Switched to using upstream's implementation of the tests. commit 4b82dc84f520f459063c2a7c9ad59653a2a95181 Author: Claire Date: Wed May 1 01:39:28 2024 +0200 [Glitch] Change width breakpoint for mobile placement behavior Port 26e10aa203d18e452cdf836209875f05a6e01882 to glitch-soc Signed-off-by: Claire commit 6662d604c161716856ca5a7f55d78d4a63207040 Author: Claire Date: Mon Apr 29 11:55:41 2024 +0200 [Glitch] Add loading indicator and empty result message to advanced interface search Port 7d3fe2b4c3cd9511df8f8026890c71b2119719f3 to glitch-soc Signed-off-by: Claire commit e62595c9667151ec5038da9232639c97250f9c64 Author: Renaud Chaput Date: Mon Apr 29 11:29:59 2024 +0200 [Glitch] Remove usage of deprecated `defaultTypes` on React functional components Port b9b4db483cc588a2eb334b63fe6740c8dad9b57b to glitch-soc Signed-off-by: Claire commit f09f5b35f2d347d12d34fff112fa3fd694c1e698 Merge: 494d28bb56 d97d31cce6 Author: Claire Date: Sat May 4 16:12:51 2024 +0200 Merge commit 'd97d31cce664281d868e4c661451687a301c97c8' into glitch-soc/merge-upstream Conflicts: - `app/models/account.rb`: Upstream refactored this file a bit, moving validation limits to constants. We already had a similar change, although with different constant names. Updated to match upstream's code. The following files were also modified accordingly: - `app/views/settings/profiles/show.html.haml` - `spec/requests/api/v1/accounts/credentials_spec.rb` commit 494d28bb563caac94f8f4fda3683525b69a6f69f Author: Renaud Chaput Date: Mon Apr 29 10:23:05 2024 +0200 [Glitch] Convert `entrypoints/sign_up` to Typescript Port 4527e012daa61dc07258eaedf3e03179b59fca8d to glitch-soc Signed-off-by: Claire commit fe7db7905fe9b8a120b6f6f7169eefd3df976727 Author: Renaud Chaput Date: Mon Apr 29 10:02:41 2024 +0200 [Glitch] Convert easy entrypoints files to Typescript Port 36909065b544d06e8487f1e0679e595fd01a7f22 to glitch-soc Signed-off-by: Claire commit defd1e4024ffb89b8dbcc82fb7384903cd2c3e79 Author: David Beck Date: Mon Apr 29 00:55:58 2024 -0700 [Glitch] Remove home marker updates Port 4f4b77920eeb3ba65346862d489945494dfeab64 to glitch-soc Signed-off-by: Claire commit a76980a229fa9b0cdf427ed52c00a7e5980ce674 Merge: 552e09d57f f0c9cbaf3b Author: Claire Date: Sat May 4 15:40:07 2024 +0200 Merge commit 'f0c9cbaf3b079700b8179222d409c644dfd8ff66' into glitch-soc/merge-upstream commit 552e09d57f195633e635b9d036b1c74fd1b2a643 Author: Renaud Chaput Date: Fri Apr 26 19:11:27 2024 +0200 [Glitch] Fix marker thunks to not ignore eslint directives for the whole file Port 65093c619fdd1b18a4cf0c288051d8c524d5f434 to glitch-soc Signed-off-by: Claire commit a4ce53df2721a4ec16bbc41001f8f1c430204490 Author: Claire Date: Fri Apr 26 17:33:15 2024 +0200 [Glitch] Change moderation warning notification icon Port de4a7bf53159f72a9a122bf8df21e8d5f4ad7512 to glitch-soc Signed-off-by: Claire commit aac59a34ed120ad269aad70fb6600782cdd2bae8 Author: Claire Date: Thu Apr 25 19:26:05 2024 +0200 [Glitch] Add in-app notifications for moderation actions/warnings Port 4ef0b48b951d65920d3a3d9cdfd099967c5e4f6d to glitch-soc Signed-off-by: Claire commit 8dbcf8a2873e5fa5dc7a3d35cb8d54abcef27b2f Author: Eugen Rochko Date: Thu Apr 25 18:25:33 2024 +0200 [Glitch] Change design of people tab on explore in web UI Port 0ec061aa8f7383330b26b3323d2fafd9ec7663e3 to glitch-soc Signed-off-by: Claire commit d6f9c97ae4c5fb1a44c4f4bd4144217dcf320f29 Merge: 333905b2d5 7201f99cf8 Author: Claire Date: Sat May 4 15:24:22 2024 +0200 Merge commit '7201f99cf83a74331febd1624ca9aaace68af5e6' into glitch-soc/merge-upstream commit 333905b2d54b33b6c0e1103ecb5c113ab77843a0 Author: Eugen Rochko Date: Wed Apr 24 10:45:12 2024 +0200 [Glitch] Change mute options to be in dropdown on muted users list in web UI Port 74012831f61a36b7f52540c5ccafa0f9692a6596 to glitch-soc Signed-off-by: Claire commit bac4026d8080bdcb517cfc856d3d6f39a35c70b9 Merge: bceb45adda 85fdbd0ad5 Author: Claire Date: Sat May 4 15:10:54 2024 +0200 Merge commit '85fdbd0ad53837c9209acf3fb45811d5bae41cd9' into glitch-soc/merge-upstream commit bceb45adda5d295d234bcea6d668a9fe41a584c2 Merge: e7b09486ed 3f6887557b Author: Claire Date: Sat May 4 14:59:00 2024 +0200 Merge commit '3f6887557b23d363e7f8f18518db4447739d64bb' into glitch-soc/merge-upstream Conflicts: - `app/javascript/entrypoints/common.js`: Upstream moved everything from `app/javascript/packs` to `app/javascript/entrypoints` while this file was a glitch-soc addition. Moved it like the rest. - `tsconfig.json`: Conflict due to glitch-soc's flavor. Updated like upstream. Also moved and updated the following files accordingly: - `app/javascript/flavours/vanilla/theme.yml` - `app/javascript/flavours/glitch/theme.yml` - everything in `app/javascript/flavours/glitch/packs` commit b7902225d698a107df2cf8b4ca221caad38fa464 Author: Matt Jankowski Date: Fri May 3 10:56:48 2024 -0400 Use built-in github annotation output for `stylelint` (#30165) commit 33368e3e79a6edfcaf65fd2b80b636a7c1e56e48 Author: Claire Date: Fri May 3 11:26:24 2024 +0200 Change ActiveRecordEncryption variable to be more explicit (#30151) commit 9aa31be8d3fd7f20a537bfb08b5e4ef11f636c34 Author: Râu Cao <842+raucao@users.noreply.github.com> Date: Fri May 3 11:22:48 2024 +0200 Fix local account search on LDAP login being case-sensitive (#30113) Co-authored-by: Claire commit d5444a2c6c6bf9597503297dba9181e6d9bfad46 Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri May 3 11:15:06 2024 +0200 New Crowdin Translations (automated) (#30160) Co-authored-by: GitHub Actions commit 9380805fc15f0a0bfc4ed9e70c393191f64e2718 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri May 3 10:48:09 2024 +0200 Update dependency rubocop-rspec to v2.29.2 (#30158) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 4b2054ee57b41c304f85eab6236baebe0b732d95 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Thu May 2 23:22:26 2024 +0200 Update Yarn to v4.2.1 (#30153) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 253ead3aa7f69053eb6b275ba3016c43be2d3675 Author: Claire Date: Thu May 2 22:56:21 2024 +0200 Fix not being able to block a subdomain of an already-blocked domain through the API (#30119) commit 9e260014c72fa83740d70d2d603e836f86e64b55 Author: Renaud Chaput Date: Thu May 2 14:02:13 2024 +0200 Convert `entrypoints/two_factor_authentication` to Typescript (#30105) commit e7b09486ede327c99baaddb973d7c6fc39ded85d Merge: 3024212403 b039e62194 Author: Claire Date: Thu May 2 12:55:04 2024 +0200 Merge pull request #2699 from ClearlyClaire/glitch-soc/merge-upstream Merge upstream changes up to a2399046ca600d492b492b8dae88011de687bece commit 616e2f26668d578ae81043a3836e881178d3e806 Author: mogaminsk Date: Thu May 2 18:40:18 2024 +0900 Fix word breaking in filtered notifications badge (#30114) commit 88882fbbeefe0a5a91985a4c50c44f897e30aabd Author: Matt Jankowski Date: Thu May 2 05:40:05 2024 -0400 Move Rails/HABTM cop out of todo (#30118) commit 1e7d5d2957678788fdea8ade77eced98848ff4ff Author: Matt Jankowski Date: Thu May 2 05:31:41 2024 -0400 Update `devise-two-factor` to version 5.0.0 (#28325) Co-authored-by: Claire commit 309f352e6a2fe68729ef5b723c986bc536fe0773 Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu May 2 10:57:30 2024 +0200 New Crowdin Translations (automated) (#30140) Co-authored-by: GitHub Actions commit 2447497a4cc6ea305f9431e4d8002b7abb750c7e Author: Matt Jankowski Date: Thu May 2 04:31:06 2024 -0400 Status length validation spec updates (#30132) commit d97d31cce664281d868e4c661451687a301c97c8 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Thu May 2 10:28:13 2024 +0200 Update dependency irb to v1.13.0 (#30143) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit ac1d830e6cd795b7658d0ae7fe7cec52cd24cf6e Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Thu May 2 10:27:47 2024 +0200 Update dependency aws-sdk-s3 to v1.149.0 (#30136) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 474e5ffaaeba42db6abacd0194720cdfc66f79f3 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Thu May 2 10:15:49 2024 +0200 Update dependency dotenv to v3.1.1 (#30133) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 62992ba54a102a52ba49087f13c86a662f9d5807 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Thu May 2 10:14:45 2024 +0200 Update dependency sass to v1.76.0 (#30138) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit a9dd68b90a8f8ae5bffb7ad97a34919bcf0f9d17 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Thu May 2 10:00:43 2024 +0200 Update dependency react-redux to v9.1.2 (#30146) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit b039e621948f92ac34255b15403278c0aea09952 Merge: eeefb7cdbc a2399046ca Author: Claire Date: Wed May 1 19:49:59 2024 +0200 Merge commit 'a2399046ca600d492b492b8dae88011de687bece' into glitch-soc/merge-upstream commit eeefb7cdbc93da812f333628bab24a1bdce0f6ee Merge: 6204d13a2e a15139bc02 Author: Claire Date: Wed May 1 19:42:34 2024 +0200 Merge commit 'a15139bc02d279b9ef85e95990f41e3e88838d20' into glitch-soc/merge-upstream commit 6204d13a2eb57fd7d9c71102dbc172dd1aac1f2b Merge: 360590ecd8 ec71c02c4b Author: Claire Date: Wed May 1 19:38:34 2024 +0200 Merge commit 'ec71c02c4b028c3541742f023729aeb295a51559' into glitch-soc/merge-upstream Conflicts: - `Gemfile`: There was an extra newline in glitch-soc for some reason. Removed it. commit 360590ecd8bf84294217ffb7b899cec65f6df101 Merge: df933836ca a390299744 Author: Claire Date: Wed May 1 19:30:41 2024 +0200 Merge commit 'a3902997440c71f161e392f1ad6c5cdcf6aba95d' into glitch-soc/merge-upstream Conflicts: - `app/controllers/accounts_controller.rb`: Conflict due to glitch-soc's local-only posting feature. Refactored as upstream did but kept local changes. - `app/lib/account_statuses_filter.rb`: Conflict due to glitch-soc's local-only posting feature. Refactored as upstream did but kept local changes. commit df933836caaf136c2ee3fcd977aaab85821d0bfa Author: Claire Date: Tue Apr 16 11:25:23 2024 +0200 [Glitch] Fix incorrect label for filtered notifications badge Port 66ee0d4a1f35ce4455418921879b8d2f96538d57 to glitch-soc Signed-off-by: Claire commit 62b3f284dba9ce811235494062d0f3bf65a1e2a3 Author: Claire Date: Mon Apr 15 13:56:48 2024 +0200 [Glitch] Fix unfollow button being out of frame on small screens on old browsers Port 4117c8f6b88f72a9f2a3177f2c02708b7e05c772 to glitch-soc Signed-off-by: Claire commit 946bd2e7e144ff6f0b9292579949de12bbdb5d19 Merge: ac5113d524 0622107449 Author: Claire Date: Wed May 1 19:16:48 2024 +0200 Merge commit '0622107449e72d35b22afeeba2f0ba983e914803' into glitch-soc/merge-upstream commit ac5113d524dd7d18f66a8dcfcc23fab1d8850c76 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Wed Apr 3 20:05:39 2024 +0200 [Glitch] Update eslint (non-major) Port 37d984b8bf19f86a8a371a97d8a1a000022448b3 to glitch-soc Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Renaud Chaput Signed-off-by: Claire commit e76ddf79bc9dee7290541b7274a2b997efcbc343 Author: Claire Date: Fri Apr 12 11:42:12 2024 +0200 [Glitch] Add `/` keyboard shortcut to focus the search field Port c386c36866881ac3bd3d0b156264231f7b4c8053 to glitch-soc Signed-off-by: Claire commit 6f342a6d4c4250f08e01362fa9208b62ead48f59 Merge: 2d43547934 34e826f373 Author: Claire Date: Wed May 1 18:56:48 2024 +0200 Merge commit '34e826f373d20f6230d1ef0aa03ad41a3bdf5998' into glitch-soc/merge-upstream Conflicts: - `app/helpers/theme_helper.rb`: Conflict caused by our different theme systems. Ported upstream's changes. - `app/models/account.rb`: Upstream basically made a change we already made. Moved constant declaration to match upstream. commit 2d43547934d17d88e1e055c2a84673c20c7e6fde Author: Renaud Chaput Date: Mon Apr 8 10:17:51 2024 +0200 [Glitch] Fix webpack warnings due to unhandled extensions (`LICENCE` and `README.md`) Port 730e2127e1fa0e81952bb83d91cede91d8b47b72 to glitch-soc Signed-off-by: Claire commit 9ce82a35cb40fc8f3319b2e33f64f52a097522bf Merge: 555e33a392 20b1e55f24 Author: Claire Date: Wed May 1 18:42:26 2024 +0200 Merge commit '20b1e55f24a87868d661fc7b033bbbbd48b1a918' into glitch-soc/merge-upstream commit 555e33a392949f97429d0d10f54af96271aa4752 Merge: 3739dda2f6 b61ae28f8d Author: Claire Date: Wed May 1 18:38:55 2024 +0200 Merge commit 'b61ae28f8d4b6f269f50a05c3e65ec7f2c846d32' into glitch-soc/merge-upstream Conflicts: - `app/helpers/application_helper.rb`: Conflict because of our different theming systems. Updated accordingly, along with `app/helpers/theme_helper.rb` and `app/helpers/theme_helper_spec.rb`. commit 3739dda2f6c4da44c536813ea0adcc4ae70238cc Author: Michael Stanclift Date: Thu Apr 4 06:51:06 2024 -0500 [Glitch] Add purple border to active compose field search inputs Port 1c87cb8019bafd2eb5b126ed0e9186ce20e94b1e to glitch-soc Signed-off-by: Claire commit 0fb469e2f359a25993b339884cb60d5a15ea3639 Merge: 41c43168fb 52ab8a59c6 Author: Claire Date: Wed May 1 17:30:52 2024 +0200 Merge commit '52ab8a59c6e77b6409a7d4d81b15751732b3af91' into glitch-soc/merge-upstream commit 41c43168fbcd94f9cd989c69ee7e55b853be6d0d Author: nicolas Date: Wed Apr 3 23:10:02 2024 +0200 [Glitch] Makes the star icon rotate around its actual centre axis Port c6da3ee828ba2f8ddadfbb8b51a6fba90abc6824 to glitch-soc Signed-off-by: Claire commit b21322b406bf798954c55a72bb93c111c4643694 Author: Michael Stanclift Date: Wed Apr 3 10:19:10 2024 -0500 [Glitch] Fix blue border on emoji/language search in Safari & Chrome Port e2844173499254bd5f460ca2c205d16de228db62 to glitch-soc Signed-off-by: Claire commit 4543bb9384bac388c34a58771f7131c8fa5ad794 Author: Michael Stanclift Date: Wed Apr 3 09:22:50 2024 -0500 [Glitch] Fix language and emoji search field background colors on light theme Port 5d67247061770bb4228c479dd03845735b849e3a to glitch-soc Signed-off-by: Claire commit 3503fe186517ba9c6f87d65b99bf488cd879681e Merge: 46cc9141c9 4045c069f8 Author: Claire Date: Wed May 1 17:26:21 2024 +0200 Merge commit '4045c069f8f91200d0e7c64a8097e425aee71041' into glitch-soc/merge-upstream commit 46cc9141c9dcd4b8b0ca1b77162bfa6b0ea8291c Author: Claire Date: Tue Apr 2 16:05:46 2024 +0200 [Glitch] Fix contrast in notification request badge Port 0b9d4103cb5502faee4cc61717aa5454f63bc8f5 to glitch-soc Signed-off-by: Claire commit 15f6d2d038b9bea7e9638e20476459e5a43f0be1 Merge: 87b9b23025 d27eb181f6 Author: Claire Date: Wed May 1 17:22:02 2024 +0200 Merge commit 'd27eb181f6ab419d1745a1fe9b94094be17a618f' into glitch-soc/merge-upstream Conflicts: - `spec/requests/api/v2/instance_spec.rb`: Conflict due to glitch-soc having a different default site name. Updated the tests as upstream did, keeping glitch-soc's default name. commit 87b9b23025c0323747d9ca919edc5653a5a5ebab Author: Renaud Chaput Date: Tue Apr 2 12:06:26 2024 +0200 [Glitch] Use integers and not numbers in notification policy API counters Port b4d991adaa82e05a2dd95ae5c08bb374391ef568 to glitch-soc Signed-off-by: Claire commit c316852a65dbac2b77d2c1300eeae9a154d0b37e Author: Renaud Chaput Date: Tue Apr 2 12:03:33 2024 +0200 [Glitch] Add API types for status and related objects Port e47a3d00fe21fa51ee1aeffbfb5e152f1f715fef to glitch-soc Signed-off-by: Claire commit 297c8c37b11d5e1c83fa3ed0fea654ffe8aa64dc Author: Renaud Chaput Date: Tue Apr 2 11:56:03 2024 +0200 [Glitch] Fix Redux Middleware types Port 07635228e2b2182888850cecddd4b09756d9edbc to glitch-soc Signed-off-by: Claire commit 0f756eaed263311b82f5a6430497bb535ee31a32 Author: Michael Stanclift Date: Tue Apr 2 04:15:31 2024 -0500 [Glitch] Fix search box color on light theme Port fa9574086d1b2cc16a733cd60677054c67eed48d to glitch-soc Signed-off-by: Claire commit 2c386d4cfee248dd596d3a90e7a51c802d12cab8 Merge: d52263e0e3 c70c39cad0 Author: Claire Date: Wed May 1 17:06:49 2024 +0200 Merge commit 'c70c39cad03824c64564fa7d241e6bf01acbab76' into glitch-soc/merge-upstream commit d52263e0e3c3115166a2ecb8ba9e07a479f90f30 Merge: 3b1c8d56b2 143d9553fa Author: Claire Date: Wed May 1 17:04:33 2024 +0200 Merge commit '143d9553fa0187b9950a802cdedaea5c8cd12f75' into glitch-soc/merge-upstream Conflicts: - `yarn.lock`: Upstream updated dependencies textually close to a glitch-soc-only dependency. Updated the dependencies as well. commit 3b1c8d56b28406dcbac12e6485b5a90d159d69d1 Author: Michael Stanclift Date: Fri Mar 29 16:03:30 2024 -0500 [Glitch] Fix light theme header on mobile Port 90eb4a5d01f1f1e8a76e7dc814eae992a9c1ee16 to glitch-soc Signed-off-by: Claire commit 1783820acd6918e5f757897a10b1d41303eeb4ba Author: Michael Stanclift Date: Fri Mar 29 12:16:51 2024 -0500 [Glitch] Fix background tint in single column light theme Port 430da0316062d3fabfb74dec68bb6de9d42ee750 to glitch-soc Signed-off-by: Claire commit 375bd52d97fde84cab3c2d1c480bc6397217ef7b Author: Renaud Chaput Date: Fri Mar 29 14:57:39 2024 +0100 [Glitch] Handle `createAppAsyncThunk` rejected actions in the errors middleware Port 69e5771881037e52380712dfc029c101f76efe74 to glitch-soc Signed-off-by: Claire commit 7f404fd6358d38fe1d20cb591d95ccba90809d26 Merge: b3d5567bd0 90eb4a5d01 Author: Claire Date: Wed May 1 16:47:25 2024 +0200 Merge commit '90eb4a5d01f1f1e8a76e7dc814eae992a9c1ee16' into glitch-soc/merge-upstream commit b3d5567bd0b78e3b69eecdcbdb85f46bf1df1521 Author: Renaud Chaput Date: Thu Mar 28 16:33:15 2024 +0100 [Glitch] Remove global `boosts` state and convert boosts modal to Typescript Port 67442f90393c644064bf34d531bdebe15f88d729 to glitch-soc Signed-off-by: Claire commit 0f90e624c54a1a2ef810d06c7e3dd75baa063227 Merge: bc370938ef 672c9f5f05 Author: Claire Date: Wed May 1 16:10:45 2024 +0200 Merge commit '672c9f5f05bde788877ae0dcdb6668366c4c8941' into glitch-soc/merge-upstream Conflicts: - `app/helpers/application_helper.rb`: Conflict due to our theming system being different. Ported upstream's changes. commit bc370938ef8e29a32a2563388fd220983b454bb9 Author: Claire Date: Thu Mar 28 15:00:57 2024 +0100 [Glitch] Fix logo pushing header buttons out of view on certain conditions in mobile layout Port 4f068d4fcc4d134fcbd56faa8f39c608dd343417 to glitch-soc Signed-off-by: Claire commit cc720cd38f82ebcd6fb55aaf938e53aa174ac688 Author: Renaud Chaput Date: Thu Mar 28 11:07:01 2024 +0100 [Glitch] Fix `` types Port 961bb84e4c87555bbce930a87291938a988a483a to glitch-soc Signed-off-by: Claire commit 0ab212f6a92b21e2899b3a66ebbbf64ae3e6dec6 Author: Renaud Chaput Date: Thu Mar 28 11:06:25 2024 +0100 [Glitch] Fix props for ` - ); -}; - -BackButton.propTypes = { - pinned: PropTypes.bool, - show: PropTypes.bool, - onlyIcon: PropTypes.bool, -}; - -class ColumnHeader extends PureComponent { - - static contextTypes = { - identity: PropTypes.object, - }; - - static propTypes = { - intl: PropTypes.object.isRequired, - title: PropTypes.node, - icon: PropTypes.string, - iconComponent: PropTypes.func, - active: PropTypes.bool, - multiColumn: PropTypes.bool, - extraButton: PropTypes.node, - showBackButton: PropTypes.bool, - children: PropTypes.node, - pinned: PropTypes.bool, - placeholder: PropTypes.bool, - onPin: PropTypes.func, - onMove: PropTypes.func, - onClick: PropTypes.func, - appendContent: PropTypes.node, - collapseIssues: PropTypes.bool, - ...WithRouterPropTypes, - }; - - state = { - collapsed: true, - animating: false, - }; - - handleToggleClick = (e) => { - e.stopPropagation(); - this.setState({ collapsed: !this.state.collapsed, animating: true }); - }; - - handleTitleClick = () => { - this.props.onClick?.(); - }; - - handleMoveLeft = () => { - this.props.onMove(-1); - }; - - handleMoveRight = () => { - this.props.onMove(1); - }; - - handleTransitionEnd = () => { - this.setState({ animating: false }); - }; - - handlePin = () => { - if (!this.props.pinned) { - this.props.history.replace('/'); - } - - this.props.onPin(); - }; - - render () { - const { title, icon, iconComponent, active, children, pinned, multiColumn, extraButton, showBackButton, intl: { formatMessage }, placeholder, appendContent, collapseIssues } = this.props; - const { collapsed, animating } = this.state; - - const wrapperClassName = classNames('column-header__wrapper', { - 'active': active, - }); - - const buttonClassName = classNames('column-header', { - 'active': active, - }); - - const collapsibleClassName = classNames('column-header__collapsible', { - 'collapsed': collapsed, - 'animating': animating, - }); - - const collapsibleButtonClassName = classNames('column-header__button', { - 'active': !collapsed, - }); - - let extraContent, pinButton, moveButtons, backButton, collapseButton; - - if (children) { - extraContent = ( -
- {children} -
- ); - } - - if (multiColumn && pinned) { - pinButton = ; - - moveButtons = ( -
- - -
- ); - } else if (multiColumn && this.props.onPin) { - pinButton = ; - } - - backButton = ; - - const collapsedContent = [ - extraContent, - ]; - - if (multiColumn) { - collapsedContent.push( -
- {pinButton} - {moveButtons} -
- ); - } - - if (this.context.identity.signedIn && (children || (multiColumn && this.props.onPin))) { - collapseButton = ( - - ); - } - - const hasTitle = (icon || iconComponent) && title; - - const component = ( -
-

- {hasTitle && ( - <> - {showBackButton && backButton} - - - - )} - - {!hasTitle && showBackButton && backButton} - -
- {extraButton} - {collapseButton} -
-

- -
-
- {(!collapsed || animating) && collapsedContent} -
-
- - {appendContent} -
- ); - - if (placeholder) { - return component; - } else { - return ( - {component} - ); - } - } - -} - -export default injectIntl(withRouter(ColumnHeader)); diff --git a/app/javascript/flavours/glitch/components/column_header.tsx b/app/javascript/flavours/glitch/components/column_header.tsx new file mode 100644 index 00000000000000..9bd155990466c8 --- /dev/null +++ b/app/javascript/flavours/glitch/components/column_header.tsx @@ -0,0 +1,301 @@ +import { useCallback, useState } from 'react'; + +import { FormattedMessage, defineMessages, useIntl } from 'react-intl'; + +import classNames from 'classnames'; + +import AddIcon from '@/material-icons/400-24px/add.svg?react'; +import ArrowBackIcon from '@/material-icons/400-24px/arrow_back.svg?react'; +import ChevronLeftIcon from '@/material-icons/400-24px/chevron_left.svg?react'; +import ChevronRightIcon from '@/material-icons/400-24px/chevron_right.svg?react'; +import CloseIcon from '@/material-icons/400-24px/close.svg?react'; +import SettingsIcon from '@/material-icons/400-24px/settings.svg?react'; +import type { IconProp } from 'flavours/glitch/components/icon'; +import { Icon } from 'flavours/glitch/components/icon'; +import { ButtonInTabsBar } from 'flavours/glitch/features/ui/util/columns_context'; +import { useIdentity } from 'flavours/glitch/identity_context'; + +import { useAppHistory } from './router'; + +const messages = defineMessages({ + show: { id: 'column_header.show_settings', defaultMessage: 'Show settings' }, + hide: { id: 'column_header.hide_settings', defaultMessage: 'Hide settings' }, + moveLeft: { + id: 'column_header.moveLeft_settings', + defaultMessage: 'Move column to the left', + }, + moveRight: { + id: 'column_header.moveRight_settings', + defaultMessage: 'Move column to the right', + }, + back: { id: 'column_back_button.label', defaultMessage: 'Back' }, +}); + +const BackButton: React.FC<{ + onlyIcon: boolean; +}> = ({ onlyIcon }) => { + const history = useAppHistory(); + const intl = useIntl(); + + const handleBackClick = useCallback(() => { + if (history.location.state?.fromMastodon) { + history.goBack(); + } else { + history.push('/'); + } + }, [history]); + + return ( + + ); +}; + +export interface Props { + title?: string; + icon?: string; + iconComponent?: IconProp; + active?: boolean; + children?: React.ReactNode; + pinned?: boolean; + multiColumn?: boolean; + extraButton?: React.ReactNode; + showBackButton?: boolean; + placeholder?: boolean; + appendContent?: React.ReactNode; + collapseIssues?: boolean; + onClick?: () => void; + onMove?: (arg0: number) => void; + onPin?: () => void; +} + +export const ColumnHeader: React.FC = ({ + title, + icon, + iconComponent, + active, + children, + pinned, + multiColumn, + extraButton, + showBackButton, + placeholder, + appendContent, + collapseIssues, + onClick, + onMove, + onPin, +}) => { + const intl = useIntl(); + const { signedIn } = useIdentity(); + const history = useAppHistory(); + const [collapsed, setCollapsed] = useState(true); + const [animating, setAnimating] = useState(false); + + const handleToggleClick = useCallback( + (e: React.MouseEvent) => { + e.stopPropagation(); + setCollapsed((value) => !value); + setAnimating(true); + }, + [setCollapsed, setAnimating], + ); + + const handleTitleClick = useCallback(() => { + onClick?.(); + }, [onClick]); + + const handleMoveLeft = useCallback(() => { + onMove?.(-1); + }, [onMove]); + + const handleMoveRight = useCallback(() => { + onMove?.(1); + }, [onMove]); + + const handleTransitionEnd = useCallback(() => { + setAnimating(false); + }, [setAnimating]); + + const handlePin = useCallback(() => { + if (!pinned) { + history.replace('/'); + } + + onPin?.(); + }, [history, pinned, onPin]); + + const wrapperClassName = classNames('column-header__wrapper', { + active, + }); + + const buttonClassName = classNames('column-header', { + active, + }); + + const collapsibleClassName = classNames('column-header__collapsible', { + collapsed, + animating, + }); + + const collapsibleButtonClassName = classNames('column-header__button', { + active: !collapsed, + }); + + let extraContent, pinButton, moveButtons, backButton, collapseButton; + + if (children) { + extraContent = ( +
+ {children} +
+ ); + } + + if (multiColumn && pinned) { + pinButton = ( + + ); + + moveButtons = ( +
+ + +
+ ); + } else if (multiColumn && onPin) { + pinButton = ( + + ); + } + + if ( + !pinned && + ((multiColumn && history.location.state?.fromMastodon) || showBackButton) + ) { + backButton = ; + } + + const collapsedContent = [extraContent]; + + if (multiColumn) { + collapsedContent.push( +
+ {pinButton} + {moveButtons} +
, + ); + } + + if (signedIn && (children || (multiColumn && onPin))) { + collapseButton = ( + + ); + } + + const hasIcon = icon && iconComponent; + const hasTitle = hasIcon && title; + + const component = ( +
+

+ {hasTitle && ( + <> + {backButton} + + + + )} + + {!hasTitle && backButton} + +
+ {extraButton} + {collapseButton} +
+

+ +
+
+ {(!collapsed || animating) && collapsedContent} +
+
+ + {appendContent} +
+ ); + + if (placeholder) { + return component; + } else { + return {component}; + } +}; + +// eslint-disable-next-line import/no-default-export +export default ColumnHeader; diff --git a/app/javascript/flavours/glitch/components/follow_button.tsx b/app/javascript/flavours/glitch/components/follow_button.tsx new file mode 100644 index 00000000000000..a6b206470327ee --- /dev/null +++ b/app/javascript/flavours/glitch/components/follow_button.tsx @@ -0,0 +1,125 @@ +import { useCallback, useEffect } from 'react'; + +import { useIntl, defineMessages, FormattedMessage } from 'react-intl'; + +import { useIdentity } from '@/flavours/glitch/identity_context'; +import { + fetchRelationships, + followAccount, + unfollowAccount, +} from 'flavours/glitch/actions/accounts'; +import { openModal } from 'flavours/glitch/actions/modal'; +import { Button } from 'flavours/glitch/components/button'; +import { LoadingIndicator } from 'flavours/glitch/components/loading_indicator'; +import { me } from 'flavours/glitch/initial_state'; +import { useAppDispatch, useAppSelector } from 'flavours/glitch/store'; + +const messages = defineMessages({ + unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' }, + follow: { id: 'account.follow', defaultMessage: 'Follow' }, + followBack: { id: 'account.follow_back', defaultMessage: 'Follow back' }, + edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' }, +}); + +export const FollowButton: React.FC<{ + accountId?: string; +}> = ({ accountId }) => { + const intl = useIntl(); + const dispatch = useAppDispatch(); + const { signedIn } = useIdentity(); + const account = useAppSelector((state) => + accountId ? state.accounts.get(accountId) : undefined, + ); + const relationship = useAppSelector((state) => + accountId ? state.relationships.get(accountId) : undefined, + ); + const following = relationship?.following || relationship?.requested; + + useEffect(() => { + if (accountId && signedIn) { + dispatch(fetchRelationships([accountId])); + } + }, [dispatch, accountId, signedIn]); + + const handleClick = useCallback(() => { + if (!signedIn) { + dispatch( + openModal({ + modalType: 'INTERACTION', + modalProps: { + type: 'follow', + accountId: accountId, + url: account?.url, + }, + }), + ); + } + + if (!relationship) return; + + if (accountId === me) { + return; + } else if (relationship.following || relationship.requested) { + dispatch( + openModal({ + modalType: 'CONFIRM', + modalProps: { + message: ( + @{account?.acct} }} + /> + ), + confirm: intl.formatMessage(messages.unfollow), + onConfirm: () => { + dispatch(unfollowAccount(accountId)); + }, + }, + }), + ); + } else { + dispatch(followAccount(accountId)); + } + }, [dispatch, intl, accountId, relationship, account, signedIn]); + + let label; + + if (!signedIn) { + label = intl.formatMessage(messages.follow); + } else if (accountId === me) { + label = intl.formatMessage(messages.edit_profile); + } else if (!relationship) { + label = ; + } else if (!relationship.following && relationship.followed_by) { + label = intl.formatMessage(messages.followBack); + } else if (relationship.following || relationship.requested) { + label = intl.formatMessage(messages.unfollow); + } else { + label = intl.formatMessage(messages.follow); + } + + if (accountId === me) { + return ( + + {label} + + ); + } + + return ( + + ); +}; diff --git a/app/javascript/flavours/glitch/components/hashtag_bar.tsx b/app/javascript/flavours/glitch/components/hashtag_bar.tsx index 91fa9221983a70..1642ba65042867 100644 --- a/app/javascript/flavours/glitch/components/hashtag_bar.tsx +++ b/app/javascript/flavours/glitch/components/hashtag_bar.tsx @@ -24,7 +24,7 @@ export type StatusLike = Record<{ function normalizeHashtag(hashtag: string) { return ( - hashtag && hashtag.startsWith('#') ? hashtag.slice(1) : hashtag + !!hashtag && hashtag.startsWith('#') ? hashtag.slice(1) : hashtag ).normalize('NFKC'); } @@ -52,7 +52,10 @@ function uniqueHashtagsWithCaseHandling(hashtags: string[]) { ); return Object.values(groups).map((tags) => { - if (tags.length === 1) return tags[0]; + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- we know that the array has at least one element + const firstTag = tags[0]!; + + if (tags.length === 1) return firstTag; // The best match is the one where we have the less difference between upper and lower case letter count const best = minBy(tags, (tag) => { @@ -66,7 +69,7 @@ function uniqueHashtagsWithCaseHandling(hashtags: string[]) { return Math.abs(lowerCase - upperCase); }); - return best ?? tags[0]; + return best ?? firstTag; }); } diff --git a/app/javascript/flavours/glitch/components/hover_card_account.tsx b/app/javascript/flavours/glitch/components/hover_card_account.tsx new file mode 100644 index 00000000000000..56f431a7867156 --- /dev/null +++ b/app/javascript/flavours/glitch/components/hover_card_account.tsx @@ -0,0 +1,78 @@ +import { useEffect, forwardRef } from 'react'; + +import classNames from 'classnames'; + +import { fetchAccount } from 'flavours/glitch/actions/accounts'; +import { AccountBio } from 'flavours/glitch/components/account_bio'; +import { AccountFields } from 'flavours/glitch/components/account_fields'; +import { Avatar } from 'flavours/glitch/components/avatar'; +import { FollowersCounter } from 'flavours/glitch/components/counters'; +import { DisplayName } from 'flavours/glitch/components/display_name'; +import { FollowButton } from 'flavours/glitch/components/follow_button'; +import { LoadingIndicator } from 'flavours/glitch/components/loading_indicator'; +import { Permalink } from 'flavours/glitch/components/permalink'; +import { ShortNumber } from 'flavours/glitch/components/short_number'; +import { domain } from 'flavours/glitch/initial_state'; +import { useAppSelector, useAppDispatch } from 'flavours/glitch/store'; + +export const HoverCardAccount = forwardRef< + HTMLDivElement, + { accountId?: string } +>(({ accountId }, ref) => { + const dispatch = useAppDispatch(); + + const account = useAppSelector((state) => + accountId ? state.accounts.get(accountId) : undefined, + ); + + useEffect(() => { + if (accountId && !account) { + dispatch(fetchAccount(accountId)); + } + }, [dispatch, accountId, account]); + + return ( + + ); +}); + +HoverCardAccount.displayName = 'HoverCardAccount'; diff --git a/app/javascript/flavours/glitch/components/hover_card_controller.tsx b/app/javascript/flavours/glitch/components/hover_card_controller.tsx new file mode 100644 index 00000000000000..d2a636e939ca4b --- /dev/null +++ b/app/javascript/flavours/glitch/components/hover_card_controller.tsx @@ -0,0 +1,189 @@ +import { useEffect, useRef, useState, useCallback } from 'react'; + +import { useLocation } from 'react-router-dom'; + +import Overlay from 'react-overlays/Overlay'; +import type { + OffsetValue, + UsePopperOptions, +} from 'react-overlays/esm/usePopper'; + +import { HoverCardAccount } from 'flavours/glitch/components/hover_card_account'; +import { useTimeout } from 'flavours/glitch/hooks/useTimeout'; + +const offset = [-12, 4] as OffsetValue; +const enterDelay = 750; +const leaveDelay = 150; +const popperConfig = { strategy: 'fixed' } as UsePopperOptions; + +const isHoverCardAnchor = (element: HTMLElement) => + element.matches('[data-hover-card-account]'); + +export const HoverCardController: React.FC = () => { + const [open, setOpen] = useState(false); + const [accountId, setAccountId] = useState(); + const [anchor, setAnchor] = useState(null); + const cardRef = useRef(null); + const [setLeaveTimeout, cancelLeaveTimeout] = useTimeout(); + const [setEnterTimeout, cancelEnterTimeout, delayEnterTimeout] = useTimeout(); + const [setScrollTimeout] = useTimeout(); + const location = useLocation(); + + const handleClose = useCallback(() => { + cancelEnterTimeout(); + cancelLeaveTimeout(); + setOpen(false); + setAnchor(null); + }, [cancelEnterTimeout, cancelLeaveTimeout, setOpen, setAnchor]); + + useEffect(() => { + handleClose(); + }, [handleClose, location]); + + useEffect(() => { + let isScrolling = false; + let currentAnchor: HTMLElement | null = null; + let currentTitle: string | null = null; + + const open = (target: HTMLElement) => { + target.setAttribute('aria-describedby', 'hover-card'); + setOpen(true); + setAnchor(target); + setAccountId(target.getAttribute('data-hover-card-account') ?? undefined); + }; + + const close = () => { + currentAnchor?.removeAttribute('aria-describedby'); + currentAnchor = null; + setOpen(false); + setAnchor(null); + setAccountId(undefined); + }; + + const handleMouseEnter = (e: MouseEvent) => { + const { target } = e; + + // We've exited the window + if (!(target instanceof HTMLElement)) { + close(); + return; + } + + // We've entered an anchor + if (!isScrolling && isHoverCardAnchor(target)) { + cancelLeaveTimeout(); + + currentAnchor?.removeAttribute('aria-describedby'); + currentAnchor = target; + + currentTitle = target.getAttribute('title'); + target.removeAttribute('title'); + + setEnterTimeout(() => { + open(target); + }, enterDelay); + } + + // We've entered the hover card + if ( + !isScrolling && + (target === currentAnchor || target === cardRef.current) + ) { + cancelLeaveTimeout(); + } + }; + + const handleMouseLeave = (e: MouseEvent) => { + const { target } = e; + + if (!currentAnchor) { + return; + } + + if ( + currentTitle && + target instanceof HTMLElement && + target === currentAnchor + ) + target.setAttribute('title', currentTitle); + + if (target === currentAnchor || target === cardRef.current) { + cancelEnterTimeout(); + + setLeaveTimeout(() => { + close(); + }, leaveDelay); + } + }; + + const handleScrollEnd = () => { + isScrolling = false; + }; + + const handleScroll = () => { + isScrolling = true; + cancelEnterTimeout(); + setScrollTimeout(handleScrollEnd, 100); + }; + + const handleMouseMove = () => { + delayEnterTimeout(enterDelay); + }; + + document.body.addEventListener('mouseenter', handleMouseEnter, { + passive: true, + capture: true, + }); + + document.body.addEventListener('mousemove', handleMouseMove, { + passive: true, + capture: false, + }); + + document.body.addEventListener('mouseleave', handleMouseLeave, { + passive: true, + capture: true, + }); + + document.addEventListener('scroll', handleScroll, { + passive: true, + capture: true, + }); + + return () => { + document.body.removeEventListener('mouseenter', handleMouseEnter); + document.body.removeEventListener('mousemove', handleMouseMove); + document.body.removeEventListener('mouseleave', handleMouseLeave); + document.removeEventListener('scroll', handleScroll); + }; + }, [ + setEnterTimeout, + setLeaveTimeout, + setScrollTimeout, + cancelEnterTimeout, + cancelLeaveTimeout, + delayEnterTimeout, + setOpen, + setAccountId, + setAnchor, + ]); + + return ( + + {({ props }) => ( +
+ +
+ )} +
+ ); +}; diff --git a/app/javascript/flavours/glitch/components/load_gap.tsx b/app/javascript/flavours/glitch/components/load_gap.tsx index f0d15d37761030..1870185c2914d9 100644 --- a/app/javascript/flavours/glitch/components/load_gap.tsx +++ b/app/javascript/flavours/glitch/components/load_gap.tsx @@ -9,18 +9,18 @@ const messages = defineMessages({ load_more: { id: 'status.load_more', defaultMessage: 'Load more' }, }); -interface Props { +interface Props { disabled: boolean; - maxId: string; - onClick: (maxId: string) => void; + param: T; + onClick: (params: T) => void; } -export const LoadGap: React.FC = ({ disabled, maxId, onClick }) => { +export const LoadGap = ({ disabled, param, onClick }: Props) => { const intl = useIntl(); const handleClick = useCallback(() => { - onClick(maxId); - }, [maxId, onClick]); + onClick(param); + }, [param, onClick]); return ( } + {!showResults && } {!showResults && <> · } {showResults && !this.props.disabled && <> · } {votesCount} @@ -247,4 +244,4 @@ class Poll extends ImmutablePureComponent { } -export default injectIntl(Poll); +export default injectIntl(withIdentity(Poll)); diff --git a/app/javascript/flavours/glitch/components/relative_timestamp.tsx b/app/javascript/flavours/glitch/components/relative_timestamp.tsx index b9e1e4f8fd1ff7..ac385e88c651f6 100644 --- a/app/javascript/flavours/glitch/components/relative_timestamp.tsx +++ b/app/javascript/flavours/glitch/components/relative_timestamp.tsx @@ -191,7 +191,7 @@ const timeRemainingString = ( interface Props { intl: IntlShape; timestamp: string; - year: number; + year?: number; futureDate?: boolean; short?: boolean; } @@ -203,11 +203,6 @@ class RelativeTimestamp extends Component { now: Date.now(), }; - static defaultProps = { - year: new Date().getFullYear(), - short: true, - }; - _timer: number | undefined; shouldComponentUpdate(nextProps: Props, nextState: States) { @@ -257,7 +252,13 @@ class RelativeTimestamp extends Component { } render() { - const { timestamp, intl, year, futureDate, short } = this.props; + const { + timestamp, + intl, + futureDate, + year = new Date().getFullYear(), + short = true, + } = this.props; const timeGiven = timestamp.includes('T'); const date = new Date(timestamp); diff --git a/app/javascript/flavours/glitch/components/router.tsx b/app/javascript/flavours/glitch/components/router.tsx index 0637c35ada131f..48f35d8aedefa9 100644 --- a/app/javascript/flavours/glitch/components/router.tsx +++ b/app/javascript/flavours/glitch/components/router.tsx @@ -22,7 +22,7 @@ type LocationState = MastodonLocationState | null | undefined; type HistoryPath = Path | LocationDescriptor; -const browserHistory = createBrowserHistory(); +export const browserHistory = createBrowserHistory(); const originalPush = browserHistory.push.bind(browserHistory); const originalReplace = browserHistory.replace.bind(browserHistory); diff --git a/app/javascript/flavours/glitch/components/server_banner.jsx b/app/javascript/flavours/glitch/components/server_banner.jsx index 1b449ff1a8d9e7..43afebe9cf2b82 100644 --- a/app/javascript/flavours/glitch/components/server_banner.jsx +++ b/app/javascript/flavours/glitch/components/server_banner.jsx @@ -42,10 +42,12 @@ class ServerBanner extends PureComponent { return (
- {domain}, mastodon: Mastodon }} /> + {domain}, mastodon: Mastodon }} />
- + + +
{isLoading ? ( @@ -84,10 +86,6 @@ class ServerBanner extends PureComponent { )}
- -
- - ); } diff --git a/app/javascript/flavours/glitch/components/short_number.tsx b/app/javascript/flavours/glitch/components/short_number.tsx index 74c3c5d75e71cf..a0b523aaadc920 100644 --- a/app/javascript/flavours/glitch/components/short_number.tsx +++ b/app/javascript/flavours/glitch/components/short_number.tsx @@ -48,7 +48,7 @@ const ShortNumberCounter: React.FC = ({ value }) => { const count = ( ); diff --git a/app/javascript/flavours/glitch/components/status.jsx b/app/javascript/flavours/glitch/components/status.jsx index 32a34a086a0f97..a037895b4e1924 100644 --- a/app/javascript/flavours/glitch/components/status.jsx +++ b/app/javascript/flavours/glitch/components/status.jsx @@ -115,6 +115,8 @@ class Status extends ImmutablePureComponent { cacheMediaWidth: PropTypes.func, cachedMediaWidth: PropTypes.number, scrollKey: PropTypes.string, + skipPrepend: PropTypes.bool, + avatarSize: PropTypes.number, deployPictureInPicture: PropTypes.func, settings: ImmutablePropTypes.map.isRequired, pictureInPicture: ImmutablePropTypes.contains({ @@ -440,7 +442,7 @@ class Status extends ImmutablePureComponent { handleHotkeyReply = e => { e.preventDefault(); - this.props.onReply(this.props.status, this.props.history); + this.props.onReply(this.props.status); }; handleHotkeyFavourite = (e) => { @@ -457,7 +459,7 @@ class Status extends ImmutablePureComponent { handleHotkeyMention = e => { e.preventDefault(); - this.props.onMention(this.props.status.get('account'), this.props.history); + this.props.onMention(this.props.status.get('account')); }; handleHotkeyOpen = () => { @@ -518,12 +520,14 @@ class Status extends ImmutablePureComponent { } render () { + const { intl, hidden, featured, unfocusable, unread, pictureInPicture, previousId, nextInReplyToId, rootId, skipPrepend, avatarSize = 46 } = this.props; + const { parseClick, setCollapsed, } = this; + const { - intl, status, account, settings, @@ -533,13 +537,6 @@ class Status extends ImmutablePureComponent { onOpenVideo, onOpenMedia, notification, - hidden, - unread, - featured, - pictureInPicture, - previousId, - nextInReplyToId, - rootId, history, ...other } = this.props; @@ -588,8 +585,8 @@ class Status extends ImmutablePureComponent { if (hidden) { return ( - -
+ +
{status.getIn(['account', 'display_name']) || status.getIn(['account', 'username'])} {status.get('content')}
@@ -609,8 +606,8 @@ class Status extends ImmutablePureComponent { }; return ( - -
+ +
: {matchedFilters.join(', ')}. {' '} - -
- -
- -
-
- )} - -
- ); +export const Upload = ({ id, onDragStart, onDragEnter, onDragEnd }) => { + const dispatch = useDispatch(); + const media = useSelector(state => state.getIn(['compose', 'media_attachments']).find(item => item.get('id') === id)); + const sensitive = useSelector(state => state.getIn(['compose', 'sensitive'])); + + const handleUndoClick = useCallback(() => { + dispatch(undoUploadCompose(id)); + }, [dispatch, id]); + + const handleFocalPointClick = useCallback(() => { + dispatch(initMediaEditModal(id)); + }, [dispatch, id]); + + const handleDragStart = useCallback(() => { + onDragStart(id); + }, [onDragStart, id]); + + const handleDragEnter = useCallback(() => { + onDragEnter(id); + }, [onDragEnter, id]); + + if (!media) { + return null; } -} + const focusX = media.getIn(['meta', 'focus', 'x']); + const focusY = media.getIn(['meta', 'focus', 'y']); + const x = ((focusX / 2) + .5) * 100; + const y = ((focusY / -2) + .5) * 100; + const missingDescription = (media.get('description') || '').length === 0; + + return ( +
+ + {({ scale }) => ( +
+ {sensitive && } + +
+ + +
+ +
+ +
+
+ )} +
+
+ ); +}; + +Upload.propTypes = { + id: PropTypes.string, + onDragEnter: PropTypes.func, + onDragStart: PropTypes.func, + onDragEnd: PropTypes.func, +}; diff --git a/app/javascript/flavours/glitch/features/compose/components/upload_form.jsx b/app/javascript/flavours/glitch/features/compose/components/upload_form.jsx index 5c6406c3bacacc..2b26735f5e1cc5 100644 --- a/app/javascript/flavours/glitch/features/compose/components/upload_form.jsx +++ b/app/javascript/flavours/glitch/features/compose/components/upload_form.jsx @@ -1,35 +1,56 @@ -import ImmutablePropTypes from 'react-immutable-proptypes'; -import ImmutablePureComponent from 'react-immutable-pure-component'; +import { useRef, useCallback } from 'react'; -import UploadContainer from '../containers/upload_container'; -import UploadProgressContainer from '../containers/upload_progress_container'; +import { useSelector, useDispatch } from 'react-redux'; -import { SensitiveButton } from './sensitive_button'; - -export default class UploadForm extends ImmutablePureComponent { - - static propTypes = { - mediaIds: ImmutablePropTypes.list.isRequired, - }; - - render () { - const { mediaIds } = this.props; +import { changeMediaOrder } from 'flavours/glitch/actions/compose'; - return ( - <> - - - {mediaIds.size > 0 && ( -
- {mediaIds.map(id => ( - - ))} -
- )} - - {!mediaIds.isEmpty() && } - - ); - } - -} +import { SensitiveButton } from './sensitive_button'; +import { Upload } from './upload'; +import { UploadProgress } from './upload_progress'; + +export const UploadForm = () => { + const dispatch = useDispatch(); + const mediaIds = useSelector(state => state.getIn(['compose', 'media_attachments']).map(item => item.get('id'))); + const active = useSelector(state => state.getIn(['compose', 'is_uploading'])); + const progress = useSelector(state => state.getIn(['compose', 'progress'])); + const isProcessing = useSelector(state => state.getIn(['compose', 'is_processing'])); + + const dragItem = useRef(); + const dragOverItem = useRef(); + + const handleDragStart = useCallback(id => { + dragItem.current = id; + }, [dragItem]); + + const handleDragEnter = useCallback(id => { + dragOverItem.current = id; + }, [dragOverItem]); + + const handleDragEnd = useCallback(() => { + dispatch(changeMediaOrder(dragItem.current, dragOverItem.current)); + dragItem.current = null; + dragOverItem.current = null; + }, [dispatch, dragItem, dragOverItem]); + + return ( + <> + + + {mediaIds.size > 0 && ( +
+ {mediaIds.map(id => ( + + ))} +
+ )} + + {!mediaIds.isEmpty() && } + + ); +}; diff --git a/app/javascript/flavours/glitch/features/compose/components/upload_progress.jsx b/app/javascript/flavours/glitch/features/compose/components/upload_progress.jsx index 7af5d9090e795b..f72f2c4603ebac 100644 --- a/app/javascript/flavours/glitch/features/compose/components/upload_progress.jsx +++ b/app/javascript/flavours/glitch/features/compose/components/upload_progress.jsx @@ -1,5 +1,4 @@ import PropTypes from 'prop-types'; -import { PureComponent } from 'react'; import { FormattedMessage } from 'react-intl'; @@ -10,46 +9,40 @@ import { Icon } from 'flavours/glitch/components/icon'; import Motion from '../../ui/util/optional_motion'; -export default class UploadProgress extends PureComponent { - - static propTypes = { - active: PropTypes.bool, - progress: PropTypes.number, - isProcessing: PropTypes.bool, - }; - - render () { - const { active, progress, isProcessing } = this.props; - - if (!active) { - return null; - } +export const UploadProgress = ({ active, progress, isProcessing }) => { + if (!active) { + return null; + } - let message; + let message; - if (isProcessing) { - message = ; - } else { - message = ; - } + if (isProcessing) { + message = ; + } else { + message = ; + } - return ( -
- + return ( +
+ -
- {message} +
+ {message} -
- - {({ width }) => -
- } - -
+
+ + {({ width }) => +
+ } +
- ); - } - -} +
+ ); +}; + +UploadProgress.propTypes = { + active: PropTypes.bool, + progress: PropTypes.number, + isProcessing: PropTypes.bool, +}; diff --git a/app/javascript/flavours/glitch/features/compose/containers/compose_form_container.js b/app/javascript/flavours/glitch/features/compose/containers/compose_form_container.js index 067621c84ba627..227e7938695d1e 100644 --- a/app/javascript/flavours/glitch/features/compose/containers/compose_form_container.js +++ b/app/javascript/flavours/glitch/features/compose/containers/compose_form_container.js @@ -82,8 +82,8 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ dispatch(changeCompose(text)); }, - onSubmit (router, overridePrivacy = null) { - dispatch(submitCompose(router, overridePrivacy)); + onSubmit (overridePrivacy = null) { + dispatch(submitCompose(overridePrivacy)); }, onClearSuggestions () { @@ -110,14 +110,14 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ dispatch(insertEmojiCompose(position, data, needsSpace)); }, - onMediaDescriptionConfirm (routerHistory, mediaId, overridePrivacy = null) { + onMediaDescriptionConfirm (mediaId, overridePrivacy = null) { dispatch(openModal({ modalType: 'CONFIRM', modalProps: { message: intl.formatMessage(messages.missingDescriptionMessage), confirm: intl.formatMessage(messages.missingDescriptionConfirm), onConfirm: () => { - dispatch(submitCompose(routerHistory, overridePrivacy)); + dispatch(submitCompose(overridePrivacy)); }, secondary: intl.formatMessage(messages.missingDescriptionEdit), onSecondary: () => dispatch(openModal({ diff --git a/app/javascript/flavours/glitch/features/compose/containers/search_results_container.js b/app/javascript/flavours/glitch/features/compose/containers/search_results_container.js deleted file mode 100644 index 7287a022b4be25..00000000000000 --- a/app/javascript/flavours/glitch/features/compose/containers/search_results_container.js +++ /dev/null @@ -1,20 +0,0 @@ -import { connect } from 'react-redux'; - -import { expandSearch } from 'flavours/glitch/actions/search'; -import { fetchSuggestions, dismissSuggestion } from 'flavours/glitch/actions/suggestions'; - -import SearchResults from '../components/search_results'; - -const mapStateToProps = state => ({ - results: state.getIn(['search', 'results']), - suggestions: state.getIn(['suggestions', 'items']), - searchTerm: state.getIn(['search', 'searchTerm']), -}); - -const mapDispatchToProps = dispatch => ({ - fetchSuggestions: () => dispatch(fetchSuggestions()), - expandSearch: type => dispatch(expandSearch(type)), - dismissSuggestion: account => dispatch(dismissSuggestion(account.get('id'))), -}); - -export default connect(mapStateToProps, mapDispatchToProps)(SearchResults); diff --git a/app/javascript/flavours/glitch/features/compose/containers/upload_button_container.js b/app/javascript/flavours/glitch/features/compose/containers/upload_button_container.js index 2e835464b85119..39cc12078c5116 100644 --- a/app/javascript/flavours/glitch/features/compose/containers/upload_button_container.js +++ b/app/javascript/flavours/glitch/features/compose/containers/upload_button_container.js @@ -10,7 +10,7 @@ const mapStateToProps = state => { const readyAttachmentsSize = state.getIn(['compose', 'media_attachments']).size ?? 0; const pendingAttachmentsSize = state.getIn(['compose', 'pending_media_attachments']).size ?? 0; const attachmentsSize = readyAttachmentsSize + pendingAttachmentsSize; - const isOverLimit = attachmentsSize > 3; + const isOverLimit = attachmentsSize > state.getIn(['server', 'server', 'configuration', 'statuses', 'max_media_attachments'])-1; const hasVideoOrAudio = state.getIn(['compose', 'media_attachments']).some(m => ['video', 'audio'].includes(m.get('type'))); return { diff --git a/app/javascript/flavours/glitch/features/compose/containers/upload_container.js b/app/javascript/flavours/glitch/features/compose/containers/upload_container.js deleted file mode 100644 index 5afe6eaa1adb01..00000000000000 --- a/app/javascript/flavours/glitch/features/compose/containers/upload_container.js +++ /dev/null @@ -1,27 +0,0 @@ -import { connect } from 'react-redux'; - -import { undoUploadCompose, initMediaEditModal, submitCompose } from '../../../actions/compose'; -import Upload from '../components/upload'; - -const mapStateToProps = (state, { id }) => ({ - media: state.getIn(['compose', 'media_attachments']).find(item => item.get('id') === id), - sensitive: state.getIn(['compose', 'sensitive']), -}); - -const mapDispatchToProps = dispatch => ({ - - onUndo: id => { - dispatch(undoUploadCompose(id)); - }, - - onOpenFocalPoint: id => { - dispatch(initMediaEditModal(id)); - }, - - onSubmit (router) { - dispatch(submitCompose(router)); - }, - -}); - -export default connect(mapStateToProps, mapDispatchToProps)(Upload); diff --git a/app/javascript/flavours/glitch/features/compose/containers/upload_form_container.js b/app/javascript/flavours/glitch/features/compose/containers/upload_form_container.js deleted file mode 100644 index 336525cf5399d6..00000000000000 --- a/app/javascript/flavours/glitch/features/compose/containers/upload_form_container.js +++ /dev/null @@ -1,9 +0,0 @@ -import { connect } from 'react-redux'; - -import UploadForm from '../components/upload_form'; - -const mapStateToProps = state => ({ - mediaIds: state.getIn(['compose', 'media_attachments']).map(item => item.get('id')), -}); - -export default connect(mapStateToProps)(UploadForm); diff --git a/app/javascript/flavours/glitch/features/compose/containers/upload_progress_container.js b/app/javascript/flavours/glitch/features/compose/containers/upload_progress_container.js deleted file mode 100644 index ffff321c3fcdf1..00000000000000 --- a/app/javascript/flavours/glitch/features/compose/containers/upload_progress_container.js +++ /dev/null @@ -1,11 +0,0 @@ -import { connect } from 'react-redux'; - -import UploadProgress from '../components/upload_progress'; - -const mapStateToProps = state => ({ - active: state.getIn(['compose', 'is_uploading']), - progress: state.getIn(['compose', 'progress']), - isProcessing: state.getIn(['compose', 'is_processing']), -}); - -export default connect(mapStateToProps)(UploadProgress); diff --git a/app/javascript/flavours/glitch/features/compose/index.jsx b/app/javascript/flavours/glitch/features/compose/index.jsx index 0bba28b78702ba..b59fafe0481676 100644 --- a/app/javascript/flavours/glitch/features/compose/index.jsx +++ b/app/javascript/flavours/glitch/features/compose/index.jsx @@ -32,9 +32,9 @@ import { mascot } from '../../initial_state'; import { isMobile } from '../../is_mobile'; import Motion from '../ui/util/optional_motion'; +import { SearchResults } from './components/search_results'; import ComposeFormContainer from './containers/compose_form_container'; import SearchContainer from './containers/search_container'; -import SearchResultsContainer from './containers/search_results_container'; const messages = defineMessages({ start: { id: 'getting_started.heading', defaultMessage: 'Getting started' }, @@ -183,7 +183,7 @@ class Compose extends PureComponent { {({ x }) => (
- +
)}
diff --git a/app/javascript/flavours/glitch/features/direct_timeline/components/conversation.jsx b/app/javascript/flavours/glitch/features/direct_timeline/components/conversation.jsx index 458a547d020c56..2c70f48a3740fe 100644 --- a/app/javascript/flavours/glitch/features/direct_timeline/components/conversation.jsx +++ b/app/javascript/flavours/glitch/features/direct_timeline/components/conversation.jsx @@ -18,7 +18,7 @@ import ReplyIcon from '@/material-icons/400-24px/reply.svg?react'; import { replyCompose } from 'flavours/glitch/actions/compose'; import { markConversationRead, deleteConversation } from 'flavours/glitch/actions/conversations'; import { openModal } from 'flavours/glitch/actions/modal'; -import { muteStatus, unmuteStatus, revealStatus, hideStatus } from 'flavours/glitch/actions/statuses'; +import { muteStatus, unmuteStatus, toggleStatusSpoilers } from 'flavours/glitch/actions/statuses'; import AttachmentList from 'flavours/glitch/components/attachment_list'; import AvatarComposite from 'flavours/glitch/components/avatar_composite'; import { IconButton } from 'flavours/glitch/components/icon_button'; @@ -126,14 +126,14 @@ export const Conversation = ({ conversation, scrollKey, onMoveUp, onMoveDown }) modalProps: { message: intl.formatMessage(messages.replyMessage), confirm: intl.formatMessage(messages.replyConfirm), - onConfirm: () => dispatch(replyCompose(lastStatus, history)), + onConfirm: () => dispatch(replyCompose(lastStatus)), }, })); } else { - dispatch(replyCompose(lastStatus, history)); + dispatch(replyCompose(lastStatus)); } }); - }, [dispatch, lastStatus, history, intl]); + }, [dispatch, lastStatus, intl]); const handleDelete = useCallback(() => { dispatch(deleteConversation(id)); @@ -156,11 +156,7 @@ export const Conversation = ({ conversation, scrollKey, onMoveUp, onMoveDown }) }, [dispatch, lastStatus]); const handleShowMore = useCallback(() => { - if (lastStatus.get('hidden')) { - dispatch(revealStatus(lastStatus.get('id'))); - } else { - dispatch(hideStatus(lastStatus.get('id'))); - } + dispatch(toggleStatusSpoilers(lastStatus.get('id'))); if (lastStatus.get('spoiler_text')) { setExpanded(!expanded); @@ -185,7 +181,7 @@ export const Conversation = ({ conversation, scrollKey, onMoveUp, onMoveDown }) menu.push({ text: intl.formatMessage(messages.delete), action: handleDelete }); const names = accounts.map(a => ( - + { - const getAccount = makeGetAccount(); - - const mapStateToProps = (state, { id }) => ({ - account: getAccount(state, id), - }); - - return mapStateToProps; -}; - -const mapDispatchToProps = (dispatch, { intl }) => ({ - onFollow(account) { - if (account.getIn(['relationship', 'following'])) { - if (unfollowModal) { - dispatch( - openModal({ - modalType: 'CONFIRM', - modalProps: { - message: ( - @{account.get('acct')} }} - /> - ), - confirm: intl.formatMessage(messages.unfollowConfirm), - onConfirm: () => dispatch(unfollowAccount(account.get('id'))), - } }), - ); - } else { - dispatch(unfollowAccount(account.get('id'))); - } - } else if (account.getIn(['relationship', 'requested'])) { - if (unfollowModal) { - dispatch(openModal({ - modalType: 'CONFIRM', - modalProps: { - message: @{account.get('acct')} }} />, - confirm: intl.formatMessage(messages.cancelFollowRequestConfirm), - onConfirm: () => dispatch(unfollowAccount(account.get('id'))), - }, - })); - } else { - dispatch(unfollowAccount(account.get('id'))); - } - } else { - dispatch(followAccount(account.get('id'))); - } - }, - - onBlock(account) { - if (account.getIn(['relationship', 'blocking'])) { - dispatch(unblockAccount(account.get('id'))); - } - }, - - onMute(account) { - if (account.getIn(['relationship', 'muting'])) { - dispatch(unmuteAccount(account.get('id'))); - } - }, - -}); - -class AccountCard extends ImmutablePureComponent { - - static propTypes = { - account: ImmutablePropTypes.record.isRequired, - intl: PropTypes.object.isRequired, - onFollow: PropTypes.func.isRequired, - onBlock: PropTypes.func.isRequired, - onMute: PropTypes.func.isRequired, - onDismiss: PropTypes.func, - }; - - handleMouseEnter = ({ currentTarget }) => { - if (autoPlayGif) { - return; - } - - const emojis = currentTarget.querySelectorAll('.custom-emoji'); - - for (var i = 0; i < emojis.length; i++) { - let emoji = emojis[i]; - emoji.src = emoji.getAttribute('data-original'); - } - }; - - handleMouseLeave = ({ currentTarget }) => { - if (autoPlayGif) { - return; - } - - const emojis = currentTarget.querySelectorAll('.custom-emoji'); - - for (var i = 0; i < emojis.length; i++) { - let emoji = emojis[i]; - emoji.src = emoji.getAttribute('data-static'); - } - }; - - handleFollow = () => { - this.props.onFollow(this.props.account); - }; - - handleBlock = () => { - this.props.onBlock(this.props.account); - }; - - handleMute = () => { - this.props.onMute(this.props.account); - }; - - handleEditProfile = () => { - window.open('/settings/profile', '_blank'); - }; - - handleDismiss = (e) => { - const { account, onDismiss } = this.props; - onDismiss(account.get('id')); - - e.preventDefault(); - e.stopPropagation(); - }; - - render() { - const { account, intl } = this.props; - - let actionBtn; - - if (me !== account.get('id')) { - if (!account.get('relationship')) { // Wait until the relationship is loaded - actionBtn = ''; - } else if (account.getIn(['relationship', 'requested'])) { - actionBtn =
); }; diff --git a/app/javascript/flavours/glitch/features/home_timeline/index.jsx b/app/javascript/flavours/glitch/features/home_timeline/index.jsx index a2683f587f557f..3220f777e13d05 100644 --- a/app/javascript/flavours/glitch/features/home_timeline/index.jsx +++ b/app/javascript/flavours/glitch/features/home_timeline/index.jsx @@ -14,6 +14,7 @@ import { fetchAnnouncements, toggleShowAnnouncements } from 'flavours/glitch/act import { IconWithBadge } from 'flavours/glitch/components/icon_with_badge'; import { NotSignedInIndicator } from 'flavours/glitch/components/not_signed_in_indicator'; import AnnouncementsContainer from 'flavours/glitch/features/getting_started/containers/announcements_container'; +import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context'; import { criticalUpdatesPending } from 'flavours/glitch/initial_state'; import { addColumn, removeColumn, moveColumn } from '../../actions/columns'; @@ -41,12 +42,8 @@ const mapStateToProps = state => ({ }); class HomeTimeline extends PureComponent { - - static contextTypes = { - identity: PropTypes.object, - }; - static propTypes = { + identity: identityContextPropShape, dispatch: PropTypes.func.isRequired, intl: PropTypes.object.isRequired, hasUnread: PropTypes.bool, @@ -128,7 +125,7 @@ class HomeTimeline extends PureComponent { render () { const { intl, hasUnread, columnId, multiColumn, hasAnnouncements, unreadAnnouncements, showAnnouncements } = this.props; const pinned = !!columnId; - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; const banners = []; let announcementsButton; @@ -192,4 +189,4 @@ class HomeTimeline extends PureComponent { } -export default connect(mapStateToProps)(injectIntl(HomeTimeline)); +export default connect(mapStateToProps)(withIdentity(injectIntl(HomeTimeline))); diff --git a/app/javascript/flavours/glitch/features/keyboard_shortcuts/index.jsx b/app/javascript/flavours/glitch/features/keyboard_shortcuts/index.jsx index 858d760c24dbd1..bc435fbfb18eea 100644 --- a/app/javascript/flavours/glitch/features/keyboard_shortcuts/index.jsx +++ b/app/javascript/flavours/glitch/features/keyboard_shortcuts/index.jsx @@ -123,7 +123,7 @@ class KeyboardShortcuts extends ImmutablePureComponent { - s + s, / diff --git a/app/javascript/flavours/glitch/features/link_timeline/index.tsx b/app/javascript/flavours/glitch/features/link_timeline/index.tsx new file mode 100644 index 00000000000000..bbe295d4741675 --- /dev/null +++ b/app/javascript/flavours/glitch/features/link_timeline/index.tsx @@ -0,0 +1,77 @@ +import { useRef, useEffect, useCallback } from 'react'; + +import { Helmet } from 'react-helmet'; +import { useParams } from 'react-router-dom'; + +import ExploreIcon from '@/material-icons/400-24px/explore.svg?react'; +import { expandLinkTimeline } from 'flavours/glitch/actions/timelines'; +import Column from 'flavours/glitch/components/column'; +import { ColumnHeader } from 'flavours/glitch/components/column_header'; +import StatusListContainer from 'flavours/glitch/features/ui/containers/status_list_container'; +import type { Card } from 'flavours/glitch/models/status'; +import { useAppDispatch, useAppSelector } from 'flavours/glitch/store'; + +export const LinkTimeline: React.FC<{ + multiColumn: boolean; +}> = ({ multiColumn }) => { + const { url } = useParams<{ url: string }>(); + const decodedUrl = url ? decodeURIComponent(url) : undefined; + const dispatch = useAppDispatch(); + const columnRef = useRef(null); + const firstStatusId = useAppSelector((state) => + decodedUrl + ? // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access + (state.timelines.getIn([`link:${decodedUrl}`, 'items', 0]) as string) + : undefined, + ); + const story = useAppSelector((state) => + firstStatusId + ? (state.statuses.getIn([firstStatusId, 'card']) as Card) + : undefined, + ); + + const handleHeaderClick = useCallback(() => { + columnRef.current?.scrollTop(); + }, []); + + const handleLoadMore = useCallback( + (maxId: string) => { + dispatch(expandLinkTimeline(decodedUrl, { maxId })); + }, + [dispatch, decodedUrl], + ); + + useEffect(() => { + dispatch(expandLinkTimeline(decodedUrl)); + }, [dispatch, decodedUrl]); + + return ( + + + + + + + {story?.title} + + + + ); +}; + +// eslint-disable-next-line import/no-default-export +export default LinkTimeline; diff --git a/app/javascript/flavours/glitch/features/notifications/components/admin_report.jsx b/app/javascript/flavours/glitch/features/notifications/components/admin_report.jsx deleted file mode 100644 index 5ca8b59a5e2aad..00000000000000 --- a/app/javascript/flavours/glitch/features/notifications/components/admin_report.jsx +++ /dev/null @@ -1,114 +0,0 @@ -import PropTypes from 'prop-types'; - -import { FormattedMessage } from 'react-intl'; - -import classNames from 'classnames'; -import { withRouter } from 'react-router-dom'; - -import ImmutablePropTypes from 'react-immutable-proptypes'; -import ImmutablePureComponent from 'react-immutable-pure-component'; - -import { HotKeys } from 'react-hotkeys'; - -import FlagIcon from '@/material-icons/400-24px/flag-fill.svg?react'; -import { Icon } from 'flavours/glitch/components/icon'; -import { Permalink } from 'flavours/glitch/components/permalink'; -import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router'; - -import NotificationOverlayContainer from '../containers/overlay_container'; - -import Report from './report'; - -class AdminReport extends ImmutablePureComponent { - - static propTypes = { - hidden: PropTypes.bool, - id: PropTypes.string.isRequired, - account: ImmutablePropTypes.map.isRequired, - notification: ImmutablePropTypes.map.isRequired, - unread: PropTypes.bool, - report: ImmutablePropTypes.map.isRequired, - ...WithRouterPropTypes, - }; - - handleMoveUp = () => { - const { notification, onMoveUp } = this.props; - onMoveUp(notification.get('id')); - }; - - handleMoveDown = () => { - const { notification, onMoveDown } = this.props; - onMoveDown(notification.get('id')); - }; - - handleOpen = () => { - this.handleOpenProfile(); - }; - - handleOpenProfile = () => { - const { history, notification } = this.props; - history.push(`/@${notification.getIn(['account', 'acct'])}`); - }; - - handleMention = e => { - e.preventDefault(); - - const { history, notification, onMention } = this.props; - onMention(notification.get('account'), history); - }; - - getHandlers () { - return { - moveUp: this.handleMoveUp, - moveDown: this.handleMoveDown, - open: this.handleOpen, - openProfile: this.handleOpenProfile, - mention: this.handleMention, - reply: this.handleMention, - }; - } - - render () { - const { account, notification, unread, report } = this.props; - - if (!report) { - return null; - } - - // Links to the display name. - const displayName = account.get('display_name_html') || account.get('username'); - const link = ( - - ); - - const targetAccount = report.get('target_account'); - const targetDisplayNameHtml = { __html: targetAccount.get('display_name_html') }; - const targetLink = ; - - return ( - -
-
- - - - - -
- -
-
- ); - } - -} - -export default withRouter(AdminReport); diff --git a/app/javascript/flavours/glitch/features/notifications/components/admin_signup.jsx b/app/javascript/flavours/glitch/features/notifications/components/admin_signup.jsx deleted file mode 100644 index 4c815099b12f60..00000000000000 --- a/app/javascript/flavours/glitch/features/notifications/components/admin_signup.jsx +++ /dev/null @@ -1,107 +0,0 @@ -import PropTypes from 'prop-types'; - -import { FormattedMessage } from 'react-intl'; - -import classNames from 'classnames'; -import { withRouter } from 'react-router-dom'; - -import ImmutablePropTypes from 'react-immutable-proptypes'; -import ImmutablePureComponent from 'react-immutable-pure-component'; - -import { HotKeys } from 'react-hotkeys'; - -import PersonAddIcon from '@/material-icons/400-24px/person_add-fill.svg?react'; -import { Icon } from 'flavours/glitch/components/icon'; -import { Permalink } from 'flavours/glitch/components/permalink'; -import AccountContainer from 'flavours/glitch/containers/account_container'; -import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router'; - -import NotificationOverlayContainer from '../containers/overlay_container'; - -class NotificationAdminSignup extends ImmutablePureComponent { - - static propTypes = { - hidden: PropTypes.bool, - id: PropTypes.string.isRequired, - account: ImmutablePropTypes.map.isRequired, - notification: ImmutablePropTypes.map.isRequired, - unread: PropTypes.bool, - ...WithRouterPropTypes, - }; - - handleMoveUp = () => { - const { notification, onMoveUp } = this.props; - onMoveUp(notification.get('id')); - }; - - handleMoveDown = () => { - const { notification, onMoveDown } = this.props; - onMoveDown(notification.get('id')); - }; - - handleOpen = () => { - this.handleOpenProfile(); - }; - - handleOpenProfile = () => { - const { history, notification } = this.props; - history.push(`/@${notification.getIn(['account', 'acct'])}`); - }; - - handleMention = e => { - e.preventDefault(); - - const { history, notification, onMention } = this.props; - onMention(notification.get('account'), history); - }; - - getHandlers () { - return { - moveUp: this.handleMoveUp, - moveDown: this.handleMoveDown, - open: this.handleOpen, - openProfile: this.handleOpenProfile, - mention: this.handleMention, - reply: this.handleMention, - }; - } - - render () { - const { account, notification, hidden, unread } = this.props; - - // Links to the display name. - const displayName = account.get('display_name_html') || account.get('username'); - const link = ( - - ); - - // Renders. - return ( - -
-
- - - -
- -
-
- ); - } - -} - -export default withRouter(NotificationAdminSignup); diff --git a/app/javascript/flavours/glitch/features/notifications/components/column_settings.jsx b/app/javascript/flavours/glitch/features/notifications/components/column_settings.jsx index 3f02df18818086..3423517227da0f 100644 --- a/app/javascript/flavours/glitch/features/notifications/components/column_settings.jsx +++ b/app/javascript/flavours/glitch/features/notifications/components/column_settings.jsx @@ -5,6 +5,7 @@ import { FormattedMessage } from 'react-intl'; import ImmutablePropTypes from 'react-immutable-proptypes'; +import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context'; import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_REPORTS } from 'flavours/glitch/permissions'; import { CheckboxWithLabel } from './checkbox_with_label'; @@ -13,13 +14,9 @@ import GrantPermissionButton from './grant_permission_button'; import PillBarButton from './pill_bar_button'; import SettingToggle from './setting_toggle'; -export default class ColumnSettings extends PureComponent { - - static contextTypes = { - identity: PropTypes.object, - }; - +class ColumnSettings extends PureComponent { static propTypes = { + identity: identityContextPropShape, settings: ImmutablePropTypes.map.isRequired, pushSettings: ImmutablePropTypes.map.isRequired, onChange: PropTypes.func.isRequired, @@ -28,7 +25,7 @@ export default class ColumnSettings extends PureComponent { alertsEnabled: PropTypes.bool, browserSupport: PropTypes.bool, browserPermission: PropTypes.string, - notificationPolicy: ImmutablePropTypes.map, + notificationPolicy: PropTypes.object.isRequired, onChangePolicy: PropTypes.func.isRequired, }; @@ -56,6 +53,7 @@ export default class ColumnSettings extends PureComponent { const { settings, pushSettings, onChange, onClear, alertsEnabled, browserSupport, browserPermission, onRequestNotificationPermission, notificationPolicy } = this.props; const unreadMarkersShowStr = ; + const groupingShowStr = ; const filterBarShowStr = ; const filterAdvancedStr = ; const alertStr = ; @@ -87,22 +85,22 @@ export default class ColumnSettings extends PureComponent {

- + - + - + - + @@ -118,6 +116,16 @@ export default class ColumnSettings extends PureComponent {
+
+

+ +

+ +
+ +
+
+

@@ -216,7 +224,7 @@ export default class ColumnSettings extends PureComponent {

- {((this.context.identity.permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS) && ( + {((this.props.identity.permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS) && (

@@ -229,7 +237,7 @@ export default class ColumnSettings extends PureComponent {
)} - {((this.context.identity.permissions & PERMISSION_MANAGE_REPORTS) === PERMISSION_MANAGE_REPORTS) && ( + {((this.props.identity.permissions & PERMISSION_MANAGE_REPORTS) === PERMISSION_MANAGE_REPORTS) && (

@@ -246,3 +254,5 @@ export default class ColumnSettings extends PureComponent { } } + +export default withIdentity(ColumnSettings); diff --git a/app/javascript/flavours/glitch/features/notifications/components/filtered_notifications_banner.jsx b/app/javascript/flavours/glitch/features/notifications/components/filtered_notifications_banner.jsx deleted file mode 100644 index 59496628288476..00000000000000 --- a/app/javascript/flavours/glitch/features/notifications/components/filtered_notifications_banner.jsx +++ /dev/null @@ -1,48 +0,0 @@ -import { useEffect } from 'react'; - -import { FormattedMessage } from 'react-intl'; - -import { Link } from 'react-router-dom'; - -import { useDispatch, useSelector } from 'react-redux'; - -import InventoryIcon from '@/material-icons/400-24px/inventory_2.svg?react'; -import { fetchNotificationPolicy } from 'flavours/glitch/actions/notifications'; -import { Icon } from 'flavours/glitch/components/icon'; -import { toCappedNumber } from 'flavours/glitch/utils/numbers'; - -export const FilteredNotificationsBanner = () => { - const dispatch = useDispatch(); - const policy = useSelector(state => state.get('notificationPolicy')); - - useEffect(() => { - dispatch(fetchNotificationPolicy()); - - const interval = setInterval(() => { - dispatch(fetchNotificationPolicy()); - }, 120000); - - return () => { - clearInterval(interval); - }; - }, [dispatch]); - - if (policy === null || policy.getIn(['summary', 'pending_notifications_count']) * 1 === 0) { - return null; - } - - return ( - - - -
- - -
- -
- {toCappedNumber(policy.getIn(['summary', 'pending_notifications_count']))} -
- - ); -}; diff --git a/app/javascript/flavours/glitch/features/notifications/components/filtered_notifications_banner.tsx b/app/javascript/flavours/glitch/features/notifications/components/filtered_notifications_banner.tsx new file mode 100644 index 00000000000000..2be6ac84662bba --- /dev/null +++ b/app/javascript/flavours/glitch/features/notifications/components/filtered_notifications_banner.tsx @@ -0,0 +1,70 @@ +import { useEffect } from 'react'; + +import { FormattedMessage } from 'react-intl'; + +import { Link } from 'react-router-dom'; + +import InventoryIcon from '@/material-icons/400-24px/inventory_2.svg?react'; +import { fetchNotificationPolicy } from 'flavours/glitch/actions/notification_policies'; +import { Icon } from 'flavours/glitch/components/icon'; +import { useAppSelector, useAppDispatch } from 'flavours/glitch/store'; +import { toCappedNumber } from 'flavours/glitch/utils/numbers'; + +export const FilteredNotificationsBanner: React.FC = () => { + const dispatch = useAppDispatch(); + const policy = useAppSelector((state) => state.notificationPolicy); + + useEffect(() => { + void dispatch(fetchNotificationPolicy()); + + const interval = setInterval(() => { + void dispatch(fetchNotificationPolicy()); + }, 120000); + + return () => { + clearInterval(interval); + }; + }, [dispatch]); + + if (policy === null || policy.summary.pending_notifications_count === 0) { + return null; + } + + return ( + +
+ +
+ +
+ + + + + + +
+ +
+
+ {toCappedNumber(policy.summary.pending_notifications_count)} +
+ +
+ + ); +}; diff --git a/app/javascript/flavours/glitch/features/notifications/components/follow.jsx b/app/javascript/flavours/glitch/features/notifications/components/follow.jsx deleted file mode 100644 index d26039fd5faf06..00000000000000 --- a/app/javascript/flavours/glitch/features/notifications/components/follow.jsx +++ /dev/null @@ -1,107 +0,0 @@ -import PropTypes from 'prop-types'; - -import { FormattedMessage } from 'react-intl'; - -import classNames from 'classnames'; -import { withRouter } from 'react-router-dom'; - -import ImmutablePropTypes from 'react-immutable-proptypes'; -import ImmutablePureComponent from 'react-immutable-pure-component'; - -import { HotKeys } from 'react-hotkeys'; - -import PersonAddIcon from '@/material-icons/400-24px/person_add-fill.svg?react'; -import { Icon } from 'flavours/glitch/components/icon'; -import { Permalink } from 'flavours/glitch/components/permalink'; -import AccountContainer from 'flavours/glitch/containers/account_container'; -import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router'; - -import NotificationOverlayContainer from '../containers/overlay_container'; - -class NotificationFollow extends ImmutablePureComponent { - - static propTypes = { - hidden: PropTypes.bool, - id: PropTypes.string.isRequired, - account: ImmutablePropTypes.map.isRequired, - notification: ImmutablePropTypes.map.isRequired, - unread: PropTypes.bool, - ...WithRouterPropTypes, - }; - - handleMoveUp = () => { - const { notification, onMoveUp } = this.props; - onMoveUp(notification.get('id')); - }; - - handleMoveDown = () => { - const { notification, onMoveDown } = this.props; - onMoveDown(notification.get('id')); - }; - - handleOpen = () => { - this.handleOpenProfile(); - }; - - handleOpenProfile = () => { - const { history, notification } = this.props; - history.push(`/@${notification.getIn(['account', 'acct'])}`); - }; - - handleMention = e => { - e.preventDefault(); - - const { history, notification, onMention } = this.props; - onMention(notification.get('account'), history); - }; - - getHandlers () { - return { - moveUp: this.handleMoveUp, - moveDown: this.handleMoveDown, - open: this.handleOpen, - openProfile: this.handleOpenProfile, - mention: this.handleMention, - reply: this.handleMention, - }; - } - - render () { - const { account, notification, hidden, unread } = this.props; - - // Links to the display name. - const displayName = account.get('display_name_html') || account.get('username'); - const link = ( - - ); - - // Renders. - return ( - -
-
- - - -
- -
-
- ); - } - -} - -export default withRouter(NotificationFollow); diff --git a/app/javascript/flavours/glitch/features/notifications/components/follow_request.jsx b/app/javascript/flavours/glitch/features/notifications/components/follow_request.jsx index 11aa343609a735..bd45e1f826c0fa 100644 --- a/app/javascript/flavours/glitch/features/notifications/components/follow_request.jsx +++ b/app/javascript/flavours/glitch/features/notifications/components/follow_request.jsx @@ -1,26 +1,16 @@ import PropTypes from 'prop-types'; -import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; - -import classNames from 'classnames'; -import { withRouter } from 'react-router-dom'; +import { defineMessages, injectIntl } from 'react-intl'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; -import { HotKeys } from 'react-hotkeys'; - import CheckIcon from '@/material-icons/400-24px/check.svg?react'; import CloseIcon from '@/material-icons/400-24px/close.svg?react'; -import PersonIcon from '@/material-icons/400-24px/person-fill.svg?react'; import { Avatar } from 'flavours/glitch/components/avatar'; import { DisplayName } from 'flavours/glitch/components/display_name'; -import { Icon } from 'flavours/glitch/components/icon'; import { IconButton } from 'flavours/glitch/components/icon_button'; import { Permalink } from 'flavours/glitch/components/permalink'; -import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router'; - -import NotificationOverlayContainer from '../containers/overlay_container'; const messages = defineMessages({ authorize: { id: 'follow_request.authorize', defaultMessage: 'Authorize' }, @@ -34,50 +24,10 @@ class FollowRequest extends ImmutablePureComponent { onAuthorize: PropTypes.func.isRequired, onReject: PropTypes.func.isRequired, intl: PropTypes.object.isRequired, - notification: ImmutablePropTypes.map.isRequired, - unread: PropTypes.bool, - ...WithRouterPropTypes, - }; - - handleMoveUp = () => { - const { notification, onMoveUp } = this.props; - onMoveUp(notification.get('id')); - }; - - handleMoveDown = () => { - const { notification, onMoveDown } = this.props; - onMoveDown(notification.get('id')); - }; - - handleOpen = () => { - this.handleOpenProfile(); }; - handleOpenProfile = () => { - const { history, notification } = this.props; - history.push(`/@${notification.getIn(['account', 'acct'])}`); - }; - - handleMention = e => { - e.preventDefault(); - - const { history, notification, onMention } = this.props; - onMention(notification.get('account'), history); - }; - - getHandlers () { - return { - moveUp: this.handleMoveUp, - moveDown: this.handleMoveDown, - open: this.handleOpen, - openProfile: this.handleOpenProfile, - mention: this.handleMention, - reply: this.handleMention, - }; - } - render () { - const { intl, hidden, account, onAuthorize, onReject, notification, unread } = this.props; + const { intl, hidden, account, onAuthorize, onReject } = this.props; if (!account) { return
; @@ -92,51 +42,23 @@ class FollowRequest extends ImmutablePureComponent { ); } - // Links to the display name. - const displayName = account.get('display_name_html') || account.get('username'); - const link = ( - - ); - return ( - -
-
- - - +
+
+ +
+ +
+ +
+ +
- -
-
- -
- -
- -
- - -
-
-
- -
- +
); } } -export default withRouter(injectIntl(FollowRequest)); +export default injectIntl(FollowRequest); diff --git a/app/javascript/flavours/glitch/features/notifications/components/moderation_warning.tsx b/app/javascript/flavours/glitch/features/notifications/components/moderation_warning.tsx new file mode 100644 index 00000000000000..16eac6ded55a30 --- /dev/null +++ b/app/javascript/flavours/glitch/features/notifications/components/moderation_warning.tsx @@ -0,0 +1,89 @@ +import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; + +import classNames from 'classnames'; + +import GavelIcon from '@/material-icons/400-24px/gavel.svg?react'; +import { Icon } from 'flavours/glitch/components/icon'; +import type { AccountWarningAction } from 'flavours/glitch/models/notification_group'; + +// This needs to be kept in sync with app/models/account_warning.rb +const messages = defineMessages({ + none: { + id: 'notification.moderation_warning.action_none', + defaultMessage: 'Your account has received a moderation warning.', + }, + disable: { + id: 'notification.moderation_warning.action_disable', + defaultMessage: 'Your account has been disabled.', + }, + mark_statuses_as_sensitive: { + id: 'notification.moderation_warning.action_mark_statuses_as_sensitive', + defaultMessage: 'Some of your posts have been marked as sensitive.', + }, + delete_statuses: { + id: 'notification.moderation_warning.action_delete_statuses', + defaultMessage: 'Some of your posts have been removed.', + }, + sensitive: { + id: 'notification.moderation_warning.action_sensitive', + defaultMessage: 'Your posts will be marked as sensitive from now on.', + }, + silence: { + id: 'notification.moderation_warning.action_silence', + defaultMessage: 'Your account has been limited.', + }, + suspend: { + id: 'notification.moderation_warning.action_suspend', + defaultMessage: 'Your account has been suspended.', + }, +}); + +interface Props { + action: AccountWarningAction; + id: string; + hidden?: boolean; + unread?: boolean; +} + +export const ModerationWarning: React.FC = ({ + action, + id, + hidden, + unread, +}) => { + const intl = useIntl(); + + if (hidden) { + return null; + } + + return ( +
+
+ +
+ +
+

{intl.formatMessage(messages[action])}

+ + + +
+
+ ); +}; diff --git a/app/javascript/flavours/glitch/features/notifications/components/notification.jsx b/app/javascript/flavours/glitch/features/notifications/components/notification.jsx index 1d476969cb3d72..1a049847d5b792 100644 --- a/app/javascript/flavours/glitch/features/notifications/components/notification.jsx +++ b/app/javascript/flavours/glitch/features/notifications/components/notification.jsx @@ -1,236 +1,464 @@ -// Package imports. import PropTypes from 'prop-types'; +import { injectIntl, FormattedMessage, defineMessages } from 'react-intl'; + +import classNames from 'classnames'; +import { withRouter } from 'react-router-dom'; + import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; -// Our imports, +import { HotKeys } from 'react-hotkeys'; + +import FlagIcon from '@/material-icons/400-24px/flag-fill.svg?react'; +import PersonIcon from '@/material-icons/400-24px/person-fill.svg?react'; +import PersonAddIcon from '@/material-icons/400-24px/person_add-fill.svg?react'; +import { Icon } from 'flavours/glitch/components/icon'; +import { Permalink } from 'flavours/glitch/components/permalink'; +import AccountContainer from 'flavours/glitch/containers/account_container'; import StatusContainer from 'flavours/glitch/containers/status_container'; +import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router'; + +import FollowRequestContainer from '../containers/follow_request_container'; +import NotificationOverlayContainer from '../containers/overlay_container'; + +import { ModerationWarning } from './moderation_warning'; +import { RelationshipsSeveranceEvent } from './relationships_severance_event'; +import Report from './report'; + +const messages = defineMessages({ + follow: { id: 'notification.follow', defaultMessage: '{name} followed you' }, + adminSignUp: { id: 'notification.admin.sign_up', defaultMessage: '{name} signed up' }, + adminReport: { id: 'notification.admin.report', defaultMessage: '{name} reported {target}' }, + relationshipsSevered: { id: 'notification.relationships_severance_event', defaultMessage: 'Lost connections with {name}' }, + moderationWarning: { id: 'notification.moderation_warning', defaultMessage: 'You have received a moderation warning' }, +}); -import NotificationAdminReportContainer from '../containers/admin_report_container'; -import NotificationFollowRequestContainer from '../containers/follow_request_container'; +const notificationForScreenReader = (intl, message, timestamp) => { + const output = [message]; -import NotificationAdminSignup from './admin_signup'; -import NotificationFollow from './follow'; + output.push(intl.formatDate(timestamp, { hour: '2-digit', minute: '2-digit', month: 'short', day: 'numeric' })); -export default class Notification extends ImmutablePureComponent { + return output.join(', '); +}; +class Notification extends ImmutablePureComponent { static propTypes = { notification: ImmutablePropTypes.map.isRequired, hidden: PropTypes.bool, onMoveUp: PropTypes.func.isRequired, onMoveDown: PropTypes.func.isRequired, onMention: PropTypes.func.isRequired, + onFavourite: PropTypes.func.isRequired, + onReblog: PropTypes.func.isRequired, + onToggleHidden: PropTypes.func.isRequired, + status: ImmutablePropTypes.map, + intl: PropTypes.object.isRequired, getScrollPosition: PropTypes.func, updateScrollBottom: PropTypes.func, cacheMediaWidth: PropTypes.func, cachedMediaWidth: PropTypes.number, onUnmount: PropTypes.func, unread: PropTypes.bool, + ...WithRouterPropTypes, + }; + + handleMoveUp = () => { + const { notification, onMoveUp } = this.props; + onMoveUp(notification.get('id')); + }; + + handleMoveDown = () => { + const { notification, onMoveDown } = this.props; + onMoveDown(notification.get('id')); + }; + + handleOpen = () => { + const { notification } = this.props; + + if (notification.get('status')) { + this.props.history.push(`/@${notification.getIn(['status', 'account', 'acct'])}/${notification.get('status')}`); + } else { + this.handleOpenProfile(); + } + }; + + handleOpenProfile = () => { + const { notification } = this.props; + this.props.history.push(`/@${notification.getIn(['account', 'acct'])}`); + }; + + handleMention = e => { + e.preventDefault(); + + const { notification, onMention } = this.props; + onMention(notification.get('account')); + }; + + handleHotkeyFavourite = () => { + const { status } = this.props; + if (status) this.props.onFavourite(status); }; + handleHotkeyBoost = e => { + const { status } = this.props; + if (status) this.props.onReblog(status, e); + }; + + getHandlers () { + return { + reply: this.handleMention, + favourite: this.handleHotkeyFavourite, + boost: this.handleHotkeyBoost, + mention: this.handleMention, + open: this.handleOpen, + openProfile: this.handleOpenProfile, + moveUp: this.handleMoveUp, + moveDown: this.handleMoveDown, + }; + } + + renderFollow (notification, account, link) { + const { intl, unread } = this.props; + + return ( + +
+
+ + + + + +
+ +
+
+ ); + } + + renderFollowRequest (notification, account, link) { + const { intl, unread } = this.props; + + return ( + +
+
+ + + + + +
+ +
+
+ ); + } + + renderMention (notification) { + return ( +
diff --git a/app/javascript/flavours/glitch/features/notifications/components/relationships_severance_event.jsx b/app/javascript/flavours/glitch/features/notifications/components/relationships_severance_event.jsx new file mode 100644 index 00000000000000..397a2b7558be09 --- /dev/null +++ b/app/javascript/flavours/glitch/features/notifications/components/relationships_severance_event.jsx @@ -0,0 +1,48 @@ +import PropTypes from 'prop-types'; + +import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; + +import classNames from 'classnames'; + +import HeartBrokenIcon from '@/material-icons/400-24px/heart_broken-fill.svg?react'; +import { Icon } from 'flavours/glitch/components/icon'; +import { domain } from 'flavours/glitch/initial_state'; + +// This needs to be kept in sync with app/models/relationships_severance_event.rb +const messages = defineMessages({ + account_suspension: { id: 'notification.relationships_severance_event.account_suspension', defaultMessage: 'An admin from {from} has suspended {target}, which means you can no longer receive updates from them or interact with them.' }, + domain_block: { id: 'notification.relationships_severance_event.domain_block', defaultMessage: 'An admin from {from} has blocked {target}, including {followersCount} of your followers and {followingCount, plural, one {# account} other {# accounts}} you follow.' }, + user_domain_block: { id: 'notification.relationships_severance_event.user_domain_block', defaultMessage: 'You have blocked {target}, removing {followersCount} of your followers and {followingCount, plural, one {# account} other {# accounts}} you follow.' }, +}); + +export const RelationshipsSeveranceEvent = ({ type, target, followingCount, followersCount, hidden, unread }) => { + const intl = useIntl(); + + if (hidden) { + return null; + } + + return ( +
+
+ +
+

{intl.formatMessage(messages[type], { from: {domain}, target: {target}, followingCount, followersCount })}

+ +
+
+ ); +}; + +RelationshipsSeveranceEvent.propTypes = { + type: PropTypes.oneOf([ + 'account_suspension', + 'domain_block', + 'user_domain_block', + ]).isRequired, + target: PropTypes.string.isRequired, + followersCount: PropTypes.number.isRequired, + followingCount: PropTypes.number.isRequired, + hidden: PropTypes.bool, + unread: PropTypes.bool, +}; diff --git a/app/javascript/flavours/glitch/features/notifications/containers/admin_report_container.js b/app/javascript/flavours/glitch/features/notifications/containers/admin_report_container.js deleted file mode 100644 index 62809b57b2bc8f..00000000000000 --- a/app/javascript/flavours/glitch/features/notifications/containers/admin_report_container.js +++ /dev/null @@ -1,15 +0,0 @@ -import { connect } from 'react-redux'; - -import { makeGetReport } from 'flavours/glitch/selectors'; - -import AdminReport from '../components/admin_report'; - -const mapStateToProps = (state, { notification }) => { - const getReport = makeGetReport(); - - return { - report: notification.get('report') ? getReport(state, notification.get('report'), notification.getIn(['report', 'target_account', 'id'])) : null, - }; -}; - -export default connect(mapStateToProps)(AdminReport); diff --git a/app/javascript/flavours/glitch/features/notifications/containers/column_settings_container.js b/app/javascript/flavours/glitch/features/notifications/containers/column_settings_container.js index de266160f8511c..55dcd4226c9859 100644 --- a/app/javascript/flavours/glitch/features/notifications/containers/column_settings_container.js +++ b/app/javascript/flavours/glitch/features/notifications/containers/column_settings_container.js @@ -2,9 +2,13 @@ import { defineMessages, injectIntl } from 'react-intl'; import { connect } from 'react-redux'; +import { initializeNotifications } from 'flavours/glitch/actions/notifications_migration'; + import { showAlert } from '../../../actions/alerts'; import { openModal } from '../../../actions/modal'; -import { setFilter, clearNotifications, requestBrowserPermission, updateNotificationsPolicy } from '../../../actions/notifications'; +import { clearNotifications } from '../../../actions/notification_groups'; +import { updateNotificationsPolicy } from '../../../actions/notification_policies'; +import { setFilter, requestBrowserPermission } from '../../../actions/notifications'; import { changeAlerts as changePushNotifications } from '../../../actions/push_notifications'; import { changeSetting } from '../../../actions/settings'; import ColumnSettings from '../components/column_settings'; @@ -15,13 +19,16 @@ const messages = defineMessages({ permissionDenied: { id: 'notifications.permission_denied_alert', defaultMessage: 'Desktop notifications can\'t be enabled, as browser permission has been denied before' }, }); +/** + * @param {import('flavours/glitch/store').RootState} state + */ const mapStateToProps = state => ({ settings: state.getIn(['settings', 'notifications']), pushSettings: state.get('push_notifications'), alertsEnabled: state.getIn(['settings', 'notifications', 'alerts']).includes(true), browserSupport: state.getIn(['notifications', 'browserSupport']), browserPermission: state.getIn(['notifications', 'browserPermission']), - notificationPolicy: state.get('notificationPolicy'), + notificationPolicy: state.notificationPolicy, }); const mapDispatchToProps = (dispatch, { intl }) => ({ @@ -54,6 +61,9 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ } else { dispatch(changeSetting(['notifications', ...path], checked)); } + } else if(path[0] === 'groupingBeta') { + dispatch(changeSetting(['notifications', ...path], checked)); + dispatch(initializeNotifications()); } else { dispatch(changeSetting(['notifications', ...path], checked)); } diff --git a/app/javascript/flavours/glitch/features/notifications/containers/follow_request_container.js b/app/javascript/flavours/glitch/features/notifications/containers/follow_request_container.js index d66b24991df5de..ad87da84aab7a1 100644 --- a/app/javascript/flavours/glitch/features/notifications/containers/follow_request_container.js +++ b/app/javascript/flavours/glitch/features/notifications/containers/follow_request_container.js @@ -1,17 +1,28 @@ import { connect } from 'react-redux'; import { authorizeFollowRequest, rejectFollowRequest } from 'flavours/glitch/actions/accounts'; +import { makeGetAccount } from 'flavours/glitch/selectors'; import FollowRequest from '../components/follow_request'; -const mapDispatchToProps = (dispatch, { account }) => ({ +const makeMapStateToProps = () => { + const getAccount = makeGetAccount(); + + const mapStateToProps = (state, props) => ({ + account: getAccount(state, props.id), + }); + + return mapStateToProps; +}; + +const mapDispatchToProps = (dispatch, { id }) => ({ onAuthorize () { - dispatch(authorizeFollowRequest(account.get('id'))); + dispatch(authorizeFollowRequest(id)); }, onReject () { - dispatch(rejectFollowRequest(account.get('id'))); + dispatch(rejectFollowRequest(id)); }, }); -export default connect(null, mapDispatchToProps)(FollowRequest); +export default connect(makeMapStateToProps, mapDispatchToProps)(FollowRequest); diff --git a/app/javascript/flavours/glitch/features/notifications/containers/notification_container.js b/app/javascript/flavours/glitch/features/notifications/containers/notification_container.js index 2fda4ac3a2c7d2..8ecea4bc735731 100644 --- a/app/javascript/flavours/glitch/features/notifications/containers/notification_container.js +++ b/app/javascript/flavours/glitch/features/notifications/containers/notification_container.js @@ -1,24 +1,42 @@ import { connect } from 'react-redux'; -import { mentionCompose } from 'flavours/glitch/actions/compose'; -import { makeGetNotification } from 'flavours/glitch/selectors'; - +import { mentionCompose } from '../../../actions/compose'; +import { + toggleReblog, + toggleFavourite, +} from '../../../actions/interactions'; +import { makeGetNotification, makeGetStatus, makeGetReport } from '../../../selectors'; import Notification from '../components/notification'; const makeMapStateToProps = () => { const getNotification = makeGetNotification(); + const getStatus = makeGetStatus(); + const getReport = makeGetReport(); - const mapStateToProps = (state, props) => ({ - notification: getNotification(state, props.notification, props.accountId), - notifCleaning: state.getIn(['notifications', 'cleaningMode']), - }); + const mapStateToProps = (state, props) => { + const notification = getNotification(state, props.notification, props.accountId); + return { + notification: notification, + status: notification.get('status') ? getStatus(state, { id: notification.get('status'), contextType: 'notifications' }) : null, + report: notification.get('report') ? getReport(state, notification.get('report'), notification.getIn(['report', 'target_account', 'id'])) : null, + notifCleaning: state.getIn(['notifications', 'cleaningMode']), + }; + }; return mapStateToProps; }; const mapDispatchToProps = dispatch => ({ - onMention: (account, history) => { - dispatch(mentionCompose(account, history)); + onMention: (account) => { + dispatch(mentionCompose(account)); + }, + + onReblog (status, e) { + dispatch(toggleReblog(status.get('id'), e.shiftKey)); + }, + + onFavourite (status, e) { + dispatch(toggleFavourite(status.get('id'), e.shiftKey)); }, }); diff --git a/app/javascript/flavours/glitch/features/notifications/index.jsx b/app/javascript/flavours/glitch/features/notifications/index.jsx index e84ef70b05cd15..2d3d4377561e7e 100644 --- a/app/javascript/flavours/glitch/features/notifications/index.jsx +++ b/app/javascript/flavours/glitch/features/notifications/index.jsx @@ -19,6 +19,7 @@ import NotificationsIcon from '@/material-icons/400-24px/notifications-fill.svg? import { compareId } from 'flavours/glitch/compare_id'; import { Icon } from 'flavours/glitch/components/icon'; import { NotSignedInIndicator } from 'flavours/glitch/components/not_signed_in_indicator'; +import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context'; import { addColumn, removeColumn, moveColumn } from '../../actions/columns'; import { submitMarkers } from '../../actions/markers'; @@ -93,12 +94,8 @@ const mapDispatchToProps = dispatch => ({ }); class Notifications extends PureComponent { - - static contextTypes = { - identity: PropTypes.object, - }; - static propTypes = { + identity: identityContextPropShape, columnId: PropTypes.string, notifications: ImmutablePropTypes.list.isRequired, showFilterBar: PropTypes.bool.isRequired, @@ -225,7 +222,7 @@ class Notifications extends PureComponent { const { animatingNCD } = this.state; const pinned = !!columnId; const emptyMessage = ; - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; let scrollableContent = null; @@ -240,7 +237,7 @@ class Notifications extends PureComponent { 0 ? notifications.getIn([index - 1, 'id']) : null} + param={index > 0 ? notifications.getIn([index - 1, 'id']) : null} onClick={this.handleLoadGap} /> ) : ( @@ -261,6 +258,13 @@ class Notifications extends PureComponent { let scrollContainer; + const prepend = ( + <> + {needsNotificationPermission && } + + + ); + if (signedIn) { scrollContainer = ( } + prepend={prepend} alwaysPrepend emptyMessage={emptyMessage} onLoadMore={this.handleLoadOlder} @@ -359,8 +363,6 @@ class Notifications extends PureComponent { {filterBarContainer} - - {scrollContainer} @@ -373,4 +375,4 @@ class Notifications extends PureComponent { } -export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(Notifications)); +export default connect(mapStateToProps, mapDispatchToProps)(withIdentity(injectIntl(Notifications))); diff --git a/app/javascript/flavours/glitch/features/notifications_v2/components/avatar_group.tsx b/app/javascript/flavours/glitch/features/notifications_v2/components/avatar_group.tsx new file mode 100644 index 00000000000000..48f2328bbbcfc2 --- /dev/null +++ b/app/javascript/flavours/glitch/features/notifications_v2/components/avatar_group.tsx @@ -0,0 +1,31 @@ +import { Link } from 'react-router-dom'; + +import { Avatar } from 'flavours/glitch/components/avatar'; +import { NOTIFICATIONS_GROUP_MAX_AVATARS } from 'flavours/glitch/models/notification_group'; +import { useAppSelector } from 'flavours/glitch/store'; + +const AvatarWrapper: React.FC<{ accountId: string }> = ({ accountId }) => { + const account = useAppSelector((state) => state.accounts.get(accountId)); + + if (!account) return null; + + return ( + + + + ); +}; + +export const AvatarGroup: React.FC<{ accountIds: string[] }> = ({ + accountIds, +}) => ( +
+ {accountIds.slice(0, NOTIFICATIONS_GROUP_MAX_AVATARS).map((accountId) => ( + + ))} +
+); diff --git a/app/javascript/flavours/glitch/features/notifications_v2/components/embedded_status.tsx b/app/javascript/flavours/glitch/features/notifications_v2/components/embedded_status.tsx new file mode 100644 index 00000000000000..3ff021e574eede --- /dev/null +++ b/app/javascript/flavours/glitch/features/notifications_v2/components/embedded_status.tsx @@ -0,0 +1,159 @@ +import { useCallback, useRef } from 'react'; + +import { FormattedMessage } from 'react-intl'; + +import { useHistory } from 'react-router-dom'; + +import type { List as ImmutableList, RecordOf } from 'immutable'; + +import BarChart4BarsIcon from '@/material-icons/400-24px/bar_chart_4_bars.svg?react'; +import PhotoLibraryIcon from '@/material-icons/400-24px/photo_library.svg?react'; +import { Avatar } from 'flavours/glitch/components/avatar'; +import { DisplayName } from 'flavours/glitch/components/display_name'; +import { Icon } from 'flavours/glitch/components/icon'; +import type { Status } from 'flavours/glitch/models/status'; +import { useAppSelector } from 'flavours/glitch/store'; + +import { EmbeddedStatusContent } from './embedded_status_content'; + +export type Mention = RecordOf<{ url: string; acct: string }>; + +export const EmbeddedStatus: React.FC<{ statusId: string }> = ({ + statusId, +}) => { + const history = useHistory(); + const clickCoordinatesRef = useRef<[number, number] | null>(); + + const status = useAppSelector( + (state) => state.statuses.get(statusId) as Status | undefined, + ); + + const account = useAppSelector((state) => + state.accounts.get(status?.get('account') as string), + ); + + const handleMouseDown = useCallback>( + ({ clientX, clientY }) => { + clickCoordinatesRef.current = [clientX, clientY]; + }, + [clickCoordinatesRef], + ); + + const handleMouseUp = useCallback>( + ({ clientX, clientY, target, button }) => { + const [startX, startY] = clickCoordinatesRef.current ?? [0, 0]; + const [deltaX, deltaY] = [ + Math.abs(clientX - startX), + Math.abs(clientY - startY), + ]; + + let element: HTMLDivElement | null = target as HTMLDivElement; + + while (element) { + if ( + element.localName === 'button' || + element.localName === 'a' || + element.localName === 'label' + ) { + return; + } + + element = element.parentNode as HTMLDivElement | null; + } + + if (deltaX + deltaY < 5 && button === 0 && account) { + history.push(`/@${account.acct}/${statusId}`); + } + + clickCoordinatesRef.current = null; + }, + [clickCoordinatesRef, statusId, account, history], + ); + + const handleMouseEnter = useCallback>( + ({ currentTarget }) => { + const emojis = + currentTarget.querySelectorAll('.custom-emoji'); + + for (const emoji of emojis) { + const newSrc = emoji.getAttribute('data-original'); + if (newSrc) emoji.src = newSrc; + } + }, + [], + ); + + const handleMouseLeave = useCallback>( + ({ currentTarget }) => { + const emojis = + currentTarget.querySelectorAll('.custom-emoji'); + + for (const emoji of emojis) { + const newSrc = emoji.getAttribute('data-static'); + if (newSrc) emoji.src = newSrc; + } + }, + [], + ); + + if (!status) { + return null; + } + + // Assign status attributes to variables with a forced type, as status is not yet properly typed + const contentHtml = status.get('contentHtml') as string; + const poll = status.get('poll'); + const language = status.get('language') as string; + const mentions = status.get('mentions') as ImmutableList; + const mediaAttachmentsSize = ( + status.get('media_attachments') as ImmutableList + ).size; + + return ( +
+
+ + +
+ + + + {(poll || mediaAttachmentsSize > 0) && ( +
+ {!!poll && ( + <> + + + + )} + {mediaAttachmentsSize > 0 && ( + <> + + + + )} +
+ )} +
+ ); +}; diff --git a/app/javascript/flavours/glitch/features/notifications_v2/components/embedded_status_content.tsx b/app/javascript/flavours/glitch/features/notifications_v2/components/embedded_status_content.tsx new file mode 100644 index 00000000000000..1a38be536ba6a8 --- /dev/null +++ b/app/javascript/flavours/glitch/features/notifications_v2/components/embedded_status_content.tsx @@ -0,0 +1,93 @@ +import { useCallback } from 'react'; + +import { useHistory } from 'react-router-dom'; + +import type { List } from 'immutable'; + +import type { History } from 'history'; + +import type { Mention } from './embedded_status'; + +const handleMentionClick = ( + history: History, + mention: Mention, + e: MouseEvent, +) => { + if (e.button === 0 && !(e.ctrlKey || e.metaKey)) { + e.preventDefault(); + history.push(`/@${mention.get('acct')}`); + } +}; + +const handleHashtagClick = ( + history: History, + hashtag: string, + e: MouseEvent, +) => { + if (e.button === 0 && !(e.ctrlKey || e.metaKey)) { + e.preventDefault(); + history.push(`/tags/${hashtag.replace(/^#/, '')}`); + } +}; + +export const EmbeddedStatusContent: React.FC<{ + content: string; + mentions: List; + language: string; + className?: string; +}> = ({ content, mentions, language, className }) => { + const history = useHistory(); + + const handleContentRef = useCallback( + (node: HTMLDivElement | null) => { + if (!node) { + return; + } + + const links = node.querySelectorAll('a'); + + for (const link of links) { + if (link.classList.contains('status-link')) { + continue; + } + + link.classList.add('status-link'); + + const mention = mentions.find((item) => link.href === item.get('url')); + + if (mention) { + link.addEventListener( + 'click', + handleMentionClick.bind(null, history, mention), + false, + ); + link.setAttribute('title', `@${mention.get('acct')}`); + link.setAttribute('href', `/@${mention.get('acct')}`); + } else if ( + link.textContent?.[0] === '#' || + link.previousSibling?.textContent?.endsWith('#') + ) { + link.addEventListener( + 'click', + handleHashtagClick.bind(null, history, link.text), + false, + ); + link.setAttribute('href', `/tags/${link.text.replace(/^#/, '')}`); + } else { + link.setAttribute('title', link.href); + link.classList.add('unhandled-link'); + } + } + }, + [mentions, history], + ); + + return ( +
+ ); +}; diff --git a/app/javascript/flavours/glitch/features/notifications_v2/components/names_list.tsx b/app/javascript/flavours/glitch/features/notifications_v2/components/names_list.tsx new file mode 100644 index 00000000000000..a46b584e46b3c6 --- /dev/null +++ b/app/javascript/flavours/glitch/features/notifications_v2/components/names_list.tsx @@ -0,0 +1,51 @@ +import { FormattedMessage } from 'react-intl'; + +import { Link } from 'react-router-dom'; + +import { useAppSelector } from 'flavours/glitch/store'; + +export const NamesList: React.FC<{ + accountIds: string[]; + total: number; + seeMoreHref?: string; +}> = ({ accountIds, total, seeMoreHref }) => { + const lastAccountId = accountIds[0] ?? '0'; + const account = useAppSelector((state) => state.accounts.get(lastAccountId)); + + if (!account) return null; + + const displayedName = ( + + + + ); + + if (total === 1) { + return displayedName; + } + + if (seeMoreHref) + return ( + {chunks}, + }} + /> + ); + + return ( + + ); +}; diff --git a/app/javascript/flavours/glitch/features/notifications_v2/components/notification_admin_report.tsx b/app/javascript/flavours/glitch/features/notifications_v2/components/notification_admin_report.tsx new file mode 100644 index 00000000000000..fc2d3149b3006f --- /dev/null +++ b/app/javascript/flavours/glitch/features/notifications_v2/components/notification_admin_report.tsx @@ -0,0 +1,132 @@ +import { FormattedMessage, useIntl, defineMessages } from 'react-intl'; + +import classNames from 'classnames'; + +import FlagIcon from '@/material-icons/400-24px/flag-fill.svg?react'; +import { Icon } from 'flavours/glitch/components/icon'; +import { RelativeTimestamp } from 'flavours/glitch/components/relative_timestamp'; +import type { NotificationGroupAdminReport } from 'flavours/glitch/models/notification_group'; +import { useAppSelector } from 'flavours/glitch/store'; + +// This needs to be kept in sync with app/models/report.rb +const messages = defineMessages({ + other: { + id: 'report_notification.categories.other_sentence', + defaultMessage: 'other', + }, + spam: { + id: 'report_notification.categories.spam_sentence', + defaultMessage: 'spam', + }, + legal: { + id: 'report_notification.categories.legal_sentence', + defaultMessage: 'illegal content', + }, + violation: { + id: 'report_notification.categories.violation_sentence', + defaultMessage: 'rule violation', + }, +}); + +export const NotificationAdminReport: React.FC<{ + notification: NotificationGroupAdminReport; + unread?: boolean; +}> = ({ notification, notification: { report }, unread }) => { + const intl = useIntl(); + const targetAccount = useAppSelector((state) => + state.accounts.get(report.targetAccountId), + ); + const account = useAppSelector((state) => + state.accounts.get(notification.sampleAccountIds[0] ?? '0'), + ); + + if (!account || !targetAccount) return null; + + const values = { + name: ( + + ), + target: ( + + ), + category: intl.formatMessage(messages[report.category]), + count: report.status_ids.length, + }; + + let message; + + if (report.status_ids.length > 0) { + if (report.category === 'other') { + message = ( + + ); + } else { + message = ( + + ); + } + } else { + if (report.category === 'other') { + message = ( + + ); + } else { + message = ( + + ); + } + } + + return ( + +
+ +
+ +
+
+
+ {message} + +
+
+ + {report.comment.length > 0 && ( +
+ “{report.comment}†+
+ )} +
+
+ ); +}; diff --git a/app/javascript/flavours/glitch/features/notifications_v2/components/notification_admin_sign_up.tsx b/app/javascript/flavours/glitch/features/notifications_v2/components/notification_admin_sign_up.tsx new file mode 100644 index 00000000000000..8a56b880a8ed13 --- /dev/null +++ b/app/javascript/flavours/glitch/features/notifications_v2/components/notification_admin_sign_up.tsx @@ -0,0 +1,31 @@ +import { FormattedMessage } from 'react-intl'; + +import PersonAddIcon from '@/material-icons/400-24px/person_add-fill.svg?react'; +import type { NotificationGroupAdminSignUp } from 'flavours/glitch/models/notification_group'; + +import type { LabelRenderer } from './notification_group_with_status'; +import { NotificationGroupWithStatus } from './notification_group_with_status'; + +const labelRenderer: LabelRenderer = (values) => ( + +); + +export const NotificationAdminSignUp: React.FC<{ + notification: NotificationGroupAdminSignUp; + unread: boolean; +}> = ({ notification, unread }) => ( + +); diff --git a/app/javascript/flavours/glitch/features/notifications_v2/components/notification_favourite.tsx b/app/javascript/flavours/glitch/features/notifications_v2/components/notification_favourite.tsx new file mode 100644 index 00000000000000..8e16a042ced32e --- /dev/null +++ b/app/javascript/flavours/glitch/features/notifications_v2/components/notification_favourite.tsx @@ -0,0 +1,45 @@ +import { FormattedMessage } from 'react-intl'; + +import StarIcon from '@/material-icons/400-24px/star-fill.svg?react'; +import type { NotificationGroupFavourite } from 'flavours/glitch/models/notification_group'; +import { useAppSelector } from 'flavours/glitch/store'; + +import type { LabelRenderer } from './notification_group_with_status'; +import { NotificationGroupWithStatus } from './notification_group_with_status'; + +const labelRenderer: LabelRenderer = (values) => ( + +); + +export const NotificationFavourite: React.FC<{ + notification: NotificationGroupFavourite; + unread: boolean; +}> = ({ notification, unread }) => { + const { statusId } = notification; + const statusAccount = useAppSelector( + (state) => + state.accounts.get(state.statuses.getIn([statusId, 'account']) as string) + ?.acct, + ); + + return ( + + ); +}; diff --git a/app/javascript/flavours/glitch/features/notifications_v2/components/notification_follow.tsx b/app/javascript/flavours/glitch/features/notifications_v2/components/notification_follow.tsx new file mode 100644 index 00000000000000..92d28dccbde33c --- /dev/null +++ b/app/javascript/flavours/glitch/features/notifications_v2/components/notification_follow.tsx @@ -0,0 +1,31 @@ +import { FormattedMessage } from 'react-intl'; + +import PersonAddIcon from '@/material-icons/400-24px/person_add-fill.svg?react'; +import type { NotificationGroupFollow } from 'flavours/glitch/models/notification_group'; + +import type { LabelRenderer } from './notification_group_with_status'; +import { NotificationGroupWithStatus } from './notification_group_with_status'; + +const labelRenderer: LabelRenderer = (values) => ( + +); + +export const NotificationFollow: React.FC<{ + notification: NotificationGroupFollow; + unread: boolean; +}> = ({ notification, unread }) => ( + +); diff --git a/app/javascript/flavours/glitch/features/notifications_v2/components/notification_follow_request.tsx b/app/javascript/flavours/glitch/features/notifications_v2/components/notification_follow_request.tsx new file mode 100644 index 00000000000000..eff233152d1a24 --- /dev/null +++ b/app/javascript/flavours/glitch/features/notifications_v2/components/notification_follow_request.tsx @@ -0,0 +1,78 @@ +import { useCallback } from 'react'; + +import { FormattedMessage, useIntl, defineMessages } from 'react-intl'; + +import CheckIcon from '@/material-icons/400-24px/check.svg?react'; +import CloseIcon from '@/material-icons/400-24px/close.svg?react'; +import PersonAddIcon from '@/material-icons/400-24px/person_add-fill.svg?react'; +import { + authorizeFollowRequest, + rejectFollowRequest, +} from 'flavours/glitch/actions/accounts'; +import { IconButton } from 'flavours/glitch/components/icon_button'; +import type { NotificationGroupFollowRequest } from 'flavours/glitch/models/notification_group'; +import { useAppDispatch } from 'flavours/glitch/store'; + +import type { LabelRenderer } from './notification_group_with_status'; +import { NotificationGroupWithStatus } from './notification_group_with_status'; + +const messages = defineMessages({ + authorize: { id: 'follow_request.authorize', defaultMessage: 'Authorize' }, + reject: { id: 'follow_request.reject', defaultMessage: 'Reject' }, +}); + +const labelRenderer: LabelRenderer = (values) => ( + +); + +export const NotificationFollowRequest: React.FC<{ + notification: NotificationGroupFollowRequest; + unread: boolean; +}> = ({ notification, unread }) => { + const intl = useIntl(); + + const dispatch = useAppDispatch(); + + const onAuthorize = useCallback(() => { + dispatch(authorizeFollowRequest(notification.sampleAccountIds[0])); + }, [dispatch, notification.sampleAccountIds]); + + const onReject = useCallback(() => { + dispatch(rejectFollowRequest(notification.sampleAccountIds[0])); + }, [dispatch, notification.sampleAccountIds]); + + const actions = ( +
+ + +
+ ); + + return ( + + ); +}; diff --git a/app/javascript/flavours/glitch/features/notifications_v2/components/notification_group.tsx b/app/javascript/flavours/glitch/features/notifications_v2/components/notification_group.tsx new file mode 100644 index 00000000000000..f4275179c5efe9 --- /dev/null +++ b/app/javascript/flavours/glitch/features/notifications_v2/components/notification_group.tsx @@ -0,0 +1,151 @@ +import { useMemo } from 'react'; + +import { HotKeys } from 'react-hotkeys'; + +import { navigateToProfile } from 'flavours/glitch/actions/accounts'; +import { mentionComposeById } from 'flavours/glitch/actions/compose'; +import type { NotificationGroup as NotificationGroupModel } from 'flavours/glitch/models/notification_group'; +import { useAppSelector, useAppDispatch } from 'flavours/glitch/store'; + +import { NotificationAdminReport } from './notification_admin_report'; +import { NotificationAdminSignUp } from './notification_admin_sign_up'; +import { NotificationFavourite } from './notification_favourite'; +import { NotificationFollow } from './notification_follow'; +import { NotificationFollowRequest } from './notification_follow_request'; +import { NotificationMention } from './notification_mention'; +import { NotificationModerationWarning } from './notification_moderation_warning'; +import { NotificationPoll } from './notification_poll'; +import { NotificationReblog } from './notification_reblog'; +import { NotificationSeveredRelationships } from './notification_severed_relationships'; +import { NotificationStatus } from './notification_status'; +import { NotificationUpdate } from './notification_update'; + +export const NotificationGroup: React.FC<{ + notificationGroupId: NotificationGroupModel['group_key']; + unread: boolean; + onMoveUp: (groupId: string) => void; + onMoveDown: (groupId: string) => void; +}> = ({ notificationGroupId, unread, onMoveUp, onMoveDown }) => { + const notificationGroup = useAppSelector((state) => + state.notificationGroups.groups.find( + (item) => item.type !== 'gap' && item.group_key === notificationGroupId, + ), + ); + + const dispatch = useAppDispatch(); + + const accountId = + notificationGroup?.type === 'gap' + ? undefined + : notificationGroup?.sampleAccountIds[0]; + + const handlers = useMemo( + () => ({ + moveUp: () => { + onMoveUp(notificationGroupId); + }, + + moveDown: () => { + onMoveDown(notificationGroupId); + }, + + openProfile: () => { + if (accountId) dispatch(navigateToProfile(accountId)); + }, + + mention: () => { + if (accountId) dispatch(mentionComposeById(accountId)); + }, + }), + [dispatch, notificationGroupId, accountId, onMoveUp, onMoveDown], + ); + + if (!notificationGroup || notificationGroup.type === 'gap') return null; + + let content; + + switch (notificationGroup.type) { + case 'reblog': + content = ( + + ); + break; + case 'favourite': + content = ( + + ); + break; + case 'severed_relationships': + content = ( + + ); + break; + case 'mention': + content = ( + + ); + break; + case 'follow': + content = ( + + ); + break; + case 'follow_request': + content = ( + + ); + break; + case 'poll': + content = ( + + ); + break; + case 'status': + content = ( + + ); + break; + case 'update': + content = ( + + ); + break; + case 'admin.sign_up': + content = ( + + ); + break; + case 'admin.report': + content = ( + + ); + break; + case 'moderation_warning': + content = ( + + ); + break; + default: + return null; + } + + return {content}; +}; diff --git a/app/javascript/flavours/glitch/features/notifications_v2/components/notification_group_with_status.tsx b/app/javascript/flavours/glitch/features/notifications_v2/components/notification_group_with_status.tsx new file mode 100644 index 00000000000000..a7c1170d854d06 --- /dev/null +++ b/app/javascript/flavours/glitch/features/notifications_v2/components/notification_group_with_status.tsx @@ -0,0 +1,113 @@ +import { useMemo } from 'react'; + +import classNames from 'classnames'; + +import { HotKeys } from 'react-hotkeys'; + +import { replyComposeById } from 'flavours/glitch/actions/compose'; +import { navigateToStatus } from 'flavours/glitch/actions/statuses'; +import type { IconProp } from 'flavours/glitch/components/icon'; +import { Icon } from 'flavours/glitch/components/icon'; +import { RelativeTimestamp } from 'flavours/glitch/components/relative_timestamp'; +import { useAppDispatch } from 'flavours/glitch/store'; + +import { AvatarGroup } from './avatar_group'; +import { EmbeddedStatus } from './embedded_status'; +import { NamesList } from './names_list'; + +export type LabelRenderer = ( + values: Record, +) => JSX.Element; + +export const NotificationGroupWithStatus: React.FC<{ + icon: IconProp; + iconId: string; + statusId?: string; + actions?: JSX.Element; + count: number; + accountIds: string[]; + timestamp: string; + labelRenderer: LabelRenderer; + labelSeeMoreHref?: string; + type: string; + unread: boolean; +}> = ({ + icon, + iconId, + timestamp, + accountIds, + actions, + count, + statusId, + labelRenderer, + labelSeeMoreHref, + type, + unread, +}) => { + const dispatch = useAppDispatch(); + + const label = useMemo( + () => + labelRenderer({ + name: ( + + ), + }), + [labelRenderer, accountIds, count, labelSeeMoreHref], + ); + + const handlers = useMemo( + () => ({ + open: () => { + dispatch(navigateToStatus(statusId)); + }, + + reply: () => { + dispatch(replyComposeById(statusId)); + }, + }), + [dispatch, statusId], + ); + + return ( + +
+
+ +
+ +
+
+
+ + + {actions} +
+ +
+ {label} + {timestamp && } +
+
+ + {statusId && ( +
+ +
+ )} +
+
+
+ ); +}; diff --git a/app/javascript/flavours/glitch/features/notifications_v2/components/notification_mention.tsx b/app/javascript/flavours/glitch/features/notifications_v2/components/notification_mention.tsx new file mode 100644 index 00000000000000..8d2d5a6282acd1 --- /dev/null +++ b/app/javascript/flavours/glitch/features/notifications_v2/components/notification_mention.tsx @@ -0,0 +1,55 @@ +import { FormattedMessage } from 'react-intl'; + +import ReplyIcon from '@/material-icons/400-24px/reply-fill.svg?react'; +import type { StatusVisibility } from 'flavours/glitch/api_types/statuses'; +import type { NotificationGroupMention } from 'flavours/glitch/models/notification_group'; +import { useAppSelector } from 'flavours/glitch/store'; + +import type { LabelRenderer } from './notification_group_with_status'; +import { NotificationWithStatus } from './notification_with_status'; + +const labelRenderer: LabelRenderer = (values) => ( + +); + +const privateMentionLabelRenderer: LabelRenderer = (values) => ( + +); + +export const NotificationMention: React.FC<{ + notification: NotificationGroupMention; + unread: boolean; +}> = ({ notification, unread }) => { + const statusVisibility = useAppSelector( + (state) => + state.statuses.getIn([ + notification.statusId, + 'visibility', + ]) as StatusVisibility, + ); + + return ( + + ); +}; diff --git a/app/javascript/flavours/glitch/features/notifications_v2/components/notification_moderation_warning.tsx b/app/javascript/flavours/glitch/features/notifications_v2/components/notification_moderation_warning.tsx new file mode 100644 index 00000000000000..6faf4c2a745b1a --- /dev/null +++ b/app/javascript/flavours/glitch/features/notifications_v2/components/notification_moderation_warning.tsx @@ -0,0 +1,13 @@ +import { ModerationWarning } from 'flavours/glitch/features/notifications/components/moderation_warning'; +import type { NotificationGroupModerationWarning } from 'flavours/glitch/models/notification_group'; + +export const NotificationModerationWarning: React.FC<{ + notification: NotificationGroupModerationWarning; + unread: boolean; +}> = ({ notification: { moderationWarning }, unread }) => ( + +); diff --git a/app/javascript/flavours/glitch/features/notifications_v2/components/notification_poll.tsx b/app/javascript/flavours/glitch/features/notifications_v2/components/notification_poll.tsx new file mode 100644 index 00000000000000..1e62a18483ffee --- /dev/null +++ b/app/javascript/flavours/glitch/features/notifications_v2/components/notification_poll.tsx @@ -0,0 +1,41 @@ +import { FormattedMessage } from 'react-intl'; + +import BarChart4BarsIcon from '@/material-icons/400-20px/bar_chart_4_bars.svg?react'; +import { me } from 'flavours/glitch/initial_state'; +import type { NotificationGroupPoll } from 'flavours/glitch/models/notification_group'; + +import { NotificationWithStatus } from './notification_with_status'; + +const labelRendererOther = () => ( + +); + +const labelRendererOwn = () => ( + +); + +export const NotificationPoll: React.FC<{ + notification: NotificationGroupPoll; + unread: boolean; +}> = ({ notification, unread }) => ( + +); diff --git a/app/javascript/flavours/glitch/features/notifications_v2/components/notification_reblog.tsx b/app/javascript/flavours/glitch/features/notifications_v2/components/notification_reblog.tsx new file mode 100644 index 00000000000000..0748b56c9479c5 --- /dev/null +++ b/app/javascript/flavours/glitch/features/notifications_v2/components/notification_reblog.tsx @@ -0,0 +1,45 @@ +import { FormattedMessage } from 'react-intl'; + +import RepeatIcon from '@/material-icons/400-24px/repeat.svg?react'; +import type { NotificationGroupReblog } from 'flavours/glitch/models/notification_group'; +import { useAppSelector } from 'flavours/glitch/store'; + +import type { LabelRenderer } from './notification_group_with_status'; +import { NotificationGroupWithStatus } from './notification_group_with_status'; + +const labelRenderer: LabelRenderer = (values) => ( + +); + +export const NotificationReblog: React.FC<{ + notification: NotificationGroupReblog; + unread: boolean; +}> = ({ notification, unread }) => { + const { statusId } = notification; + const statusAccount = useAppSelector( + (state) => + state.accounts.get(state.statuses.getIn([statusId, 'account']) as string) + ?.acct, + ); + + return ( + + ); +}; diff --git a/app/javascript/flavours/glitch/features/notifications_v2/components/notification_severed_relationships.tsx b/app/javascript/flavours/glitch/features/notifications_v2/components/notification_severed_relationships.tsx new file mode 100644 index 00000000000000..9c2b0b3edbea9e --- /dev/null +++ b/app/javascript/flavours/glitch/features/notifications_v2/components/notification_severed_relationships.tsx @@ -0,0 +1,15 @@ +import { RelationshipsSeveranceEvent } from 'flavours/glitch/features/notifications/components/relationships_severance_event'; +import type { NotificationGroupSeveredRelationships } from 'flavours/glitch/models/notification_group'; + +export const NotificationSeveredRelationships: React.FC<{ + notification: NotificationGroupSeveredRelationships; + unread: boolean; +}> = ({ notification: { event }, unread }) => ( + +); diff --git a/app/javascript/flavours/glitch/features/notifications_v2/components/notification_status.tsx b/app/javascript/flavours/glitch/features/notifications_v2/components/notification_status.tsx new file mode 100644 index 00000000000000..2d9944eb18f28f --- /dev/null +++ b/app/javascript/flavours/glitch/features/notifications_v2/components/notification_status.tsx @@ -0,0 +1,31 @@ +import { FormattedMessage } from 'react-intl'; + +import NotificationsActiveIcon from '@/material-icons/400-24px/notifications_active-fill.svg?react'; +import type { NotificationGroupStatus } from 'flavours/glitch/models/notification_group'; + +import type { LabelRenderer } from './notification_group_with_status'; +import { NotificationWithStatus } from './notification_with_status'; + +const labelRenderer: LabelRenderer = (values) => ( + +); + +export const NotificationStatus: React.FC<{ + notification: NotificationGroupStatus; + unread: boolean; +}> = ({ notification, unread }) => ( + +); diff --git a/app/javascript/flavours/glitch/features/notifications_v2/components/notification_update.tsx b/app/javascript/flavours/glitch/features/notifications_v2/components/notification_update.tsx new file mode 100644 index 00000000000000..6b9452a3ebba3a --- /dev/null +++ b/app/javascript/flavours/glitch/features/notifications_v2/components/notification_update.tsx @@ -0,0 +1,31 @@ +import { FormattedMessage } from 'react-intl'; + +import EditIcon from '@/material-icons/400-24px/edit.svg?react'; +import type { NotificationGroupUpdate } from 'flavours/glitch/models/notification_group'; + +import type { LabelRenderer } from './notification_group_with_status'; +import { NotificationWithStatus } from './notification_with_status'; + +const labelRenderer: LabelRenderer = (values) => ( + +); + +export const NotificationUpdate: React.FC<{ + notification: NotificationGroupUpdate; + unread: boolean; +}> = ({ notification, unread }) => ( + +); diff --git a/app/javascript/flavours/glitch/features/notifications_v2/components/notification_with_status.tsx b/app/javascript/flavours/glitch/features/notifications_v2/components/notification_with_status.tsx new file mode 100644 index 00000000000000..23e56ce3a50c82 --- /dev/null +++ b/app/javascript/flavours/glitch/features/notifications_v2/components/notification_with_status.tsx @@ -0,0 +1,115 @@ +import { useMemo } from 'react'; + +import classNames from 'classnames'; + +import { HotKeys } from 'react-hotkeys'; + +import { replyComposeById } from 'flavours/glitch/actions/compose'; +import { + toggleReblog, + toggleFavourite, +} from 'flavours/glitch/actions/interactions'; +import { + navigateToStatus, + toggleStatusSpoilers, +} from 'flavours/glitch/actions/statuses'; +import type { IconProp } from 'flavours/glitch/components/icon'; +import { Icon } from 'flavours/glitch/components/icon'; +import Status from 'flavours/glitch/containers/status_container'; +import { useAppSelector, useAppDispatch } from 'flavours/glitch/store'; + +import { NamesList } from './names_list'; +import type { LabelRenderer } from './notification_group_with_status'; + +export const NotificationWithStatus: React.FC<{ + type: string; + icon: IconProp; + iconId: string; + accountIds: string[]; + statusId: string; + count: number; + labelRenderer: LabelRenderer; + unread: boolean; +}> = ({ + icon, + iconId, + accountIds, + statusId, + count, + labelRenderer, + type, + unread, +}) => { + const dispatch = useAppDispatch(); + + const label = useMemo( + () => + labelRenderer({ + name: , + }), + [labelRenderer, accountIds, count], + ); + + const isPrivateMention = useAppSelector( + (state) => state.statuses.getIn([statusId, 'visibility']) === 'direct', + ); + + const handlers = useMemo( + () => ({ + open: () => { + dispatch(navigateToStatus(statusId)); + }, + + reply: () => { + dispatch(replyComposeById(statusId)); + }, + + boost: () => { + dispatch(toggleReblog(statusId)); + }, + + favourite: () => { + dispatch(toggleFavourite(statusId)); + }, + + toggleHidden: () => { + // TODO: glitch-soc is different and needs different handling of CWs + dispatch(toggleStatusSpoilers(statusId)); + }, + }), + [dispatch, statusId], + ); + + return ( + +
+
+
+ +
+ {label} +
+ + is not yet typed + id={statusId} + contextType='notifications' + withDismiss + skipPrepend + avatarSize={40} + unfocusable + /> +
+
+ ); +}; diff --git a/app/javascript/flavours/glitch/features/notifications_v2/filter_bar.tsx b/app/javascript/flavours/glitch/features/notifications_v2/filter_bar.tsx new file mode 100644 index 00000000000000..1299796662b1d6 --- /dev/null +++ b/app/javascript/flavours/glitch/features/notifications_v2/filter_bar.tsx @@ -0,0 +1,145 @@ +import type { PropsWithChildren } from 'react'; +import { useCallback } from 'react'; + +import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; + +import HomeIcon from '@/material-icons/400-24px/home-fill.svg?react'; +import InsertChartIcon from '@/material-icons/400-24px/insert_chart.svg?react'; +import PersonAddIcon from '@/material-icons/400-24px/person_add.svg?react'; +import RepeatIcon from '@/material-icons/400-24px/repeat.svg?react'; +import ReplyAllIcon from '@/material-icons/400-24px/reply_all.svg?react'; +import StarIcon from '@/material-icons/400-24px/star.svg?react'; +import { setNotificationsFilter } from 'flavours/glitch/actions/notification_groups'; +import { Icon } from 'flavours/glitch/components/icon'; +import { + selectSettingsNotificationsQuickFilterActive, + selectSettingsNotificationsQuickFilterAdvanced, +} from 'flavours/glitch/selectors/settings'; +import { useAppDispatch, useAppSelector } from 'flavours/glitch/store'; + +const tooltips = defineMessages({ + mentions: { id: 'notifications.filter.mentions', defaultMessage: 'Mentions' }, + favourites: { + id: 'notifications.filter.favourites', + defaultMessage: 'Favorites', + }, + boosts: { id: 'notifications.filter.boosts', defaultMessage: 'Boosts' }, + polls: { id: 'notifications.filter.polls', defaultMessage: 'Poll results' }, + follows: { id: 'notifications.filter.follows', defaultMessage: 'Follows' }, + statuses: { + id: 'notifications.filter.statuses', + defaultMessage: 'Updates from people you follow', + }, +}); + +const BarButton: React.FC< + PropsWithChildren<{ + selectedFilter: string; + type: string; + title?: string; + }> +> = ({ selectedFilter, type, title, children }) => { + const dispatch = useAppDispatch(); + + const onClick = useCallback(() => { + void dispatch(setNotificationsFilter({ filterType: type })); + }, [dispatch, type]); + + return ( + + ); +}; + +export const FilterBar: React.FC = () => { + const intl = useIntl(); + + const selectedFilter = useAppSelector( + selectSettingsNotificationsQuickFilterActive, + ); + const advancedMode = useAppSelector( + selectSettingsNotificationsQuickFilterAdvanced, + ); + + if (advancedMode) + return ( +
+ + + + + + + + + + + + + + + + + + + + + +
+ ); + else + return ( +
+ + + + + + +
+ ); +}; diff --git a/app/javascript/flavours/glitch/features/notifications_v2/index.tsx b/app/javascript/flavours/glitch/features/notifications_v2/index.tsx new file mode 100644 index 00000000000000..94051713751779 --- /dev/null +++ b/app/javascript/flavours/glitch/features/notifications_v2/index.tsx @@ -0,0 +1,354 @@ +import { useCallback, useEffect, useMemo, useRef } from 'react'; + +import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; + +import { Helmet } from 'react-helmet'; + +import { createSelector } from '@reduxjs/toolkit'; + +import { useDebouncedCallback } from 'use-debounce'; + +import DoneAllIcon from '@/material-icons/400-24px/done_all.svg?react'; +import NotificationsIcon from '@/material-icons/400-24px/notifications-fill.svg?react'; +import { + fetchNotificationsGap, + updateScrollPosition, + loadPending, + markNotificationsAsRead, + mountNotifications, + unmountNotifications, +} from 'flavours/glitch/actions/notification_groups'; +import { compareId } from 'flavours/glitch/compare_id'; +import { Icon } from 'flavours/glitch/components/icon'; +import { NotSignedInIndicator } from 'flavours/glitch/components/not_signed_in_indicator'; +import { useIdentity } from 'flavours/glitch/identity_context'; +import type { NotificationGap } from 'flavours/glitch/reducers/notification_groups'; +import { + selectUnreadNotificationGroupsCount, + selectPendingNotificationGroupsCount, +} from 'flavours/glitch/selectors/notifications'; +import { + selectNeedsNotificationPermission, + selectSettingsNotificationsExcludedTypes, + selectSettingsNotificationsQuickFilterActive, + selectSettingsNotificationsQuickFilterShow, + selectSettingsNotificationsShowUnread, +} from 'flavours/glitch/selectors/settings'; +import { useAppDispatch, useAppSelector } from 'flavours/glitch/store'; +import type { RootState } from 'flavours/glitch/store'; + +import { addColumn, removeColumn, moveColumn } from '../../actions/columns'; +import { submitMarkers } from '../../actions/markers'; +import Column from '../../components/column'; +import { ColumnHeader } from '../../components/column_header'; +import { LoadGap } from '../../components/load_gap'; +import ScrollableList from '../../components/scrollable_list'; +import { FilteredNotificationsBanner } from '../notifications/components/filtered_notifications_banner'; +import NotificationsPermissionBanner from '../notifications/components/notifications_permission_banner'; +import ColumnSettingsContainer from '../notifications/containers/column_settings_container'; + +import { NotificationGroup } from './components/notification_group'; +import { FilterBar } from './filter_bar'; + +const messages = defineMessages({ + title: { id: 'column.notifications', defaultMessage: 'Notifications' }, + markAsRead: { + id: 'notifications.mark_as_read', + defaultMessage: 'Mark every notification as read', + }, +}); + +const getNotifications = createSelector( + [ + selectSettingsNotificationsQuickFilterShow, + selectSettingsNotificationsQuickFilterActive, + selectSettingsNotificationsExcludedTypes, + (state: RootState) => state.notificationGroups.groups, + ], + (showFilterBar, allowedType, excludedTypes, notifications) => { + if (!showFilterBar || allowedType === 'all') { + // used if user changed the notification settings after loading the notifications from the server + // otherwise a list of notifications will come pre-filtered from the backend + // we need to turn it off for FilterBar in order not to block ourselves from seeing a specific category + return notifications.filter( + (item) => item.type === 'gap' || !excludedTypes.includes(item.type), + ); + } + return notifications.filter( + (item) => item.type === 'gap' || allowedType === item.type, + ); + }, +); + +export const Notifications: React.FC<{ + columnId?: string; + multiColumn?: boolean; +}> = ({ columnId, multiColumn }) => { + const intl = useIntl(); + const notifications = useAppSelector(getNotifications); + const dispatch = useAppDispatch(); + const isLoading = useAppSelector((s) => s.notificationGroups.isLoading); + const hasMore = notifications.at(-1)?.type === 'gap'; + + const lastReadId = useAppSelector((s) => + selectSettingsNotificationsShowUnread(s) + ? s.notificationGroups.lastReadId + : '0', + ); + + const numPending = useAppSelector(selectPendingNotificationGroupsCount); + + const unreadNotificationsCount = useAppSelector( + selectUnreadNotificationGroupsCount, + ); + + const isUnread = unreadNotificationsCount > 0; + + const canMarkAsRead = + useAppSelector(selectSettingsNotificationsShowUnread) && + unreadNotificationsCount > 0; + + const needsNotificationPermission = useAppSelector( + selectNeedsNotificationPermission, + ); + + const columnRef = useRef(null); + + const selectChild = useCallback((index: number, alignTop: boolean) => { + const container = columnRef.current?.node as HTMLElement | undefined; + + if (!container) return; + + const element = container.querySelector( + `article:nth-of-type(${index + 1}) .focusable`, + ); + + if (element) { + if (alignTop && container.scrollTop > element.offsetTop) { + element.scrollIntoView(true); + } else if ( + !alignTop && + container.scrollTop + container.clientHeight < + element.offsetTop + element.offsetHeight + ) { + element.scrollIntoView(false); + } + element.focus(); + } + }, []); + + // Keep track of mounted components for unread notification handling + useEffect(() => { + dispatch(mountNotifications()); + + return () => { + dispatch(unmountNotifications()); + dispatch(updateScrollPosition({ top: false })); + }; + }, [dispatch]); + + const handleLoadGap = useCallback( + (gap: NotificationGap) => { + void dispatch(fetchNotificationsGap({ gap })); + }, + [dispatch], + ); + + const handleLoadOlder = useDebouncedCallback( + () => { + const gap = notifications.at(-1); + if (gap?.type === 'gap') void dispatch(fetchNotificationsGap({ gap })); + }, + 300, + { leading: true }, + ); + + const handleLoadPending = useCallback(() => { + dispatch(loadPending()); + }, [dispatch]); + + const handleScrollToTop = useDebouncedCallback(() => { + dispatch(updateScrollPosition({ top: true })); + }, 100); + + const handleScroll = useDebouncedCallback(() => { + dispatch(updateScrollPosition({ top: false })); + }, 100); + + useEffect(() => { + return () => { + handleLoadOlder.cancel(); + handleScrollToTop.cancel(); + handleScroll.cancel(); + }; + }, [handleLoadOlder, handleScrollToTop, handleScroll]); + + const handlePin = useCallback(() => { + if (columnId) { + dispatch(removeColumn(columnId)); + } else { + dispatch(addColumn('NOTIFICATIONS', {})); + } + }, [columnId, dispatch]); + + const handleMove = useCallback( + (dir: unknown) => { + dispatch(moveColumn(columnId, dir)); + }, + [dispatch, columnId], + ); + + const handleHeaderClick = useCallback(() => { + columnRef.current?.scrollTop(); + }, []); + + const handleMoveUp = useCallback( + (id: string) => { + const elementIndex = + notifications.findIndex( + (item) => item.type !== 'gap' && item.group_key === id, + ) - 1; + selectChild(elementIndex, true); + }, + [notifications, selectChild], + ); + + const handleMoveDown = useCallback( + (id: string) => { + const elementIndex = + notifications.findIndex( + (item) => item.type !== 'gap' && item.group_key === id, + ) + 1; + selectChild(elementIndex, false); + }, + [notifications, selectChild], + ); + + const handleMarkAsRead = useCallback(() => { + dispatch(markNotificationsAsRead()); + void dispatch(submitMarkers({ immediate: true })); + }, [dispatch]); + + const pinned = !!columnId; + const emptyMessage = ( + + ); + + const { signedIn } = useIdentity(); + + const filterBar = signedIn ? : null; + + const scrollableContent = useMemo(() => { + if (notifications.length === 0 && !hasMore) return null; + + return notifications.map((item) => + item.type === 'gap' ? ( + + ) : ( + 0 + } + /> + ), + ); + }, [ + notifications, + isLoading, + hasMore, + lastReadId, + handleLoadGap, + handleMoveUp, + handleMoveDown, + ]); + + const prepend = ( + <> + {needsNotificationPermission && } + + + ); + + const scrollContainer = signedIn ? ( + + {scrollableContent} + + ) : ( + + ); + + const extraButton = canMarkAsRead ? ( + + ) : null; + + return ( + + + + + + {filterBar} + + {scrollContainer} + + + {intl.formatMessage(messages.title)} + + + + ); +}; + +// eslint-disable-next-line import/no-default-export +export default Notifications; diff --git a/app/javascript/flavours/glitch/features/notifications_wrapper.jsx b/app/javascript/flavours/glitch/features/notifications_wrapper.jsx new file mode 100644 index 00000000000000..15ab3367cc1bf8 --- /dev/null +++ b/app/javascript/flavours/glitch/features/notifications_wrapper.jsx @@ -0,0 +1,13 @@ +import Notifications from 'flavours/glitch/features/notifications'; +import Notifications_v2 from 'flavours/glitch/features/notifications_v2'; +import { useAppSelector } from 'flavours/glitch/store'; + +export const NotificationsWrapper = (props) => { + const optedInGroupedNotifications = useAppSelector((state) => state.getIn(['settings', 'notifications', 'groupingBeta'], false)); + + return ( + optedInGroupedNotifications ? : + ); +}; + +export default NotificationsWrapper; \ No newline at end of file diff --git a/app/javascript/flavours/glitch/features/onboarding/index.jsx b/app/javascript/flavours/glitch/features/onboarding/index.jsx index 187ee3b7703610..7922b616775090 100644 --- a/app/javascript/flavours/glitch/features/onboarding/index.jsx +++ b/app/javascript/flavours/glitch/features/onboarding/index.jsx @@ -3,7 +3,7 @@ import { useCallback } from 'react'; import { FormattedMessage, useIntl, defineMessages } from 'react-intl'; import { Helmet } from 'react-helmet'; -import { Link, Switch, Route, useHistory } from 'react-router-dom'; +import { Link, Switch, Route } from 'react-router-dom'; import { useDispatch } from 'react-redux'; @@ -34,11 +34,10 @@ const Onboarding = () => { const account = useAppSelector(state => state.getIn(['accounts', me])); const dispatch = useDispatch(); const intl = useIntl(); - const history = useHistory(); const handleComposeClick = useCallback(() => { - dispatch(focusCompose(history, intl.formatMessage(messages.template))); - }, [dispatch, intl, history]); + dispatch(focusCompose(intl.formatMessage(messages.template))); + }, [dispatch, intl]); return ( diff --git a/app/javascript/flavours/glitch/features/picture_in_picture/components/footer.jsx b/app/javascript/flavours/glitch/features/picture_in_picture/components/footer.jsx index 3bf4f3b8577887..3e26d8406915c9 100644 --- a/app/javascript/flavours/glitch/features/picture_in_picture/components/footer.jsx +++ b/app/javascript/flavours/glitch/features/picture_in_picture/components/footer.jsx @@ -14,12 +14,12 @@ import RepeatIcon from '@/material-icons/400-24px/repeat.svg?react'; import ReplyIcon from '@/material-icons/400-24px/reply.svg?react'; import ReplyAllIcon from '@/material-icons/400-24px/reply_all.svg?react'; import StarIcon from '@/material-icons/400-24px/star.svg?react'; -import { initBoostModal } from 'flavours/glitch/actions/boosts'; import { replyCompose } from 'flavours/glitch/actions/compose'; -import { reblog, favourite, unreblog, unfavourite } from 'flavours/glitch/actions/interactions'; +import { toggleReblog, toggleFavourite } from 'flavours/glitch/actions/interactions'; import { openModal } from 'flavours/glitch/actions/modal'; import { IconButton } from 'flavours/glitch/components/icon_button'; -import { me, boostModal } from 'flavours/glitch/initial_state'; +import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context'; +import { me } from 'flavours/glitch/initial_state'; import { makeGetStatus } from 'flavours/glitch/selectors'; import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router'; @@ -49,12 +49,8 @@ const makeMapStateToProps = () => { }; class Footer extends ImmutablePureComponent { - - static contextTypes = { - identity: PropTypes.object, - }; - static propTypes = { + identity: identityContextPropShape, statusId: PropTypes.string.isRequired, status: ImmutablePropTypes.map.isRequired, intl: PropTypes.object.isRequired, @@ -67,18 +63,18 @@ class Footer extends ImmutablePureComponent { }; _performReply = () => { - const { dispatch, status, onClose, history } = this.props; + const { dispatch, status, onClose } = this.props; if (onClose) { onClose(true); } - dispatch(replyCompose(status, history)); + dispatch(replyCompose(status)); }; handleReplyClick = () => { const { dispatch, askReplyConfirmation, status, intl } = this.props; - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; if (signedIn) { if (askReplyConfirmation) { @@ -105,16 +101,12 @@ class Footer extends ImmutablePureComponent { } }; - handleFavouriteClick = () => { + handleFavouriteClick = e => { const { dispatch, status } = this.props; - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; if (signedIn) { - if (status.get('favourited')) { - dispatch(unfavourite(status)); - } else { - dispatch(favourite(status)); - } + dispatch(toggleFavourite(status.get('id'), e && e.shiftKey)); } else { dispatch(openModal({ modalType: 'INTERACTION', @@ -127,23 +119,12 @@ class Footer extends ImmutablePureComponent { } }; - _performReblog = (status, privacy) => { - const { dispatch } = this.props; - dispatch(reblog(status, privacy)); - }; - handleReblogClick = e => { const { dispatch, status } = this.props; - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; if (signedIn) { - if (status.get('reblogged')) { - dispatch(unreblog(status)); - } else if ((e && e.shiftKey) || !boostModal) { - this._performReblog(status); - } else { - dispatch(initBoostModal({ status, onReblog: this._performReblog })); - } + dispatch(toggleReblog(status.get('id'), e && e.shiftKey)); } else { dispatch(openModal({ modalType: 'INTERACTION', @@ -237,4 +218,4 @@ class Footer extends ImmutablePureComponent { } -export default withRouter(connect(makeMapStateToProps)(injectIntl(Footer))); +export default connect(makeMapStateToProps)(withIdentity(withRouter(injectIntl(Footer)))); diff --git a/app/javascript/flavours/glitch/features/picture_in_picture/components/header.jsx b/app/javascript/flavours/glitch/features/picture_in_picture/components/header.jsx deleted file mode 100644 index 5996ab240d3bc7..00000000000000 --- a/app/javascript/flavours/glitch/features/picture_in_picture/components/header.jsx +++ /dev/null @@ -1,51 +0,0 @@ -import PropTypes from 'prop-types'; - -import { defineMessages, injectIntl } from 'react-intl'; - -import { Link } from 'react-router-dom'; - -import ImmutablePropTypes from 'react-immutable-proptypes'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import { connect } from 'react-redux'; - -import CloseIcon from '@/material-icons/400-24px/close.svg?react'; -import { Avatar } from 'flavours/glitch/components/avatar'; -import { DisplayName } from 'flavours/glitch/components/display_name'; -import { IconButton } from 'flavours/glitch/components/icon_button'; - -const messages = defineMessages({ - close: { id: 'lightbox.close', defaultMessage: 'Close' }, -}); - -const mapStateToProps = (state, { accountId }) => ({ - account: state.getIn(['accounts', accountId]), -}); - -class Header extends ImmutablePureComponent { - - static propTypes = { - accountId: PropTypes.string.isRequired, - statusId: PropTypes.string.isRequired, - account: ImmutablePropTypes.record.isRequired, - onClose: PropTypes.func.isRequired, - intl: PropTypes.object.isRequired, - }; - - render () { - const { account, statusId, onClose, intl } = this.props; - - return ( -
- - - - - - -
- ); - } - -} - -export default connect(mapStateToProps)(injectIntl(Header)); diff --git a/app/javascript/flavours/glitch/features/picture_in_picture/components/header.tsx b/app/javascript/flavours/glitch/features/picture_in_picture/components/header.tsx new file mode 100644 index 00000000000000..3bbd8294293f72 --- /dev/null +++ b/app/javascript/flavours/glitch/features/picture_in_picture/components/header.tsx @@ -0,0 +1,46 @@ +import { defineMessages, useIntl } from 'react-intl'; + +import { Link } from 'react-router-dom'; + +import CloseIcon from '@/material-icons/400-24px/close.svg?react'; +import { Avatar } from 'flavours/glitch/components/avatar'; +import { DisplayName } from 'flavours/glitch/components/display_name'; +import { IconButton } from 'flavours/glitch/components/icon_button'; +import { useAppSelector } from 'flavours/glitch/store'; + +const messages = defineMessages({ + close: { id: 'lightbox.close', defaultMessage: 'Close' }, +}); + +interface Props { + accountId: string; + statusId: string; + onClose: () => void; +} + +export const Header: React.FC = ({ accountId, statusId, onClose }) => { + const account = useAppSelector((state) => state.accounts.get(accountId)); + + const intl = useIntl(); + + if (!account) return null; + + return ( +
+ + + + + + +
+ ); +}; diff --git a/app/javascript/flavours/glitch/features/picture_in_picture/index.jsx b/app/javascript/flavours/glitch/features/picture_in_picture/index.jsx deleted file mode 100644 index ed229384c4a04b..00000000000000 --- a/app/javascript/flavours/glitch/features/picture_in_picture/index.jsx +++ /dev/null @@ -1,93 +0,0 @@ -import PropTypes from 'prop-types'; -import { Component } from 'react'; - -import classNames from 'classnames'; - -import { connect } from 'react-redux'; - -import { removePictureInPicture } from 'flavours/glitch/actions/picture_in_picture'; -import Audio from 'flavours/glitch/features/audio'; -import Video from 'flavours/glitch/features/video'; - -import Footer from './components/footer'; -import Header from './components/header'; - -const mapStateToProps = state => ({ - ...state.get('picture_in_picture'), - left: state.getIn(['local_settings', 'media', 'pop_in_position']) === 'left', -}); - -class PictureInPicture extends Component { - - static propTypes = { - statusId: PropTypes.string, - accountId: PropTypes.string, - type: PropTypes.string, - src: PropTypes.string, - muted: PropTypes.bool, - volume: PropTypes.number, - currentTime: PropTypes.number, - poster: PropTypes.string, - backgroundColor: PropTypes.string, - foregroundColor: PropTypes.string, - accentColor: PropTypes.string, - dispatch: PropTypes.func.isRequired, - left: PropTypes.bool, - }; - - handleClose = () => { - const { dispatch } = this.props; - dispatch(removePictureInPicture()); - }; - - render () { - const { type, src, currentTime, accountId, statusId, left } = this.props; - - if (!currentTime) { - return null; - } - - let player; - - if (type === 'video') { - player = ( -
+
+

+ +

+ +
+ +
+
+

@@ -116,6 +125,16 @@ export default class ColumnSettings extends PureComponent {

+
+

+ +

+ +
+ +
+
+

@@ -204,7 +223,7 @@ export default class ColumnSettings extends PureComponent {
- {((this.context.identity.permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS) && ( + {((this.props.identity.permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS) && (

@@ -217,7 +236,7 @@ export default class ColumnSettings extends PureComponent {
)} - {((this.context.identity.permissions & PERMISSION_MANAGE_REPORTS) === PERMISSION_MANAGE_REPORTS) && ( + {((this.props.identity.permissions & PERMISSION_MANAGE_REPORTS) === PERMISSION_MANAGE_REPORTS) && (

@@ -234,3 +253,5 @@ export default class ColumnSettings extends PureComponent { } } + +export default withIdentity(ColumnSettings); diff --git a/app/javascript/mastodon/features/notifications/components/filtered_notifications_banner.jsx b/app/javascript/mastodon/features/notifications/components/filtered_notifications_banner.jsx deleted file mode 100644 index adf58afbf0951b..00000000000000 --- a/app/javascript/mastodon/features/notifications/components/filtered_notifications_banner.jsx +++ /dev/null @@ -1,48 +0,0 @@ -import { useEffect } from 'react'; - -import { FormattedMessage } from 'react-intl'; - -import { Link } from 'react-router-dom'; - -import { useDispatch, useSelector } from 'react-redux'; - -import InventoryIcon from '@/material-icons/400-24px/inventory_2.svg?react'; -import { fetchNotificationPolicy } from 'mastodon/actions/notifications'; -import { Icon } from 'mastodon/components/icon'; -import { toCappedNumber } from 'mastodon/utils/numbers'; - -export const FilteredNotificationsBanner = () => { - const dispatch = useDispatch(); - const policy = useSelector(state => state.get('notificationPolicy')); - - useEffect(() => { - dispatch(fetchNotificationPolicy()); - - const interval = setInterval(() => { - dispatch(fetchNotificationPolicy()); - }, 120000); - - return () => { - clearInterval(interval); - }; - }, [dispatch]); - - if (policy === null || policy.getIn(['summary', 'pending_notifications_count']) * 1 === 0) { - return null; - } - - return ( - - - -
- - -
- -
- {toCappedNumber(policy.getIn(['summary', 'pending_notifications_count']))} -
- - ); -}; diff --git a/app/javascript/mastodon/features/notifications/components/filtered_notifications_banner.tsx b/app/javascript/mastodon/features/notifications/components/filtered_notifications_banner.tsx new file mode 100644 index 00000000000000..be1ea2c556e1d2 --- /dev/null +++ b/app/javascript/mastodon/features/notifications/components/filtered_notifications_banner.tsx @@ -0,0 +1,70 @@ +import { useEffect } from 'react'; + +import { FormattedMessage } from 'react-intl'; + +import { Link } from 'react-router-dom'; + +import InventoryIcon from '@/material-icons/400-24px/inventory_2.svg?react'; +import { fetchNotificationPolicy } from 'mastodon/actions/notification_policies'; +import { Icon } from 'mastodon/components/icon'; +import { useAppSelector, useAppDispatch } from 'mastodon/store'; +import { toCappedNumber } from 'mastodon/utils/numbers'; + +export const FilteredNotificationsBanner: React.FC = () => { + const dispatch = useAppDispatch(); + const policy = useAppSelector((state) => state.notificationPolicy); + + useEffect(() => { + void dispatch(fetchNotificationPolicy()); + + const interval = setInterval(() => { + void dispatch(fetchNotificationPolicy()); + }, 120000); + + return () => { + clearInterval(interval); + }; + }, [dispatch]); + + if (policy === null || policy.summary.pending_notifications_count === 0) { + return null; + } + + return ( + +
+ +
+ +
+ + + + + + +
+ +
+
+ {toCappedNumber(policy.summary.pending_notifications_count)} +
+ +
+ + ); +}; diff --git a/app/javascript/mastodon/features/notifications/components/moderation_warning.tsx b/app/javascript/mastodon/features/notifications/components/moderation_warning.tsx new file mode 100644 index 00000000000000..827ec3b378bf39 --- /dev/null +++ b/app/javascript/mastodon/features/notifications/components/moderation_warning.tsx @@ -0,0 +1,89 @@ +import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; + +import classNames from 'classnames'; + +import GavelIcon from '@/material-icons/400-24px/gavel.svg?react'; +import { Icon } from 'mastodon/components/icon'; +import type { AccountWarningAction } from 'mastodon/models/notification_group'; + +// This needs to be kept in sync with app/models/account_warning.rb +const messages = defineMessages({ + none: { + id: 'notification.moderation_warning.action_none', + defaultMessage: 'Your account has received a moderation warning.', + }, + disable: { + id: 'notification.moderation_warning.action_disable', + defaultMessage: 'Your account has been disabled.', + }, + mark_statuses_as_sensitive: { + id: 'notification.moderation_warning.action_mark_statuses_as_sensitive', + defaultMessage: 'Some of your posts have been marked as sensitive.', + }, + delete_statuses: { + id: 'notification.moderation_warning.action_delete_statuses', + defaultMessage: 'Some of your posts have been removed.', + }, + sensitive: { + id: 'notification.moderation_warning.action_sensitive', + defaultMessage: 'Your posts will be marked as sensitive from now on.', + }, + silence: { + id: 'notification.moderation_warning.action_silence', + defaultMessage: 'Your account has been limited.', + }, + suspend: { + id: 'notification.moderation_warning.action_suspend', + defaultMessage: 'Your account has been suspended.', + }, +}); + +interface Props { + action: AccountWarningAction; + id: string; + hidden?: boolean; + unread?: boolean; +} + +export const ModerationWarning: React.FC = ({ + action, + id, + hidden, + unread, +}) => { + const intl = useIntl(); + + if (hidden) { + return null; + } + + return ( +
+
+ +
+ +
+

{intl.formatMessage(messages[action])}

+ + + +
+
+ ); +}; diff --git a/app/javascript/mastodon/features/notifications/components/notification.jsx b/app/javascript/mastodon/features/notifications/components/notification.jsx index d7101f8384f61e..f1eada13595f82 100644 --- a/app/javascript/mastodon/features/notifications/components/notification.jsx +++ b/app/javascript/mastodon/features/notifications/components/notification.jsx @@ -26,18 +26,22 @@ import { WithRouterPropTypes } from 'mastodon/utils/react_router'; import FollowRequestContainer from '../containers/follow_request_container'; +import { ModerationWarning } from './moderation_warning'; +import { RelationshipsSeveranceEvent } from './relationships_severance_event'; import Report from './report'; const messages = defineMessages({ favourite: { id: 'notification.favourite', defaultMessage: '{name} favorited your status' }, follow: { id: 'notification.follow', defaultMessage: '{name} followed you' }, ownPoll: { id: 'notification.own_poll', defaultMessage: 'Your poll has ended' }, - poll: { id: 'notification.poll', defaultMessage: 'A poll you have voted in has ended' }, + poll: { id: 'notification.poll', defaultMessage: 'A poll you voted in has ended' }, reblog: { id: 'notification.reblog', defaultMessage: '{name} boosted your status' }, status: { id: 'notification.status', defaultMessage: '{name} just posted' }, update: { id: 'notification.update', defaultMessage: '{name} edited a post' }, adminSignUp: { id: 'notification.admin.sign_up', defaultMessage: '{name} signed up' }, adminReport: { id: 'notification.admin.report', defaultMessage: '{name} reported {target}' }, + relationshipsSevered: { id: 'notification.relationships_severance_event', defaultMessage: 'Lost connections with {name}' }, + moderationWarning: { id: 'notification.moderation_warning', defaultMessage: 'You have received a moderation warning' }, }); const notificationForScreenReader = (intl, message, timestamp) => { @@ -97,7 +101,7 @@ class Notification extends ImmutablePureComponent { e.preventDefault(); const { notification, onMention } = this.props; - onMention(notification.get('account'), this.props.history); + onMention(notification.get('account')); }; handleHotkeyFavourite = () => { @@ -336,7 +340,7 @@ class Notification extends ImmutablePureComponent { {ownPoll ? ( ) : ( - + )} @@ -358,6 +362,50 @@ class Notification extends ImmutablePureComponent { ); } + renderRelationshipsSevered (notification) { + const { intl, unread, hidden } = this.props; + const event = notification.get('event'); + + if (!event) { + return null; + } + + return ( + +
+
+
+ ); + } + + renderModerationWarning (notification) { + const { intl, unread, hidden } = this.props; + const warning = notification.get('moderation_warning'); + + if (!warning) { + return null; + } + + return ( + +
+
+
+ ); + } + renderAdminSignUp (notification, account, link) { const { intl, unread } = this.props; @@ -387,7 +435,7 @@ class Notification extends ImmutablePureComponent { const targetAccount = report.get('target_account'); const targetDisplayNameHtml = { __html: targetAccount.get('display_name_html') }; - const targetLink = ; + const targetLink = ; return ( @@ -410,7 +458,7 @@ class Notification extends ImmutablePureComponent { const { notification } = this.props; const account = notification.get('account'); const displayNameHtml = { __html: account.get('display_name_html') }; - const link = ; + const link = ; switch(notification.get('type')) { case 'follow': @@ -429,6 +477,10 @@ class Notification extends ImmutablePureComponent { return this.renderUpdate(notification, link); case 'poll': return this.renderPoll(notification, account); + case 'severed_relationships': + return this.renderRelationshipsSevered(notification); + case 'moderation_warning': + return this.renderModerationWarning(notification); case 'admin.sign_up': return this.renderAdminSignUp(notification, account, link); case 'admin.report': diff --git a/app/javascript/mastodon/features/notifications/components/notification_request.jsx b/app/javascript/mastodon/features/notifications/components/notification_request.jsx index e24124ca6a2f6f..3a77ef4e2e14ad 100644 --- a/app/javascript/mastodon/features/notifications/components/notification_request.jsx +++ b/app/javascript/mastodon/features/notifications/components/notification_request.jsx @@ -7,8 +7,8 @@ import { Link } from 'react-router-dom'; import { useSelector, useDispatch } from 'react-redux'; +import DeleteIcon from '@/material-icons/400-24px/delete.svg?react'; import DoneIcon from '@/material-icons/400-24px/done.svg?react'; -import VolumeOffIcon from '@/material-icons/400-24px/volume_off.svg?react'; import { acceptNotificationRequest, dismissNotificationRequest } from 'mastodon/actions/notifications'; import { Avatar } from 'mastodon/components/avatar'; import { IconButton } from 'mastodon/components/icon_button'; @@ -51,7 +51,7 @@ export const NotificationRequest = ({ id, accountId, notificationsCount }) => {
- +
diff --git a/app/javascript/mastodon/features/notifications/components/relationships_severance_event.jsx b/app/javascript/mastodon/features/notifications/components/relationships_severance_event.jsx new file mode 100644 index 00000000000000..3075aff31bad1b --- /dev/null +++ b/app/javascript/mastodon/features/notifications/components/relationships_severance_event.jsx @@ -0,0 +1,48 @@ +import PropTypes from 'prop-types'; + +import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; + +import classNames from 'classnames'; + +import HeartBrokenIcon from '@/material-icons/400-24px/heart_broken-fill.svg?react'; +import { Icon } from 'mastodon/components/icon'; +import { domain } from 'mastodon/initial_state'; + +// This needs to be kept in sync with app/models/relationships_severance_event.rb +const messages = defineMessages({ + account_suspension: { id: 'notification.relationships_severance_event.account_suspension', defaultMessage: 'An admin from {from} has suspended {target}, which means you can no longer receive updates from them or interact with them.' }, + domain_block: { id: 'notification.relationships_severance_event.domain_block', defaultMessage: 'An admin from {from} has blocked {target}, including {followersCount} of your followers and {followingCount, plural, one {# account} other {# accounts}} you follow.' }, + user_domain_block: { id: 'notification.relationships_severance_event.user_domain_block', defaultMessage: 'You have blocked {target}, removing {followersCount} of your followers and {followingCount, plural, one {# account} other {# accounts}} you follow.' }, +}); + +export const RelationshipsSeveranceEvent = ({ type, target, followingCount, followersCount, hidden, unread }) => { + const intl = useIntl(); + + if (hidden) { + return null; + } + + return ( +
+
+ +
+

{intl.formatMessage(messages[type], { from: {domain}, target: {target}, followingCount, followersCount })}

+ +
+
+ ); +}; + +RelationshipsSeveranceEvent.propTypes = { + type: PropTypes.oneOf([ + 'account_suspension', + 'domain_block', + 'user_domain_block', + ]).isRequired, + target: PropTypes.string.isRequired, + followersCount: PropTypes.number.isRequired, + followingCount: PropTypes.number.isRequired, + hidden: PropTypes.bool, + unread: PropTypes.bool, +}; diff --git a/app/javascript/mastodon/features/notifications/containers/column_settings_container.js b/app/javascript/mastodon/features/notifications/containers/column_settings_container.js index de266160f8511c..2434c3982d582b 100644 --- a/app/javascript/mastodon/features/notifications/containers/column_settings_container.js +++ b/app/javascript/mastodon/features/notifications/containers/column_settings_container.js @@ -2,9 +2,13 @@ import { defineMessages, injectIntl } from 'react-intl'; import { connect } from 'react-redux'; +import { initializeNotifications } from 'mastodon/actions/notifications_migration'; + import { showAlert } from '../../../actions/alerts'; import { openModal } from '../../../actions/modal'; -import { setFilter, clearNotifications, requestBrowserPermission, updateNotificationsPolicy } from '../../../actions/notifications'; +import { clearNotifications } from '../../../actions/notification_groups'; +import { updateNotificationsPolicy } from '../../../actions/notification_policies'; +import { setFilter, requestBrowserPermission } from '../../../actions/notifications'; import { changeAlerts as changePushNotifications } from '../../../actions/push_notifications'; import { changeSetting } from '../../../actions/settings'; import ColumnSettings from '../components/column_settings'; @@ -15,13 +19,16 @@ const messages = defineMessages({ permissionDenied: { id: 'notifications.permission_denied_alert', defaultMessage: 'Desktop notifications can\'t be enabled, as browser permission has been denied before' }, }); +/** + * @param {import('mastodon/store').RootState} state + */ const mapStateToProps = state => ({ settings: state.getIn(['settings', 'notifications']), pushSettings: state.get('push_notifications'), alertsEnabled: state.getIn(['settings', 'notifications', 'alerts']).includes(true), browserSupport: state.getIn(['notifications', 'browserSupport']), browserPermission: state.getIn(['notifications', 'browserPermission']), - notificationPolicy: state.get('notificationPolicy'), + notificationPolicy: state.notificationPolicy, }); const mapDispatchToProps = (dispatch, { intl }) => ({ @@ -54,6 +61,9 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ } else { dispatch(changeSetting(['notifications', ...path], checked)); } + } else if(path[0] === 'groupingBeta') { + dispatch(changeSetting(['notifications', ...path], checked)); + dispatch(initializeNotifications()); } else { dispatch(changeSetting(['notifications', ...path], checked)); } diff --git a/app/javascript/mastodon/features/notifications/containers/filter_bar_container.js b/app/javascript/mastodon/features/notifications/containers/filter_bar_container.js index e448cd26ad9ea5..4e0184cef30534 100644 --- a/app/javascript/mastodon/features/notifications/containers/filter_bar_container.js +++ b/app/javascript/mastodon/features/notifications/containers/filter_bar_container.js @@ -5,7 +5,7 @@ import FilterBar from '../components/filter_bar'; const makeMapStateToProps = state => ({ selectedFilter: state.getIn(['settings', 'notifications', 'quickFilter', 'active']), - advancedMode: false, + advancedMode: state.getIn(['settings', 'notifications', 'quickFilter', 'advanced']), }); const mapDispatchToProps = (dispatch) => ({ diff --git a/app/javascript/mastodon/features/notifications/containers/notification_container.js b/app/javascript/mastodon/features/notifications/containers/notification_container.js index 4458fd7bc3f3f0..d64f2a679cfeb5 100644 --- a/app/javascript/mastodon/features/notifications/containers/notification_container.js +++ b/app/javascript/mastodon/features/notifications/containers/notification_container.js @@ -1,18 +1,13 @@ import { connect } from 'react-redux'; -import { initBoostModal } from '../../../actions/boosts'; import { mentionCompose } from '../../../actions/compose'; import { - reblog, - favourite, - unreblog, - unfavourite, + toggleFavourite, + toggleReblog, } from '../../../actions/interactions'; import { - hideStatus, - revealStatus, + toggleStatusSpoilers, } from '../../../actions/statuses'; -import { boostModal } from '../../../initial_state'; import { makeGetNotification, makeGetStatus, makeGetReport } from '../../../selectors'; import Notification from '../components/notification'; @@ -34,40 +29,20 @@ const makeMapStateToProps = () => { }; const mapDispatchToProps = dispatch => ({ - onMention: (account, router) => { - dispatch(mentionCompose(account, router)); - }, - - onModalReblog (status, privacy) { - dispatch(reblog(status, privacy)); + onMention: (account) => { + dispatch(mentionCompose(account)); }, onReblog (status, e) { - if (status.get('reblogged')) { - dispatch(unreblog(status)); - } else { - if (e.shiftKey || !boostModal) { - this.onModalReblog(status); - } else { - dispatch(initBoostModal({ status, onReblog: this.onModalReblog })); - } - } + dispatch(toggleReblog(status.get('id'), e.shiftKey)); }, onFavourite (status) { - if (status.get('favourited')) { - dispatch(unfavourite(status)); - } else { - dispatch(favourite(status)); - } + dispatch(toggleFavourite(status.get('id'))); }, onToggleHidden (status) { - if (status.get('hidden')) { - dispatch(revealStatus(status.get('id'))); - } else { - dispatch(hideStatus(status.get('id'))); - } + dispatch(toggleStatusSpoilers(status.get('id'))); }, }); diff --git a/app/javascript/mastodon/features/notifications/index.jsx b/app/javascript/mastodon/features/notifications/index.jsx index e062957ff89a19..f5ebe6fe91c0e5 100644 --- a/app/javascript/mastodon/features/notifications/index.jsx +++ b/app/javascript/mastodon/features/notifications/index.jsx @@ -17,6 +17,7 @@ import NotificationsIcon from '@/material-icons/400-24px/notifications-fill.svg? import { compareId } from 'mastodon/compare_id'; import { Icon } from 'mastodon/components/icon'; import { NotSignedInIndicator } from 'mastodon/components/not_signed_in_indicator'; +import { identityContextPropShape, withIdentity } from 'mastodon/identity_context'; import { addColumn, removeColumn, moveColumn } from '../../actions/columns'; import { submitMarkers } from '../../actions/markers'; @@ -77,12 +78,8 @@ const mapStateToProps = state => ({ }); class Notifications extends PureComponent { - - static contextTypes = { - identity: PropTypes.object, - }; - static propTypes = { + identity: identityContextPropShape, columnId: PropTypes.string, notifications: ImmutablePropTypes.list.isRequired, dispatch: PropTypes.func.isRequired, @@ -190,7 +187,7 @@ class Notifications extends PureComponent { const { intl, notifications, isLoading, isUnread, columnId, multiColumn, hasMore, numPending, lastReadId, canMarkAsRead, needsNotificationPermission } = this.props; const pinned = !!columnId; const emptyMessage = ; - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; let scrollableContent = null; @@ -205,7 +202,7 @@ class Notifications extends PureComponent { 0 ? notifications.getIn([index - 1, 'id']) : null} + param={index > 0 ? notifications.getIn([index - 1, 'id']) : null} onClick={this.handleLoadGap} /> ) : ( @@ -226,6 +223,13 @@ class Notifications extends PureComponent { let scrollContainer; + const prepend = ( + <> + {needsNotificationPermission && } + + + ); + if (signedIn) { scrollContainer = ( } + prepend={prepend} alwaysPrepend emptyMessage={emptyMessage} onLoadMore={this.handleLoadOlder} @@ -285,8 +289,6 @@ class Notifications extends PureComponent { {filterBarContainer} - - {scrollContainer} @@ -299,4 +301,4 @@ class Notifications extends PureComponent { } -export default connect(mapStateToProps)(injectIntl(Notifications)); +export default connect(mapStateToProps)(withIdentity(injectIntl(Notifications))); diff --git a/app/javascript/mastodon/features/notifications_v2/components/avatar_group.tsx b/app/javascript/mastodon/features/notifications_v2/components/avatar_group.tsx new file mode 100644 index 00000000000000..b5da8914a1da08 --- /dev/null +++ b/app/javascript/mastodon/features/notifications_v2/components/avatar_group.tsx @@ -0,0 +1,31 @@ +import { Link } from 'react-router-dom'; + +import { Avatar } from 'mastodon/components/avatar'; +import { NOTIFICATIONS_GROUP_MAX_AVATARS } from 'mastodon/models/notification_group'; +import { useAppSelector } from 'mastodon/store'; + +const AvatarWrapper: React.FC<{ accountId: string }> = ({ accountId }) => { + const account = useAppSelector((state) => state.accounts.get(accountId)); + + if (!account) return null; + + return ( + + + + ); +}; + +export const AvatarGroup: React.FC<{ accountIds: string[] }> = ({ + accountIds, +}) => ( +
+ {accountIds.slice(0, NOTIFICATIONS_GROUP_MAX_AVATARS).map((accountId) => ( + + ))} +
+); diff --git a/app/javascript/mastodon/features/notifications_v2/components/embedded_status.tsx b/app/javascript/mastodon/features/notifications_v2/components/embedded_status.tsx new file mode 100644 index 00000000000000..baec0161173ff3 --- /dev/null +++ b/app/javascript/mastodon/features/notifications_v2/components/embedded_status.tsx @@ -0,0 +1,159 @@ +import { useCallback, useRef } from 'react'; + +import { FormattedMessage } from 'react-intl'; + +import { useHistory } from 'react-router-dom'; + +import type { List as ImmutableList, RecordOf } from 'immutable'; + +import BarChart4BarsIcon from '@/material-icons/400-24px/bar_chart_4_bars.svg?react'; +import PhotoLibraryIcon from '@/material-icons/400-24px/photo_library.svg?react'; +import { Avatar } from 'mastodon/components/avatar'; +import { DisplayName } from 'mastodon/components/display_name'; +import { Icon } from 'mastodon/components/icon'; +import type { Status } from 'mastodon/models/status'; +import { useAppSelector } from 'mastodon/store'; + +import { EmbeddedStatusContent } from './embedded_status_content'; + +export type Mention = RecordOf<{ url: string; acct: string }>; + +export const EmbeddedStatus: React.FC<{ statusId: string }> = ({ + statusId, +}) => { + const history = useHistory(); + const clickCoordinatesRef = useRef<[number, number] | null>(); + + const status = useAppSelector( + (state) => state.statuses.get(statusId) as Status | undefined, + ); + + const account = useAppSelector((state) => + state.accounts.get(status?.get('account') as string), + ); + + const handleMouseDown = useCallback>( + ({ clientX, clientY }) => { + clickCoordinatesRef.current = [clientX, clientY]; + }, + [clickCoordinatesRef], + ); + + const handleMouseUp = useCallback>( + ({ clientX, clientY, target, button }) => { + const [startX, startY] = clickCoordinatesRef.current ?? [0, 0]; + const [deltaX, deltaY] = [ + Math.abs(clientX - startX), + Math.abs(clientY - startY), + ]; + + let element: HTMLDivElement | null = target as HTMLDivElement; + + while (element) { + if ( + element.localName === 'button' || + element.localName === 'a' || + element.localName === 'label' + ) { + return; + } + + element = element.parentNode as HTMLDivElement | null; + } + + if (deltaX + deltaY < 5 && button === 0 && account) { + history.push(`/@${account.acct}/${statusId}`); + } + + clickCoordinatesRef.current = null; + }, + [clickCoordinatesRef, statusId, account, history], + ); + + const handleMouseEnter = useCallback>( + ({ currentTarget }) => { + const emojis = + currentTarget.querySelectorAll('.custom-emoji'); + + for (const emoji of emojis) { + const newSrc = emoji.getAttribute('data-original'); + if (newSrc) emoji.src = newSrc; + } + }, + [], + ); + + const handleMouseLeave = useCallback>( + ({ currentTarget }) => { + const emojis = + currentTarget.querySelectorAll('.custom-emoji'); + + for (const emoji of emojis) { + const newSrc = emoji.getAttribute('data-static'); + if (newSrc) emoji.src = newSrc; + } + }, + [], + ); + + if (!status) { + return null; + } + + // Assign status attributes to variables with a forced type, as status is not yet properly typed + const contentHtml = status.get('contentHtml') as string; + const poll = status.get('poll'); + const language = status.get('language') as string; + const mentions = status.get('mentions') as ImmutableList; + const mediaAttachmentsSize = ( + status.get('media_attachments') as ImmutableList + ).size; + + return ( +
+
+ + +
+ + + + {(poll || mediaAttachmentsSize > 0) && ( +
+ {!!poll && ( + <> + + + + )} + {mediaAttachmentsSize > 0 && ( + <> + + + + )} +
+ )} +
+ ); +}; diff --git a/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx b/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx new file mode 100644 index 00000000000000..1a38be536ba6a8 --- /dev/null +++ b/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx @@ -0,0 +1,93 @@ +import { useCallback } from 'react'; + +import { useHistory } from 'react-router-dom'; + +import type { List } from 'immutable'; + +import type { History } from 'history'; + +import type { Mention } from './embedded_status'; + +const handleMentionClick = ( + history: History, + mention: Mention, + e: MouseEvent, +) => { + if (e.button === 0 && !(e.ctrlKey || e.metaKey)) { + e.preventDefault(); + history.push(`/@${mention.get('acct')}`); + } +}; + +const handleHashtagClick = ( + history: History, + hashtag: string, + e: MouseEvent, +) => { + if (e.button === 0 && !(e.ctrlKey || e.metaKey)) { + e.preventDefault(); + history.push(`/tags/${hashtag.replace(/^#/, '')}`); + } +}; + +export const EmbeddedStatusContent: React.FC<{ + content: string; + mentions: List; + language: string; + className?: string; +}> = ({ content, mentions, language, className }) => { + const history = useHistory(); + + const handleContentRef = useCallback( + (node: HTMLDivElement | null) => { + if (!node) { + return; + } + + const links = node.querySelectorAll('a'); + + for (const link of links) { + if (link.classList.contains('status-link')) { + continue; + } + + link.classList.add('status-link'); + + const mention = mentions.find((item) => link.href === item.get('url')); + + if (mention) { + link.addEventListener( + 'click', + handleMentionClick.bind(null, history, mention), + false, + ); + link.setAttribute('title', `@${mention.get('acct')}`); + link.setAttribute('href', `/@${mention.get('acct')}`); + } else if ( + link.textContent?.[0] === '#' || + link.previousSibling?.textContent?.endsWith('#') + ) { + link.addEventListener( + 'click', + handleHashtagClick.bind(null, history, link.text), + false, + ); + link.setAttribute('href', `/tags/${link.text.replace(/^#/, '')}`); + } else { + link.setAttribute('title', link.href); + link.classList.add('unhandled-link'); + } + } + }, + [mentions, history], + ); + + return ( +
+ ); +}; diff --git a/app/javascript/mastodon/features/notifications_v2/components/names_list.tsx b/app/javascript/mastodon/features/notifications_v2/components/names_list.tsx new file mode 100644 index 00000000000000..3d70cc0b623260 --- /dev/null +++ b/app/javascript/mastodon/features/notifications_v2/components/names_list.tsx @@ -0,0 +1,51 @@ +import { FormattedMessage } from 'react-intl'; + +import { Link } from 'react-router-dom'; + +import { useAppSelector } from 'mastodon/store'; + +export const NamesList: React.FC<{ + accountIds: string[]; + total: number; + seeMoreHref?: string; +}> = ({ accountIds, total, seeMoreHref }) => { + const lastAccountId = accountIds[0] ?? '0'; + const account = useAppSelector((state) => state.accounts.get(lastAccountId)); + + if (!account) return null; + + const displayedName = ( + + + + ); + + if (total === 1) { + return displayedName; + } + + if (seeMoreHref) + return ( + {chunks}, + }} + /> + ); + + return ( + + ); +}; diff --git a/app/javascript/mastodon/features/notifications_v2/components/notification_admin_report.tsx b/app/javascript/mastodon/features/notifications_v2/components/notification_admin_report.tsx new file mode 100644 index 00000000000000..fda5798ae98b49 --- /dev/null +++ b/app/javascript/mastodon/features/notifications_v2/components/notification_admin_report.tsx @@ -0,0 +1,132 @@ +import { FormattedMessage, useIntl, defineMessages } from 'react-intl'; + +import classNames from 'classnames'; + +import FlagIcon from '@/material-icons/400-24px/flag-fill.svg?react'; +import { Icon } from 'mastodon/components/icon'; +import { RelativeTimestamp } from 'mastodon/components/relative_timestamp'; +import type { NotificationGroupAdminReport } from 'mastodon/models/notification_group'; +import { useAppSelector } from 'mastodon/store'; + +// This needs to be kept in sync with app/models/report.rb +const messages = defineMessages({ + other: { + id: 'report_notification.categories.other_sentence', + defaultMessage: 'other', + }, + spam: { + id: 'report_notification.categories.spam_sentence', + defaultMessage: 'spam', + }, + legal: { + id: 'report_notification.categories.legal_sentence', + defaultMessage: 'illegal content', + }, + violation: { + id: 'report_notification.categories.violation_sentence', + defaultMessage: 'rule violation', + }, +}); + +export const NotificationAdminReport: React.FC<{ + notification: NotificationGroupAdminReport; + unread?: boolean; +}> = ({ notification, notification: { report }, unread }) => { + const intl = useIntl(); + const targetAccount = useAppSelector((state) => + state.accounts.get(report.targetAccountId), + ); + const account = useAppSelector((state) => + state.accounts.get(notification.sampleAccountIds[0] ?? '0'), + ); + + if (!account || !targetAccount) return null; + + const values = { + name: ( + + ), + target: ( + + ), + category: intl.formatMessage(messages[report.category]), + count: report.status_ids.length, + }; + + let message; + + if (report.status_ids.length > 0) { + if (report.category === 'other') { + message = ( + + ); + } else { + message = ( + + ); + } + } else { + if (report.category === 'other') { + message = ( + + ); + } else { + message = ( + + ); + } + } + + return ( + +
+ +
+ +
+
+
+ {message} + +
+
+ + {report.comment.length > 0 && ( +
+ “{report.comment}†+
+ )} +
+
+ ); +}; diff --git a/app/javascript/mastodon/features/notifications_v2/components/notification_admin_sign_up.tsx b/app/javascript/mastodon/features/notifications_v2/components/notification_admin_sign_up.tsx new file mode 100644 index 00000000000000..9f7afc63f5b073 --- /dev/null +++ b/app/javascript/mastodon/features/notifications_v2/components/notification_admin_sign_up.tsx @@ -0,0 +1,31 @@ +import { FormattedMessage } from 'react-intl'; + +import PersonAddIcon from '@/material-icons/400-24px/person_add-fill.svg?react'; +import type { NotificationGroupAdminSignUp } from 'mastodon/models/notification_group'; + +import type { LabelRenderer } from './notification_group_with_status'; +import { NotificationGroupWithStatus } from './notification_group_with_status'; + +const labelRenderer: LabelRenderer = (values) => ( + +); + +export const NotificationAdminSignUp: React.FC<{ + notification: NotificationGroupAdminSignUp; + unread: boolean; +}> = ({ notification, unread }) => ( + +); diff --git a/app/javascript/mastodon/features/notifications_v2/components/notification_favourite.tsx b/app/javascript/mastodon/features/notifications_v2/components/notification_favourite.tsx new file mode 100644 index 00000000000000..22838fe69bc0be --- /dev/null +++ b/app/javascript/mastodon/features/notifications_v2/components/notification_favourite.tsx @@ -0,0 +1,45 @@ +import { FormattedMessage } from 'react-intl'; + +import StarIcon from '@/material-icons/400-24px/star-fill.svg?react'; +import type { NotificationGroupFavourite } from 'mastodon/models/notification_group'; +import { useAppSelector } from 'mastodon/store'; + +import type { LabelRenderer } from './notification_group_with_status'; +import { NotificationGroupWithStatus } from './notification_group_with_status'; + +const labelRenderer: LabelRenderer = (values) => ( + +); + +export const NotificationFavourite: React.FC<{ + notification: NotificationGroupFavourite; + unread: boolean; +}> = ({ notification, unread }) => { + const { statusId } = notification; + const statusAccount = useAppSelector( + (state) => + state.accounts.get(state.statuses.getIn([statusId, 'account']) as string) + ?.acct, + ); + + return ( + + ); +}; diff --git a/app/javascript/mastodon/features/notifications_v2/components/notification_follow.tsx b/app/javascript/mastodon/features/notifications_v2/components/notification_follow.tsx new file mode 100644 index 00000000000000..0ed96ae636c662 --- /dev/null +++ b/app/javascript/mastodon/features/notifications_v2/components/notification_follow.tsx @@ -0,0 +1,31 @@ +import { FormattedMessage } from 'react-intl'; + +import PersonAddIcon from '@/material-icons/400-24px/person_add-fill.svg?react'; +import type { NotificationGroupFollow } from 'mastodon/models/notification_group'; + +import type { LabelRenderer } from './notification_group_with_status'; +import { NotificationGroupWithStatus } from './notification_group_with_status'; + +const labelRenderer: LabelRenderer = (values) => ( + +); + +export const NotificationFollow: React.FC<{ + notification: NotificationGroupFollow; + unread: boolean; +}> = ({ notification, unread }) => ( + +); diff --git a/app/javascript/mastodon/features/notifications_v2/components/notification_follow_request.tsx b/app/javascript/mastodon/features/notifications_v2/components/notification_follow_request.tsx new file mode 100644 index 00000000000000..8c9837efa34da8 --- /dev/null +++ b/app/javascript/mastodon/features/notifications_v2/components/notification_follow_request.tsx @@ -0,0 +1,78 @@ +import { useCallback } from 'react'; + +import { FormattedMessage, useIntl, defineMessages } from 'react-intl'; + +import CheckIcon from '@/material-icons/400-24px/check.svg?react'; +import CloseIcon from '@/material-icons/400-24px/close.svg?react'; +import PersonAddIcon from '@/material-icons/400-24px/person_add-fill.svg?react'; +import { + authorizeFollowRequest, + rejectFollowRequest, +} from 'mastodon/actions/accounts'; +import { IconButton } from 'mastodon/components/icon_button'; +import type { NotificationGroupFollowRequest } from 'mastodon/models/notification_group'; +import { useAppDispatch } from 'mastodon/store'; + +import type { LabelRenderer } from './notification_group_with_status'; +import { NotificationGroupWithStatus } from './notification_group_with_status'; + +const messages = defineMessages({ + authorize: { id: 'follow_request.authorize', defaultMessage: 'Authorize' }, + reject: { id: 'follow_request.reject', defaultMessage: 'Reject' }, +}); + +const labelRenderer: LabelRenderer = (values) => ( + +); + +export const NotificationFollowRequest: React.FC<{ + notification: NotificationGroupFollowRequest; + unread: boolean; +}> = ({ notification, unread }) => { + const intl = useIntl(); + + const dispatch = useAppDispatch(); + + const onAuthorize = useCallback(() => { + dispatch(authorizeFollowRequest(notification.sampleAccountIds[0])); + }, [dispatch, notification.sampleAccountIds]); + + const onReject = useCallback(() => { + dispatch(rejectFollowRequest(notification.sampleAccountIds[0])); + }, [dispatch, notification.sampleAccountIds]); + + const actions = ( +
+ + +
+ ); + + return ( + + ); +}; diff --git a/app/javascript/mastodon/features/notifications_v2/components/notification_group.tsx b/app/javascript/mastodon/features/notifications_v2/components/notification_group.tsx new file mode 100644 index 00000000000000..36f033261ae44d --- /dev/null +++ b/app/javascript/mastodon/features/notifications_v2/components/notification_group.tsx @@ -0,0 +1,151 @@ +import { useMemo } from 'react'; + +import { HotKeys } from 'react-hotkeys'; + +import { navigateToProfile } from 'mastodon/actions/accounts'; +import { mentionComposeById } from 'mastodon/actions/compose'; +import type { NotificationGroup as NotificationGroupModel } from 'mastodon/models/notification_group'; +import { useAppSelector, useAppDispatch } from 'mastodon/store'; + +import { NotificationAdminReport } from './notification_admin_report'; +import { NotificationAdminSignUp } from './notification_admin_sign_up'; +import { NotificationFavourite } from './notification_favourite'; +import { NotificationFollow } from './notification_follow'; +import { NotificationFollowRequest } from './notification_follow_request'; +import { NotificationMention } from './notification_mention'; +import { NotificationModerationWarning } from './notification_moderation_warning'; +import { NotificationPoll } from './notification_poll'; +import { NotificationReblog } from './notification_reblog'; +import { NotificationSeveredRelationships } from './notification_severed_relationships'; +import { NotificationStatus } from './notification_status'; +import { NotificationUpdate } from './notification_update'; + +export const NotificationGroup: React.FC<{ + notificationGroupId: NotificationGroupModel['group_key']; + unread: boolean; + onMoveUp: (groupId: string) => void; + onMoveDown: (groupId: string) => void; +}> = ({ notificationGroupId, unread, onMoveUp, onMoveDown }) => { + const notificationGroup = useAppSelector((state) => + state.notificationGroups.groups.find( + (item) => item.type !== 'gap' && item.group_key === notificationGroupId, + ), + ); + + const dispatch = useAppDispatch(); + + const accountId = + notificationGroup?.type === 'gap' + ? undefined + : notificationGroup?.sampleAccountIds[0]; + + const handlers = useMemo( + () => ({ + moveUp: () => { + onMoveUp(notificationGroupId); + }, + + moveDown: () => { + onMoveDown(notificationGroupId); + }, + + openProfile: () => { + if (accountId) dispatch(navigateToProfile(accountId)); + }, + + mention: () => { + if (accountId) dispatch(mentionComposeById(accountId)); + }, + }), + [dispatch, notificationGroupId, accountId, onMoveUp, onMoveDown], + ); + + if (!notificationGroup || notificationGroup.type === 'gap') return null; + + let content; + + switch (notificationGroup.type) { + case 'reblog': + content = ( + + ); + break; + case 'favourite': + content = ( + + ); + break; + case 'severed_relationships': + content = ( + + ); + break; + case 'mention': + content = ( + + ); + break; + case 'follow': + content = ( + + ); + break; + case 'follow_request': + content = ( + + ); + break; + case 'poll': + content = ( + + ); + break; + case 'status': + content = ( + + ); + break; + case 'update': + content = ( + + ); + break; + case 'admin.sign_up': + content = ( + + ); + break; + case 'admin.report': + content = ( + + ); + break; + case 'moderation_warning': + content = ( + + ); + break; + default: + return null; + } + + return {content}; +}; diff --git a/app/javascript/mastodon/features/notifications_v2/components/notification_group_with_status.tsx b/app/javascript/mastodon/features/notifications_v2/components/notification_group_with_status.tsx new file mode 100644 index 00000000000000..2af73c8362a7b7 --- /dev/null +++ b/app/javascript/mastodon/features/notifications_v2/components/notification_group_with_status.tsx @@ -0,0 +1,113 @@ +import { useMemo } from 'react'; + +import classNames from 'classnames'; + +import { HotKeys } from 'react-hotkeys'; + +import { replyComposeById } from 'mastodon/actions/compose'; +import { navigateToStatus } from 'mastodon/actions/statuses'; +import type { IconProp } from 'mastodon/components/icon'; +import { Icon } from 'mastodon/components/icon'; +import { RelativeTimestamp } from 'mastodon/components/relative_timestamp'; +import { useAppDispatch } from 'mastodon/store'; + +import { AvatarGroup } from './avatar_group'; +import { EmbeddedStatus } from './embedded_status'; +import { NamesList } from './names_list'; + +export type LabelRenderer = ( + values: Record, +) => JSX.Element; + +export const NotificationGroupWithStatus: React.FC<{ + icon: IconProp; + iconId: string; + statusId?: string; + actions?: JSX.Element; + count: number; + accountIds: string[]; + timestamp: string; + labelRenderer: LabelRenderer; + labelSeeMoreHref?: string; + type: string; + unread: boolean; +}> = ({ + icon, + iconId, + timestamp, + accountIds, + actions, + count, + statusId, + labelRenderer, + labelSeeMoreHref, + type, + unread, +}) => { + const dispatch = useAppDispatch(); + + const label = useMemo( + () => + labelRenderer({ + name: ( + + ), + }), + [labelRenderer, accountIds, count, labelSeeMoreHref], + ); + + const handlers = useMemo( + () => ({ + open: () => { + dispatch(navigateToStatus(statusId)); + }, + + reply: () => { + dispatch(replyComposeById(statusId)); + }, + }), + [dispatch, statusId], + ); + + return ( + +
+
+ +
+ +
+
+
+ + + {actions} +
+ +
+ {label} + {timestamp && } +
+
+ + {statusId && ( +
+ +
+ )} +
+
+
+ ); +}; diff --git a/app/javascript/mastodon/features/notifications_v2/components/notification_mention.tsx b/app/javascript/mastodon/features/notifications_v2/components/notification_mention.tsx new file mode 100644 index 00000000000000..8c584f0ce1dde2 --- /dev/null +++ b/app/javascript/mastodon/features/notifications_v2/components/notification_mention.tsx @@ -0,0 +1,55 @@ +import { FormattedMessage } from 'react-intl'; + +import ReplyIcon from '@/material-icons/400-24px/reply-fill.svg?react'; +import type { StatusVisibility } from 'mastodon/api_types/statuses'; +import type { NotificationGroupMention } from 'mastodon/models/notification_group'; +import { useAppSelector } from 'mastodon/store'; + +import type { LabelRenderer } from './notification_group_with_status'; +import { NotificationWithStatus } from './notification_with_status'; + +const labelRenderer: LabelRenderer = (values) => ( + +); + +const privateMentionLabelRenderer: LabelRenderer = (values) => ( + +); + +export const NotificationMention: React.FC<{ + notification: NotificationGroupMention; + unread: boolean; +}> = ({ notification, unread }) => { + const statusVisibility = useAppSelector( + (state) => + state.statuses.getIn([ + notification.statusId, + 'visibility', + ]) as StatusVisibility, + ); + + return ( + + ); +}; diff --git a/app/javascript/mastodon/features/notifications_v2/components/notification_moderation_warning.tsx b/app/javascript/mastodon/features/notifications_v2/components/notification_moderation_warning.tsx new file mode 100644 index 00000000000000..d653385fda83c4 --- /dev/null +++ b/app/javascript/mastodon/features/notifications_v2/components/notification_moderation_warning.tsx @@ -0,0 +1,13 @@ +import { ModerationWarning } from 'mastodon/features/notifications/components/moderation_warning'; +import type { NotificationGroupModerationWarning } from 'mastodon/models/notification_group'; + +export const NotificationModerationWarning: React.FC<{ + notification: NotificationGroupModerationWarning; + unread: boolean; +}> = ({ notification: { moderationWarning }, unread }) => ( + +); diff --git a/app/javascript/mastodon/features/notifications_v2/components/notification_poll.tsx b/app/javascript/mastodon/features/notifications_v2/components/notification_poll.tsx new file mode 100644 index 00000000000000..a7748c2c7c372b --- /dev/null +++ b/app/javascript/mastodon/features/notifications_v2/components/notification_poll.tsx @@ -0,0 +1,41 @@ +import { FormattedMessage } from 'react-intl'; + +import BarChart4BarsIcon from '@/material-icons/400-20px/bar_chart_4_bars.svg?react'; +import { me } from 'mastodon/initial_state'; +import type { NotificationGroupPoll } from 'mastodon/models/notification_group'; + +import { NotificationWithStatus } from './notification_with_status'; + +const labelRendererOther = () => ( + +); + +const labelRendererOwn = () => ( + +); + +export const NotificationPoll: React.FC<{ + notification: NotificationGroupPoll; + unread: boolean; +}> = ({ notification, unread }) => ( + +); diff --git a/app/javascript/mastodon/features/notifications_v2/components/notification_reblog.tsx b/app/javascript/mastodon/features/notifications_v2/components/notification_reblog.tsx new file mode 100644 index 00000000000000..06255686884142 --- /dev/null +++ b/app/javascript/mastodon/features/notifications_v2/components/notification_reblog.tsx @@ -0,0 +1,45 @@ +import { FormattedMessage } from 'react-intl'; + +import RepeatIcon from '@/material-icons/400-24px/repeat.svg?react'; +import type { NotificationGroupReblog } from 'mastodon/models/notification_group'; +import { useAppSelector } from 'mastodon/store'; + +import type { LabelRenderer } from './notification_group_with_status'; +import { NotificationGroupWithStatus } from './notification_group_with_status'; + +const labelRenderer: LabelRenderer = (values) => ( + +); + +export const NotificationReblog: React.FC<{ + notification: NotificationGroupReblog; + unread: boolean; +}> = ({ notification, unread }) => { + const { statusId } = notification; + const statusAccount = useAppSelector( + (state) => + state.accounts.get(state.statuses.getIn([statusId, 'account']) as string) + ?.acct, + ); + + return ( + + ); +}; diff --git a/app/javascript/mastodon/features/notifications_v2/components/notification_severed_relationships.tsx b/app/javascript/mastodon/features/notifications_v2/components/notification_severed_relationships.tsx new file mode 100644 index 00000000000000..fd92498ea3dfc2 --- /dev/null +++ b/app/javascript/mastodon/features/notifications_v2/components/notification_severed_relationships.tsx @@ -0,0 +1,15 @@ +import { RelationshipsSeveranceEvent } from 'mastodon/features/notifications/components/relationships_severance_event'; +import type { NotificationGroupSeveredRelationships } from 'mastodon/models/notification_group'; + +export const NotificationSeveredRelationships: React.FC<{ + notification: NotificationGroupSeveredRelationships; + unread: boolean; +}> = ({ notification: { event }, unread }) => ( + +); diff --git a/app/javascript/mastodon/features/notifications_v2/components/notification_status.tsx b/app/javascript/mastodon/features/notifications_v2/components/notification_status.tsx new file mode 100644 index 00000000000000..9ade355a71494b --- /dev/null +++ b/app/javascript/mastodon/features/notifications_v2/components/notification_status.tsx @@ -0,0 +1,31 @@ +import { FormattedMessage } from 'react-intl'; + +import NotificationsActiveIcon from '@/material-icons/400-24px/notifications_active-fill.svg?react'; +import type { NotificationGroupStatus } from 'mastodon/models/notification_group'; + +import type { LabelRenderer } from './notification_group_with_status'; +import { NotificationWithStatus } from './notification_with_status'; + +const labelRenderer: LabelRenderer = (values) => ( + +); + +export const NotificationStatus: React.FC<{ + notification: NotificationGroupStatus; + unread: boolean; +}> = ({ notification, unread }) => ( + +); diff --git a/app/javascript/mastodon/features/notifications_v2/components/notification_update.tsx b/app/javascript/mastodon/features/notifications_v2/components/notification_update.tsx new file mode 100644 index 00000000000000..c518367bf5a24f --- /dev/null +++ b/app/javascript/mastodon/features/notifications_v2/components/notification_update.tsx @@ -0,0 +1,31 @@ +import { FormattedMessage } from 'react-intl'; + +import EditIcon from '@/material-icons/400-24px/edit.svg?react'; +import type { NotificationGroupUpdate } from 'mastodon/models/notification_group'; + +import type { LabelRenderer } from './notification_group_with_status'; +import { NotificationWithStatus } from './notification_with_status'; + +const labelRenderer: LabelRenderer = (values) => ( + +); + +export const NotificationUpdate: React.FC<{ + notification: NotificationGroupUpdate; + unread: boolean; +}> = ({ notification, unread }) => ( + +); diff --git a/app/javascript/mastodon/features/notifications_v2/components/notification_with_status.tsx b/app/javascript/mastodon/features/notifications_v2/components/notification_with_status.tsx new file mode 100644 index 00000000000000..c7dd9f6be2e320 --- /dev/null +++ b/app/javascript/mastodon/features/notifications_v2/components/notification_with_status.tsx @@ -0,0 +1,111 @@ +import { useMemo } from 'react'; + +import classNames from 'classnames'; + +import { HotKeys } from 'react-hotkeys'; + +import { replyComposeById } from 'mastodon/actions/compose'; +import { toggleReblog, toggleFavourite } from 'mastodon/actions/interactions'; +import { + navigateToStatus, + toggleStatusSpoilers, +} from 'mastodon/actions/statuses'; +import type { IconProp } from 'mastodon/components/icon'; +import { Icon } from 'mastodon/components/icon'; +import Status from 'mastodon/containers/status_container'; +import { useAppSelector, useAppDispatch } from 'mastodon/store'; + +import { NamesList } from './names_list'; +import type { LabelRenderer } from './notification_group_with_status'; + +export const NotificationWithStatus: React.FC<{ + type: string; + icon: IconProp; + iconId: string; + accountIds: string[]; + statusId: string; + count: number; + labelRenderer: LabelRenderer; + unread: boolean; +}> = ({ + icon, + iconId, + accountIds, + statusId, + count, + labelRenderer, + type, + unread, +}) => { + const dispatch = useAppDispatch(); + + const label = useMemo( + () => + labelRenderer({ + name: , + }), + [labelRenderer, accountIds, count], + ); + + const isPrivateMention = useAppSelector( + (state) => state.statuses.getIn([statusId, 'visibility']) === 'direct', + ); + + const handlers = useMemo( + () => ({ + open: () => { + dispatch(navigateToStatus(statusId)); + }, + + reply: () => { + dispatch(replyComposeById(statusId)); + }, + + boost: () => { + dispatch(toggleReblog(statusId)); + }, + + favourite: () => { + dispatch(toggleFavourite(statusId)); + }, + + toggleHidden: () => { + dispatch(toggleStatusSpoilers(statusId)); + }, + }), + [dispatch, statusId], + ); + + return ( + +
+
+
+ +
+ {label} +
+ + is not yet typed + id={statusId} + contextType='notifications' + withDismiss + skipPrepend + avatarSize={40} + unfocusable + /> +
+
+ ); +}; diff --git a/app/javascript/mastodon/features/notifications_v2/filter_bar.tsx b/app/javascript/mastodon/features/notifications_v2/filter_bar.tsx new file mode 100644 index 00000000000000..37d2d864bbd38b --- /dev/null +++ b/app/javascript/mastodon/features/notifications_v2/filter_bar.tsx @@ -0,0 +1,145 @@ +import type { PropsWithChildren } from 'react'; +import { useCallback } from 'react'; + +import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; + +import HomeIcon from '@/material-icons/400-24px/home-fill.svg?react'; +import InsertChartIcon from '@/material-icons/400-24px/insert_chart.svg?react'; +import PersonAddIcon from '@/material-icons/400-24px/person_add.svg?react'; +import RepeatIcon from '@/material-icons/400-24px/repeat.svg?react'; +import ReplyAllIcon from '@/material-icons/400-24px/reply_all.svg?react'; +import StarIcon from '@/material-icons/400-24px/star.svg?react'; +import { setNotificationsFilter } from 'mastodon/actions/notification_groups'; +import { Icon } from 'mastodon/components/icon'; +import { + selectSettingsNotificationsQuickFilterActive, + selectSettingsNotificationsQuickFilterAdvanced, +} from 'mastodon/selectors/settings'; +import { useAppDispatch, useAppSelector } from 'mastodon/store'; + +const tooltips = defineMessages({ + mentions: { id: 'notifications.filter.mentions', defaultMessage: 'Mentions' }, + favourites: { + id: 'notifications.filter.favourites', + defaultMessage: 'Favorites', + }, + boosts: { id: 'notifications.filter.boosts', defaultMessage: 'Boosts' }, + polls: { id: 'notifications.filter.polls', defaultMessage: 'Poll results' }, + follows: { id: 'notifications.filter.follows', defaultMessage: 'Follows' }, + statuses: { + id: 'notifications.filter.statuses', + defaultMessage: 'Updates from people you follow', + }, +}); + +const BarButton: React.FC< + PropsWithChildren<{ + selectedFilter: string; + type: string; + title?: string; + }> +> = ({ selectedFilter, type, title, children }) => { + const dispatch = useAppDispatch(); + + const onClick = useCallback(() => { + void dispatch(setNotificationsFilter({ filterType: type })); + }, [dispatch, type]); + + return ( + + ); +}; + +export const FilterBar: React.FC = () => { + const intl = useIntl(); + + const selectedFilter = useAppSelector( + selectSettingsNotificationsQuickFilterActive, + ); + const advancedMode = useAppSelector( + selectSettingsNotificationsQuickFilterAdvanced, + ); + + if (advancedMode) + return ( +
+ + + + + + + + + + + + + + + + + + + + + +
+ ); + else + return ( +
+ + + + + + +
+ ); +}; diff --git a/app/javascript/mastodon/features/notifications_v2/index.tsx b/app/javascript/mastodon/features/notifications_v2/index.tsx new file mode 100644 index 00000000000000..fc20f0583631ed --- /dev/null +++ b/app/javascript/mastodon/features/notifications_v2/index.tsx @@ -0,0 +1,354 @@ +import { useCallback, useEffect, useMemo, useRef } from 'react'; + +import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; + +import { Helmet } from 'react-helmet'; + +import { createSelector } from '@reduxjs/toolkit'; + +import { useDebouncedCallback } from 'use-debounce'; + +import DoneAllIcon from '@/material-icons/400-24px/done_all.svg?react'; +import NotificationsIcon from '@/material-icons/400-24px/notifications-fill.svg?react'; +import { + fetchNotificationsGap, + updateScrollPosition, + loadPending, + markNotificationsAsRead, + mountNotifications, + unmountNotifications, +} from 'mastodon/actions/notification_groups'; +import { compareId } from 'mastodon/compare_id'; +import { Icon } from 'mastodon/components/icon'; +import { NotSignedInIndicator } from 'mastodon/components/not_signed_in_indicator'; +import { useIdentity } from 'mastodon/identity_context'; +import type { NotificationGap } from 'mastodon/reducers/notification_groups'; +import { + selectUnreadNotificationGroupsCount, + selectPendingNotificationGroupsCount, +} from 'mastodon/selectors/notifications'; +import { + selectNeedsNotificationPermission, + selectSettingsNotificationsExcludedTypes, + selectSettingsNotificationsQuickFilterActive, + selectSettingsNotificationsQuickFilterShow, + selectSettingsNotificationsShowUnread, +} from 'mastodon/selectors/settings'; +import { useAppDispatch, useAppSelector } from 'mastodon/store'; +import type { RootState } from 'mastodon/store'; + +import { addColumn, removeColumn, moveColumn } from '../../actions/columns'; +import { submitMarkers } from '../../actions/markers'; +import Column from '../../components/column'; +import { ColumnHeader } from '../../components/column_header'; +import { LoadGap } from '../../components/load_gap'; +import ScrollableList from '../../components/scrollable_list'; +import { FilteredNotificationsBanner } from '../notifications/components/filtered_notifications_banner'; +import NotificationsPermissionBanner from '../notifications/components/notifications_permission_banner'; +import ColumnSettingsContainer from '../notifications/containers/column_settings_container'; + +import { NotificationGroup } from './components/notification_group'; +import { FilterBar } from './filter_bar'; + +const messages = defineMessages({ + title: { id: 'column.notifications', defaultMessage: 'Notifications' }, + markAsRead: { + id: 'notifications.mark_as_read', + defaultMessage: 'Mark every notification as read', + }, +}); + +const getNotifications = createSelector( + [ + selectSettingsNotificationsQuickFilterShow, + selectSettingsNotificationsQuickFilterActive, + selectSettingsNotificationsExcludedTypes, + (state: RootState) => state.notificationGroups.groups, + ], + (showFilterBar, allowedType, excludedTypes, notifications) => { + if (!showFilterBar || allowedType === 'all') { + // used if user changed the notification settings after loading the notifications from the server + // otherwise a list of notifications will come pre-filtered from the backend + // we need to turn it off for FilterBar in order not to block ourselves from seeing a specific category + return notifications.filter( + (item) => item.type === 'gap' || !excludedTypes.includes(item.type), + ); + } + return notifications.filter( + (item) => item.type === 'gap' || allowedType === item.type, + ); + }, +); + +export const Notifications: React.FC<{ + columnId?: string; + multiColumn?: boolean; +}> = ({ columnId, multiColumn }) => { + const intl = useIntl(); + const notifications = useAppSelector(getNotifications); + const dispatch = useAppDispatch(); + const isLoading = useAppSelector((s) => s.notificationGroups.isLoading); + const hasMore = notifications.at(-1)?.type === 'gap'; + + const lastReadId = useAppSelector((s) => + selectSettingsNotificationsShowUnread(s) + ? s.notificationGroups.lastReadId + : '0', + ); + + const numPending = useAppSelector(selectPendingNotificationGroupsCount); + + const unreadNotificationsCount = useAppSelector( + selectUnreadNotificationGroupsCount, + ); + + const isUnread = unreadNotificationsCount > 0; + + const canMarkAsRead = + useAppSelector(selectSettingsNotificationsShowUnread) && + unreadNotificationsCount > 0; + + const needsNotificationPermission = useAppSelector( + selectNeedsNotificationPermission, + ); + + const columnRef = useRef(null); + + const selectChild = useCallback((index: number, alignTop: boolean) => { + const container = columnRef.current?.node as HTMLElement | undefined; + + if (!container) return; + + const element = container.querySelector( + `article:nth-of-type(${index + 1}) .focusable`, + ); + + if (element) { + if (alignTop && container.scrollTop > element.offsetTop) { + element.scrollIntoView(true); + } else if ( + !alignTop && + container.scrollTop + container.clientHeight < + element.offsetTop + element.offsetHeight + ) { + element.scrollIntoView(false); + } + element.focus(); + } + }, []); + + // Keep track of mounted components for unread notification handling + useEffect(() => { + dispatch(mountNotifications()); + + return () => { + dispatch(unmountNotifications()); + dispatch(updateScrollPosition({ top: false })); + }; + }, [dispatch]); + + const handleLoadGap = useCallback( + (gap: NotificationGap) => { + void dispatch(fetchNotificationsGap({ gap })); + }, + [dispatch], + ); + + const handleLoadOlder = useDebouncedCallback( + () => { + const gap = notifications.at(-1); + if (gap?.type === 'gap') void dispatch(fetchNotificationsGap({ gap })); + }, + 300, + { leading: true }, + ); + + const handleLoadPending = useCallback(() => { + dispatch(loadPending()); + }, [dispatch]); + + const handleScrollToTop = useDebouncedCallback(() => { + dispatch(updateScrollPosition({ top: true })); + }, 100); + + const handleScroll = useDebouncedCallback(() => { + dispatch(updateScrollPosition({ top: false })); + }, 100); + + useEffect(() => { + return () => { + handleLoadOlder.cancel(); + handleScrollToTop.cancel(); + handleScroll.cancel(); + }; + }, [handleLoadOlder, handleScrollToTop, handleScroll]); + + const handlePin = useCallback(() => { + if (columnId) { + dispatch(removeColumn(columnId)); + } else { + dispatch(addColumn('NOTIFICATIONS', {})); + } + }, [columnId, dispatch]); + + const handleMove = useCallback( + (dir: unknown) => { + dispatch(moveColumn(columnId, dir)); + }, + [dispatch, columnId], + ); + + const handleHeaderClick = useCallback(() => { + columnRef.current?.scrollTop(); + }, []); + + const handleMoveUp = useCallback( + (id: string) => { + const elementIndex = + notifications.findIndex( + (item) => item.type !== 'gap' && item.group_key === id, + ) - 1; + selectChild(elementIndex, true); + }, + [notifications, selectChild], + ); + + const handleMoveDown = useCallback( + (id: string) => { + const elementIndex = + notifications.findIndex( + (item) => item.type !== 'gap' && item.group_key === id, + ) + 1; + selectChild(elementIndex, false); + }, + [notifications, selectChild], + ); + + const handleMarkAsRead = useCallback(() => { + dispatch(markNotificationsAsRead()); + void dispatch(submitMarkers({ immediate: true })); + }, [dispatch]); + + const pinned = !!columnId; + const emptyMessage = ( + + ); + + const { signedIn } = useIdentity(); + + const filterBar = signedIn ? : null; + + const scrollableContent = useMemo(() => { + if (notifications.length === 0 && !hasMore) return null; + + return notifications.map((item) => + item.type === 'gap' ? ( + + ) : ( + 0 + } + /> + ), + ); + }, [ + notifications, + isLoading, + hasMore, + lastReadId, + handleLoadGap, + handleMoveUp, + handleMoveDown, + ]); + + const prepend = ( + <> + {needsNotificationPermission && } + + + ); + + const scrollContainer = signedIn ? ( + + {scrollableContent} + + ) : ( + + ); + + const extraButton = canMarkAsRead ? ( + + ) : null; + + return ( + + + + + + {filterBar} + + {scrollContainer} + + + {intl.formatMessage(messages.title)} + + + + ); +}; + +// eslint-disable-next-line import/no-default-export +export default Notifications; diff --git a/app/javascript/mastodon/features/notifications_wrapper.jsx b/app/javascript/mastodon/features/notifications_wrapper.jsx new file mode 100644 index 00000000000000..057ed1b395f8ec --- /dev/null +++ b/app/javascript/mastodon/features/notifications_wrapper.jsx @@ -0,0 +1,13 @@ +import Notifications from 'mastodon/features/notifications'; +import Notifications_v2 from 'mastodon/features/notifications_v2'; +import { useAppSelector } from 'mastodon/store'; + +export const NotificationsWrapper = (props) => { + const optedInGroupedNotifications = useAppSelector((state) => state.getIn(['settings', 'notifications', 'groupingBeta'], false)); + + return ( + optedInGroupedNotifications ? : + ); +}; + +export default NotificationsWrapper; \ No newline at end of file diff --git a/app/javascript/mastodon/features/onboarding/index.jsx b/app/javascript/mastodon/features/onboarding/index.jsx index 5900b9ec76db14..d100a1c3d5f626 100644 --- a/app/javascript/mastodon/features/onboarding/index.jsx +++ b/app/javascript/mastodon/features/onboarding/index.jsx @@ -3,7 +3,7 @@ import { useCallback } from 'react'; import { FormattedMessage, useIntl, defineMessages } from 'react-intl'; import { Helmet } from 'react-helmet'; -import { Link, Switch, Route, useHistory } from 'react-router-dom'; +import { Link, Switch, Route } from 'react-router-dom'; import { useDispatch } from 'react-redux'; @@ -16,6 +16,7 @@ import EditNoteIcon from '@/material-icons/400-24px/edit_note.svg?react'; import PersonAddIcon from '@/material-icons/400-24px/person_add.svg?react'; import { focusCompose } from 'mastodon/actions/compose'; import { Icon } from 'mastodon/components/icon'; +import { NotSignedInIndicator } from 'mastodon/components/not_signed_in_indicator'; import Column from 'mastodon/features/ui/components/column'; import { me } from 'mastodon/initial_state'; import { useAppSelector } from 'mastodon/store'; @@ -34,50 +35,51 @@ const Onboarding = () => { const account = useAppSelector(state => state.getIn(['accounts', me])); const dispatch = useDispatch(); const intl = useIntl(); - const history = useHistory(); const handleComposeClick = useCallback(() => { - dispatch(focusCompose(history, intl.formatMessage(messages.template))); - }, [dispatch, intl, history]); + dispatch(focusCompose(intl.formatMessage(messages.template))); + }, [dispatch, intl]); return ( - - -
-
- -

-

+ {account ? ( + + +
+
+ +

+

+
+ +
+ 0 && account.get('note').length > 0)} icon='address-book-o' iconComponent={AccountCircleIcon} label={} description={} /> + = 1} icon='user-plus' iconComponent={PersonAddIcon} label={} description={} /> + = 1} icon='pencil-square-o' iconComponent={EditNoteIcon} label={} description={ }} />} /> + } description={} /> +
+ +

+ +
+ + + + + + + + + +
+
-
- 0 && account.get('note').length > 0)} icon='address-book-o' iconComponent={AccountCircleIcon} label={} description={} /> - = 1} icon='user-plus' iconComponent={PersonAddIcon} label={} description={} /> - = 1} icon='pencil-square-o' iconComponent={EditNoteIcon} label={} description={ }} />} /> - } description={} /> -
- -

- -
- - - - - - - - - -
-
- - - - - - + + + + + ) : } diff --git a/app/javascript/mastodon/features/picture_in_picture/components/footer.jsx b/app/javascript/mastodon/features/picture_in_picture/components/footer.jsx index 8dfbf54cb649d6..d5226eb3461987 100644 --- a/app/javascript/mastodon/features/picture_in_picture/components/footer.jsx +++ b/app/javascript/mastodon/features/picture_in_picture/components/footer.jsx @@ -14,12 +14,12 @@ import RepeatIcon from '@/material-icons/400-24px/repeat.svg?react'; import ReplyIcon from '@/material-icons/400-24px/reply.svg?react'; import ReplyAllIcon from '@/material-icons/400-24px/reply_all.svg?react'; import StarIcon from '@/material-icons/400-24px/star.svg?react'; -import { initBoostModal } from 'mastodon/actions/boosts'; import { replyCompose } from 'mastodon/actions/compose'; -import { reblog, favourite, unreblog, unfavourite } from 'mastodon/actions/interactions'; +import { toggleReblog, toggleFavourite } from 'mastodon/actions/interactions'; import { openModal } from 'mastodon/actions/modal'; import { IconButton } from 'mastodon/components/icon_button'; -import { me, boostModal } from 'mastodon/initial_state'; +import { identityContextPropShape, withIdentity } from 'mastodon/identity_context'; +import { me } from 'mastodon/initial_state'; import { makeGetStatus } from 'mastodon/selectors'; import { WithRouterPropTypes } from 'mastodon/utils/react_router'; @@ -48,12 +48,8 @@ const makeMapStateToProps = () => { }; class Footer extends ImmutablePureComponent { - - static contextTypes = { - identity: PropTypes.object, - }; - static propTypes = { + identity: identityContextPropShape, statusId: PropTypes.string.isRequired, status: ImmutablePropTypes.map.isRequired, intl: PropTypes.object.isRequired, @@ -65,18 +61,18 @@ class Footer extends ImmutablePureComponent { }; _performReply = () => { - const { dispatch, status, onClose, history } = this.props; + const { dispatch, status, onClose } = this.props; if (onClose) { onClose(true); } - dispatch(replyCompose(status, history)); + dispatch(replyCompose(status)); }; handleReplyClick = () => { const { dispatch, askReplyConfirmation, status, intl } = this.props; - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; if (signedIn) { if (askReplyConfirmation) { @@ -105,14 +101,10 @@ class Footer extends ImmutablePureComponent { handleFavouriteClick = () => { const { dispatch, status } = this.props; - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; if (signedIn) { - if (status.get('favourited')) { - dispatch(unfavourite(status)); - } else { - dispatch(favourite(status)); - } + dispatch(toggleFavourite(status.get('id'))); } else { dispatch(openModal({ modalType: 'INTERACTION', @@ -125,23 +117,12 @@ class Footer extends ImmutablePureComponent { } }; - _performReblog = (status, privacy) => { - const { dispatch } = this.props; - dispatch(reblog(status, privacy)); - }; - handleReblogClick = e => { const { dispatch, status } = this.props; - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; if (signedIn) { - if (status.get('reblogged')) { - dispatch(unreblog(status)); - } else if ((e && e.shiftKey) || !boostModal) { - this._performReblog(status); - } else { - dispatch(initBoostModal({ status, onReblog: this._performReblog })); - } + dispatch(toggleReblog(status.get('id'), e && e.shiftKey)); } else { dispatch(openModal({ modalType: 'INTERACTION', @@ -210,4 +191,4 @@ class Footer extends ImmutablePureComponent { } -export default withRouter(connect(makeMapStateToProps)(injectIntl(Footer))); +export default connect(makeMapStateToProps)(withIdentity(withRouter(injectIntl(Footer)))); diff --git a/app/javascript/mastodon/features/picture_in_picture/components/header.jsx b/app/javascript/mastodon/features/picture_in_picture/components/header.jsx deleted file mode 100644 index 31073d7387c9bc..00000000000000 --- a/app/javascript/mastodon/features/picture_in_picture/components/header.jsx +++ /dev/null @@ -1,51 +0,0 @@ -import PropTypes from 'prop-types'; - -import { defineMessages, injectIntl } from 'react-intl'; - -import { Link } from 'react-router-dom'; - -import ImmutablePropTypes from 'react-immutable-proptypes'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import { connect } from 'react-redux'; - -import CloseIcon from '@/material-icons/400-24px/close.svg?react'; -import { Avatar } from 'mastodon/components/avatar'; -import { DisplayName } from 'mastodon/components/display_name'; -import { IconButton } from 'mastodon/components/icon_button'; - -const messages = defineMessages({ - close: { id: 'lightbox.close', defaultMessage: 'Close' }, -}); - -const mapStateToProps = (state, { accountId }) => ({ - account: state.getIn(['accounts', accountId]), -}); - -class Header extends ImmutablePureComponent { - - static propTypes = { - accountId: PropTypes.string.isRequired, - statusId: PropTypes.string.isRequired, - account: ImmutablePropTypes.record.isRequired, - onClose: PropTypes.func.isRequired, - intl: PropTypes.object.isRequired, - }; - - render () { - const { account, statusId, onClose, intl } = this.props; - - return ( -
- - - - - - -
- ); - } - -} - -export default connect(mapStateToProps)(injectIntl(Header)); diff --git a/app/javascript/mastodon/features/picture_in_picture/components/header.tsx b/app/javascript/mastodon/features/picture_in_picture/components/header.tsx new file mode 100644 index 00000000000000..0f897dc44123a5 --- /dev/null +++ b/app/javascript/mastodon/features/picture_in_picture/components/header.tsx @@ -0,0 +1,46 @@ +import { defineMessages, useIntl } from 'react-intl'; + +import { Link } from 'react-router-dom'; + +import CloseIcon from '@/material-icons/400-24px/close.svg?react'; +import { Avatar } from 'mastodon/components/avatar'; +import { DisplayName } from 'mastodon/components/display_name'; +import { IconButton } from 'mastodon/components/icon_button'; +import { useAppSelector } from 'mastodon/store'; + +const messages = defineMessages({ + close: { id: 'lightbox.close', defaultMessage: 'Close' }, +}); + +interface Props { + accountId: string; + statusId: string; + onClose: () => void; +} + +export const Header: React.FC = ({ accountId, statusId, onClose }) => { + const account = useAppSelector((state) => state.accounts.get(accountId)); + + const intl = useIntl(); + + if (!account) return null; + + return ( +
+ + + + + + +
+ ); +}; diff --git a/app/javascript/mastodon/features/picture_in_picture/index.jsx b/app/javascript/mastodon/features/picture_in_picture/index.jsx deleted file mode 100644 index f087cd1b1d1531..00000000000000 --- a/app/javascript/mastodon/features/picture_in_picture/index.jsx +++ /dev/null @@ -1,89 +0,0 @@ -import PropTypes from 'prop-types'; -import { Component } from 'react'; - -import { connect } from 'react-redux'; - -import { removePictureInPicture } from 'mastodon/actions/picture_in_picture'; -import Audio from 'mastodon/features/audio'; -import Video from 'mastodon/features/video'; - -import Footer from './components/footer'; -import Header from './components/header'; - -const mapStateToProps = state => ({ - ...state.get('picture_in_picture'), -}); - -class PictureInPicture extends Component { - - static propTypes = { - statusId: PropTypes.string, - accountId: PropTypes.string, - type: PropTypes.string, - src: PropTypes.string, - muted: PropTypes.bool, - volume: PropTypes.number, - currentTime: PropTypes.number, - poster: PropTypes.string, - backgroundColor: PropTypes.string, - foregroundColor: PropTypes.string, - accentColor: PropTypes.string, - dispatch: PropTypes.func.isRequired, - }; - - handleClose = () => { - const { dispatch } = this.props; - dispatch(removePictureInPicture()); - }; - - render () { - const { type, src, currentTime, accountId, statusId } = this.props; - - if (!currentTime) { - return null; - } - - let player; - - if (type === 'video') { - player = ( -