Compare commits

...

779 Commits

Author SHA1 Message Date
Claire
855c3be3d7 Revert "Merge upstream changes up to df72a2dbbec8173515568c02427076ebff5c2297" 2025-09-25 18:29:45 +02:00
Claire
805a19e288 Merge upstream changes up to df72a2dbbe (#3202)
* Refactor emoji GIF animation (#36165)

* New Crowdin Translations (automated) (#36228)

Co-authored-by: GitHub Actions <noreply@github.com>

* Update to puma 7 (#36238)

* Fix unfortunate action button wrapping in admin area (#36247)

* Remove the `outgoing_quotes` feature flag, making the feature unconditional (#36130)

* New Crowdin Translations (automated) (#36246)

Co-authored-by: GitHub Actions <noreply@github.com>

* Highlight newly added replies in thread view (#36237)

* Fix missed event handler (#36248)

* Implement new design for "Refetch all" (#36172)

* Fix Private Messages self-quoting private posts being changed to followers-only (#36249)

* [Glitch] Refactor emoji GIF animation

Port 6bd90940b6 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>

* [Glitch] Fix unfortunate action button wrapping in admin area

Port 6cbc857ee0 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>

* [Glitch] Remove the `outgoing_quotes` feature flag, making the feature unconditional

Port e1f7847b64 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>

* [Glitch] Highlight newly added replies in thread view

Port 059bf1e980 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>

* [Glitch] Fix missed event handler

Port 29d9f81e42 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>

* [Glitch] Implement new design for "Refetch all"

Port 3a81ee8f5b to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>

* Fix newly-highlighted replies not being interactable (#36256)

* [Glitch] Fix newly-highlighted replies not being interactable

Port df72a2dbbe to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>

---------

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
Co-authored-by: Echo <ChaosExAnima@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: GitHub Actions <noreply@github.com>
Co-authored-by: David Roetzel <david@roetzel.de>
Co-authored-by: diondiondion <mail@diondiondion.com>
2025-09-25 10:23:08 +02:00
Claire
e2a8b5c30f [Glitch] Fix newly-highlighted replies not being interactable
Port df72a2dbbe to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-24 23:03:44 +02:00
Claire
9db7ad670f Merge commit 'df72a2dbbec8173515568c02427076ebff5c2297' into glitch-soc/merge-upstream 2025-09-24 23:03:32 +02:00
Claire
df72a2dbbe Fix newly-highlighted replies not being interactable (#36256) 2025-09-24 20:37:20 +00:00
diondiondion
ea3f6ce2e5 [Glitch] Implement new design for "Refetch all"
Port 3a81ee8f5b to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-24 18:43:35 +02:00
Echo
7430d399b5 [Glitch] Fix missed event handler
Port 29d9f81e42 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-24 18:42:23 +02:00
diondiondion
26e59bec15 [Glitch] Highlight newly added replies in thread view
Port 059bf1e980 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-24 18:41:09 +02:00
Claire
500619ba4c [Glitch] Remove the outgoing_quotes feature flag, making the feature unconditional
Port e1f7847b64 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-24 18:37:55 +02:00
diondiondion
ee64228963 [Glitch] Fix unfortunate action button wrapping in admin area
Port 6cbc857ee0 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-24 18:34:02 +02:00
Echo
351dc60a2f [Glitch] Refactor emoji GIF animation
Port 6bd90940b6 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-24 18:33:26 +02:00
Claire
b15b07606c Merge commit '28be5a199f685b9fb26742c4d78ddca53df05d57' into glitch-soc/merge-upstream 2025-09-24 18:26:13 +02:00
Claire
7821634df9 Fix styling of the quote notification settings pillbar in the glitch flavor (#3187) 2025-09-24 18:24:25 +02:00
Claire
28be5a199f Fix Private Messages self-quoting private posts being changed to followers-only (#36249) 2025-09-24 10:58:52 +00:00
Claire
4eb04e96d0 Merge pull request #3200 from ClearlyClaire/glitch-soc/fixes/missing-message-quote-crash
Fix quotes crashing glitch flavor because of missing translatable message
2025-09-24 12:36:11 +02:00
diondiondion
3a81ee8f5b Implement new design for "Refetch all" (#36172) 2025-09-24 09:54:07 +00:00
Echo
29d9f81e42 Fix missed event handler (#36248) 2025-09-24 09:37:11 +00:00
diondiondion
059bf1e980 Highlight newly added replies in thread view (#36237) 2025-09-24 09:27:33 +00:00
github-actions[bot]
23a69e3bd7 New Crowdin Translations (automated) (#36246)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-09-24 09:18:50 +00:00
Claire
e1f7847b64 Remove the outgoing_quotes feature flag, making the feature unconditional (#36130) 2025-09-24 08:58:08 +00:00
diondiondion
6cbc857ee0 Fix unfortunate action button wrapping in admin area (#36247) 2025-09-24 08:57:18 +00:00
Claire
e097dbd25d Merge pull request #3197 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 24ddf80ff7
2025-09-23 21:26:19 +02:00
diondiondion
ba724f80b1 [Glitch] Add quote-related info to a post's aria-label
Port e473583da0 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-23 18:41:20 +02:00
diondiondion
4ba1ad75e0 [Glitch] Left-align boost/quote menu to prevent shift based on descriptions
Port 66afc13b7f to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-23 18:41:19 +02:00
diondiondion
986e6b1505 [Glitch] Fix line break in Read more button
Port 9bd151808c to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-23 18:41:19 +02:00
Claire
a548c5c29b Merge commit '24ddf80ff7a707bcea01a6e59831ffefe495f3e0' into glitch-soc/merge-upstream 2025-09-23 18:41:09 +02:00
David Roetzel
37cec638df Update to puma 7 (#36238) 2025-09-23 13:40:04 +00:00
github-actions[bot]
82f5901a3f New Crowdin Translations (automated) (#36228)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-09-23 09:56:46 +00:00
Echo
6bd90940b6 Refactor emoji GIF animation (#36165) 2025-09-23 08:53:14 +00:00
Claire
24ddf80ff7 Revert "Add compatibility hack for GoToSocial interaction policies (#36004)" (#36218) 2025-09-23 08:14:11 +00:00
renovate[bot]
8e6c0fdf5a chore(deps): update dependency simplecov-lcov to v0.9.0 (#35884)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-22 16:18:01 +00:00
renovate[bot]
bdadfe60cb chore(deps): update dependency ffmpeg to v8 (#35886)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-22 16:16:49 +00:00
Claire
64895e5f6d Add support for has:quote in search (#36217) 2025-09-22 16:03:22 +00:00
renovate[bot]
dc808054d2 chore(deps): update opentelemetry-ruby (non-major) (#35831)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-22 15:46:27 +00:00
renovate[bot]
4b1d7490d2 chore(deps): update devdependencies (non-major) (#35889)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-22 15:45:24 +00:00
renovate[bot]
107d2a9f93 chore(deps): update playwright to v1.55.0 (#36222)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-22 15:38:59 +00:00
renovate[bot]
6c2c485638 chore(deps): update storybook (non-major) (#36221)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Renaud Chaput <renchap@gmail.com>
2025-09-22 15:01:03 +00:00
Itoh Shimon
99d5af9914 Add Traditional Mongolian to posting languages (#36196) 2025-09-22 14:05:07 +00:00
renovate[bot]
45a044cad0 fix(deps): update dependency debug to v4.4.3 (#36058)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-22 13:57:59 +00:00
Renaud Chaput
63a2ef6274 Force playwright-ruby-client version to keep it in sync with the NPM package (#36225) 2025-09-22 13:56:08 +00:00
renovate[bot]
91e666bcaa fix(deps): update dependency postcss-preset-env to v10.4.0 (#35873)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-22 13:54:38 +00:00
renovate[bot]
da272d13e2 fix(deps): update dependency react-swipeable-views to v0.14.1 (#36208)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-22 13:53:49 +00:00
renovate[bot]
28264c5c86 fix(deps): update dependency sass to v1.93.0 (#36199)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-22 13:52:52 +00:00
renovate[bot]
0ac2d11ac8 fix(deps): update dependency @vitejs/plugin-react to v5.0.3 (#36146)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-22 13:52:26 +00:00
renovate[bot]
5f2091d8d2 fix(deps): update dependency vite to v7.1.7 (#36177)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-22 13:51:42 +00:00
diondiondion
e473583da0 Add quote-related info to a post's aria-label (#36169) 2025-09-22 13:50:29 +00:00
renovate[bot]
4a99025d02 chore(deps): update docker/dockerfile docker tag to v1.18 (#36213)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-22 13:49:30 +00:00
renovate[bot]
5398dd9ee1 fix(deps): update dependency pino to v9.11.0 (#35767)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-22 13:49:05 +00:00
Matt Jankowski
4abc442add Refer to pinnable visibilities constant from status serializer pinnable? attribute (#35852) 2025-09-22 13:45:23 +00:00
renovate[bot]
1f2a84b3d0 chore(deps): update dependency net-ldap to v0.20.0 (#35871)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-22 13:34:05 +00:00
renovate[bot]
00cc6c40eb chore(deps): update dependency annotaterb to v4.19.0 (#35943)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-22 13:16:44 +00:00
renovate[bot]
187afeaee7 chore(deps): update dependency nokogiri to v1.18.10 (#36120)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-22 13:14:38 +00:00
Renaud Chaput
b1c91d885a Remove Renovate postUpgrade commands (#36223) 2025-09-22 12:44:16 +00:00
diondiondion
66afc13b7f Left-align boost/quote menu to prevent shift based on descriptions (#36220) 2025-09-22 11:54:06 +00:00
Renaud Chaput
6689040fc6 Renovate config improvements (#36209) 2025-09-22 09:08:35 +00:00
diondiondion
9bd151808c Fix line break in Read more button (#36216) 2025-09-22 08:39:32 +00:00
github-actions[bot]
a42258eca2 New Crowdin Translations (automated) (#36198)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-09-22 07:59:19 +00:00
renovate[bot]
a95deddeab chore(deps): update dependency stoplight to v5.3.8 (#36191)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-22 07:40:55 +00:00
Claire
3b6624f97e Fix crash in “Private Mentions” column in glitch-soc (#3192)
Fixes #3190
2025-09-19 19:06:48 +02:00
Claire
67c332798e Merge pull request #3191 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 854aaec6fe
2025-09-19 18:43:26 +02:00
Claire
880e662a60 Merge commit '854aaec6fe69df02e6d850cb90eef37032b4d72f' into glitch-soc/merge-upstream 2025-09-19 18:18:56 +02:00
Matt Jankowski
854aaec6fe Spec for newline in request lib initialize (#36170) 2025-09-19 15:22:23 +00:00
David Roetzel
f316cd51c8 Enable GH actions scanning with CodeQL (#36193) 2025-09-19 13:14:24 +00:00
Claire
ea7371c183 Return 404 for quote approval when either quoted or quoting status is deleted (#36194) 2025-09-19 12:55:30 +00:00
Claire
4ff215f19b Update dependency rexml (#36192) 2025-09-19 12:19:10 +00:00
Claire
938b54dff0 Switch stoplight back to upstream releases (#36188) 2025-09-19 10:02:46 +00:00
Claire
a0a56a4c7b Fix processing of out-of-order Update as implicit updates (#36190) 2025-09-19 09:52:17 +00:00
github-actions[bot]
e45fd85436 New Crowdin Translations (automated) (#3171)
* New Crowdin translations

* Update no.yml

* Update simple_form.no.yml

---------

Co-authored-by: GitHub Actions <noreply@github.com>
Co-authored-by: Claire <claire.github-309c@sitedethib.com>
2025-09-19 10:52:27 +02:00
Claire
b6bc42aaa6 Fix getting Create and Update out of order (#36176) 2025-09-19 08:45:13 +00:00
github-actions[bot]
23efdf12cb New Crowdin Translations (automated) (#36187)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-09-19 07:58:45 +00:00
Claire
1e3832f0ec Merge pull request #3189 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 48005c55ff
2025-09-18 20:05:45 +02:00
Claire
98a148dced [Glitch] Add click-through for quoted limited accounts
Port 16a6e5c118 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-18 19:21:05 +02:00
diondiondion
c9bb7e9b26 [Glitch] Fix translate button width in Safari
Port c368a16dc1 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-18 19:20:36 +02:00
Claire
af360df59b Merge commit '48005c55fffd1540105ca53870da64f742a0f7fc' into glitch-soc/merge-upstream 2025-09-18 19:19:36 +02:00
Claire
48005c55ff Add short-time HTTP caching of quote authorizations for public posts (#36171) 2025-09-18 17:03:07 +00:00
Claire
e2171f5083 Change quoted posts from silenced accounts not to be hidden (#36166) 2025-09-18 13:21:17 +00:00
Claire
16a6e5c118 Add click-through for quoted limited accounts (#36167) 2025-09-18 12:46:31 +00:00
diondiondion
c368a16dc1 Fix translate button width in Safari (#36164) 2025-09-18 10:16:22 +00:00
github-actions[bot]
bb3f9ed13b New Crowdin Translations (automated) (#36160)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-09-18 08:17:25 +00:00
Claire
d72ae0dd70 Merge pull request #3188 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 90765342a3
2025-09-17 22:27:02 +02:00
Claire
16e479e3ec Merge commit '90765342a35abd6883e57f5419342f491b83e250' into glitch-soc/merge-upstream 2025-09-17 21:46:08 +02:00
Claire
90765342a3 Fix posts when omitting quote policy and default policy is nobody (#36158) 2025-09-17 19:16:36 +00:00
diondiondion
1e70fbfc52 [Glitch] Create reusable Alert/Snackbar component
Port 085e9ea676 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-17 20:13:51 +02:00
Claire
21cf2673f2 Merge commit '085e9ea676f11cad4ae7fafce5ceadb16ecd0f83' into glitch-soc/merge-upstream 2025-09-17 20:13:13 +02:00
Claire
3a31ef11cc Merge commit 'db0cd9489c70e985da961a585f3a809ca449dccf' into glitch-soc/merge-upstream
Conflicts:
- `app/services/post_status_service.rb`:
  Upstream updated the logic to move the CW to the text content.
  Glitch-soc does not move CW to text content but has some logic
  to avoid the text being empty. Update the logic according to upstream's
  change.
- `docker-compose.yml`:
  Conflict because of different paths for composer images.
  Updated version as upstream did while keeping our path.
2025-09-17 20:10:28 +02:00
Echo
0a6895f8b9 [Glitch] Refactor: Replace all display name usage for new component
Port dfef7d9407 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-17 19:36:18 +02:00
Claire
210786efd8 Merge commit '2664bb628b7bf77b9efa4143423486cf16d17ba7' into glitch-soc/merge-upstream 2025-09-17 18:17:18 +02:00
diondiondion
085e9ea676 Create reusable Alert/Snackbar component (#36141) 2025-09-17 15:24:39 +00:00
Claire
db0cd9489c Bump version to v4.4.4 (#36152) 2025-09-17 12:19:03 +00:00
Claire
fbf093a87f Fix CW being moved to text when posting quote posts with empty text (#36151) 2025-09-17 12:19:00 +00:00
Claire
2664bb628b Fix quote with CW but no text being shown without CW (#36150) 2025-09-17 12:00:58 +00:00
renovate[bot]
8a6ef2ebdf fix(deps): update dependency jsdom to v27 (#36107)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-17 09:46:30 +00:00
renovate[bot]
de3692ca00 chore(deps): update docker.io/ruby docker tag to v3.4.6 (#36145)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-17 09:44:16 +00:00
renovate[bot]
72fff2e54f chore(deps): update dependency ruby to v3.4.6 (#36135)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-17 09:44:12 +00:00
Echo
dfef7d9407 Refactor: Replace all display name usage for new component (#36137) 2025-09-17 09:00:57 +00:00
github-actions[bot]
ff03938808 New Crowdin Translations (automated) (#36143)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-09-17 07:27:03 +00:00
Jeong Arm
3055afd1d2 Fix applying user's default quote policy if API parameter is not specified (#36132) 2025-09-17 07:08:55 +00:00
Claire
12d61e0d84 Merge pull request #3184 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to d9b70bbde1
2025-09-16 21:58:56 +02:00
Claire
322b6d8dd5 [Glitch] Change reblog button to immediately show the interaction modal when logged out
Port d1402af0b2 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-16 18:37:00 +02:00
Claire
f659190e18 [Glitch] Change wording of disabled quote state to “You are not allowed to quote this post”
Port 41ab10f88c to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-16 18:36:27 +02:00
Claire
26193a119b Merge commit 'd9b70bbde13b78709b48be6c979bc7520e81520a' into glitch-soc/merge-upstream
Conflicts:
- `app/helpers/application_helper.rb`:
  Upstream added a helper close to a glitch-soc one.
  Added upstream's helper.
2025-09-16 18:30:30 +02:00
Eugen Rochko
d9b70bbde1 Fix login page linking to other pages within OAuth authorization flow (#36115) 2025-09-16 14:25:21 +00:00
Claire
d1402af0b2 Change reblog button to immediately show the interaction modal when logged out (#36138) 2025-09-16 12:23:44 +00:00
Claire
41ab10f88c Change wording of disabled quote state to “You are not allowed to quote this post” (#36129) 2025-09-16 10:24:58 +00:00
github-actions[bot]
96d0f6f049 New Crowdin Translations (automated) (#36133)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-09-16 09:43:02 +00:00
Claire
eeb84cbf76 Merge pull request #3180 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 38fa0102c1
2025-09-16 00:32:15 +02:00
diondiondion
882a0a1040 [Glitch] Fix logged-out quote menu UX, simplify Interaction dialog copy
Port 38fa0102c1 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-15 18:44:12 +02:00
diondiondion
504f221ec8 [Glitch] Don't show more than one quote removal hint on notifications page
Port 887e982aa2 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-15 18:42:09 +02:00
Lycolia Rizzim
bce8469c99 [Glitch] Fix: clicking a status header opens the status details, no longer navigate to profile
Port 4702e369e9 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-15 18:41:40 +02:00
diondiondion
58016b9c33 [Glitch] In composer, show when quoted post is also a quote post
Port 681a9cfda1 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-15 18:41:18 +02:00
Claire
cc52833296 Merge commit '38fa0102c111f1c0cff5a42eba6882ffae4ca109' into glitch-soc/merge-upstream 2025-09-15 18:39:09 +02:00
Claire
6c5a4702d9 Use default quote policy setting in the absence of API parameter (#36094) 2025-09-15 15:53:21 +00:00
diondiondion
38fa0102c1 Fix logged-out quote menu UX, simplify Interaction dialog copy (#36124) 2025-09-15 15:38:11 +00:00
Claire
943cdc5b21 Add example post with manual quote approval policy to dev:populate_sample_data (#36099) 2025-09-15 15:35:33 +00:00
diondiondion
887e982aa2 Don't show more than one quote removal hint on notifications page (#36128) 2025-09-15 15:27:43 +00:00
Claire
e4bb0fc43a Add server-side support for handling posts with a quote policy allowing followers to quote (#36127) 2025-09-15 15:03:44 +00:00
Claire
f5591346cc Add following_url to accounts (#36093) 2025-09-15 13:45:57 +00:00
renovate[bot]
94dcf8c96c fix(deps): update dependency axios to v1.12.0 [security] (#36116)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-15 10:02:38 +00:00
Lycolia Rizzim
4702e369e9 Fix: clicking a status header opens the status details, no longer navigate to profile (#36118) 2025-09-15 09:43:14 +00:00
diondiondion
681a9cfda1 In composer, show when quoted post is also a quote post (#36119) 2025-09-15 09:21:03 +00:00
renovate[bot]
38c0c9ba3b chore(deps): update dependency libvips to v8.17.2 (#36117)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-15 08:55:15 +00:00
github-actions[bot]
93c977eb3d New Crowdin Translations (automated) (#36105)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-09-15 08:28:25 +00:00
renovate[bot]
8e46252862 chore(deps): update dependency pundit to v2.5.1 (#36097)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-15 08:15:28 +00:00
Claire
85f414da8a Merge pull request #3179 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 06803422da
2025-09-13 13:57:25 +02:00
Claire
5da295fa4d Merge commit '06803422da3794538cd9cd5c7ccd61a0694ef921' into glitch-soc/merge-upstream 2025-09-13 11:12:22 +02:00
Echo
06803422da Make Vite respect CSP for styles (#36089) 2025-09-12 13:37:26 +00:00
Claire
82b26603fe Fix quote posts with CW and no text being rejected (#36095) 2025-09-12 13:10:31 +00:00
Eugen Rochko
30b31a89e6 Add schema.org markup to SEO-enabled posts (#36075) 2025-09-12 09:12:07 +00:00
github-actions[bot]
b59e06fba7 New Crowdin Translations (automated) (#36092)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-09-12 09:04:44 +00:00
Claire
c708f06621 Merge pull request #3178 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 45a996f12b
2025-09-12 09:39:18 +02:00
diondiondion
7cb56c7bc7 [Glitch] Fix "Post revoked" label & "Pending" tooltip text
Port 45a996f12b to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-11 21:36:02 +02:00
diondiondion
268ede0391 [Glitch] Allow removing deleted quotes from composer
Port 84d1ba980b to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-11 21:35:07 +02:00
diondiondion
d471514231 [Glitch] Update labels in Posting defaults settings
Port 872044484c to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-11 21:21:48 +02:00
Claire
9f97df84da Merge commit '45a996f12b04f88e0774bc6d6b52452ce39b612f' into glitch-soc/merge-upstream 2025-09-11 21:20:15 +02:00
diondiondion
45a996f12b Fix "Post revoked" label & "Pending" tooltip text (#36090) 2025-09-11 16:36:18 +00:00
Claire
946721fd0b Fix local quote notifications (#36091) 2025-09-11 16:32:55 +00:00
diondiondion
84d1ba980b Allow removing deleted quotes from composer (#36080) 2025-09-11 14:44:20 +00:00
diondiondion
872044484c Update labels in Posting defaults settings (#36084) 2025-09-11 14:04:15 +00:00
Claire
e35dfbfdef Fix accpeted quotes sometimes not generating notifications (#36087) 2025-09-11 12:58:25 +00:00
Claire
aacc829dc6 Fix missing memoization in Web::PushNotificationWorker (#36085) 2025-09-11 12:32:56 +00:00
Claire
c198d04a62 Merge pull request #3177 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 75f78244d5
2025-09-11 14:19:35 +02:00
Echo
261edc8b87 [Glitch] Add basic HTML parser for converting strings to React components
Port 8a0d0025ff to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-11 12:16:15 +02:00
diondiondion
5e0d346e14 [Glitch] Allow disabled dropdown menu items to be focused
Port 841212710b to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-11 12:15:08 +02:00
Claire
128a69c1f4 Merge commit '75f78244d5df52cc8242b6a7c6b8d1531963aa63' into glitch-soc/merge-upstream 2025-09-11 12:13:47 +02:00
Claire
f7289b251f Add migration to fill unset default quote policy based on default post privacy (#36041) 2025-09-11 10:11:31 +00:00
github-actions[bot]
75f78244d5 New Crowdin Translations (automated) (#36082)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-09-11 09:39:51 +00:00
Claire
b60ee191ac Fix QuoteAuthorization id not being properly serialized when federating revocation (#36083) 2025-09-11 09:37:56 +00:00
Echo
8a0d0025ff Add basic HTML parser for converting strings to React components (#36071) 2025-09-11 09:22:44 +00:00
renovate[bot]
2314583606 chore(deps): update dependency hiredis-client to v0.25.3 (#36079)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-11 08:17:58 +00:00
Claire
cf7d1822f4 Merge pull request #3176 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to eb118d8523
2025-09-10 20:26:11 +02:00
diondiondion
3f7f766e47 [Glitch] Improve accessibility of visibility modal dropdowns
Port 377e870348 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-10 18:41:21 +02:00
diondiondion
c799d73484 [Glitch] Lighten up modal background colours in light mode
Port 66d73fc213 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-10 18:38:53 +02:00
diondiondion
1bb92520d6 [Glitch] Show hint explaining post visibility when quoting a "quiet public" post
Port cf20c5db9c to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-10 18:38:27 +02:00
Claire
4b85fcabff [Glitch] Move quote post fallback removal import-time
Port 1c8990927a to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-10 18:37:11 +02:00
Claire
838d88cb8f [Glitch] Fix unresponsive areas around GIFV modals in some cases
Port 2347354bba to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-10 18:35:37 +02:00
diondiondion
4388fa1495 [Glitch] Visibility dialog: Add visual dropdown indicator to Dropdown component
Port c0af4581aa to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-10 18:34:58 +02:00
diondiondion
435f536375 [Glitch] Visibility modal: Match dropdown width to button
Port 0153b49ef7 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-10 18:34:30 +02:00
Echo
50acfc48b9 [Glitch] Remove old search results with new search
Port 24fb862a65 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-10 18:34:01 +02:00
Echo
acb2c1a635 [Glitch] Revert change to EmojiHTML
Port b99c94537b to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-10 18:33:33 +02:00
diondiondion
8ce1c8ab7c [Glitch] Fix missing icons and subtitle in mobile boost/quote menu
Port a5fbe2f5c1 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-10 18:33:13 +02:00
Claire
28d479ceb3 [Glitch] Change “Posting defaults” settings page to enforce nobody quote policy for private default visibility
Port 9463a31107 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-10 18:27:47 +02:00
Claire
1d6226f66e [Glitch] Change description of “Quiet public”
Port 7ddb8814e1 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-10 18:26:56 +02:00
Claire
06f45a2046 Merge commit 'eb118d85238da8d0583868abab2756bb329742ba' into glitch-soc/merge-upstream
Conflicts:
- `yarn.lock`:
  Upstream updated dependencies textually adjacent to glitch-soc-only ones.
  Updated them as upstream did.
2025-09-10 18:11:12 +02:00
diondiondion
841212710b Allow disabled dropdown menu items to be focused (#36078) 2025-09-10 11:32:50 +00:00
Yamagishi Kazutoshi
ffaa672fd6 Display Valkey version on admin dashboard (#35785) 2025-09-10 10:58:51 +00:00
github-actions[bot]
eb118d8523 New Crowdin Translations (automated) (#36076)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-09-10 08:42:44 +00:00
Claire
e1dc960219 Rework FEP-7888 implementation (#36064) 2025-09-09 18:27:30 +00:00
diondiondion
377e870348 Improve accessibility of visibility modal dropdowns (#36068) 2025-09-09 17:44:43 +00:00
diondiondion
66d73fc213 Lighten up modal background colours in light mode (#36069) 2025-09-09 17:43:36 +00:00
Claire
e2cbef7edb Remove unused definitions from OStatus::TagManager (#36067) 2025-09-09 13:14:35 +00:00
Renaud Chaput
beca0faed0 Upgrade transitive deps with security advisories to latest version (#36066) 2025-09-09 13:13:56 +00:00
diondiondion
cf20c5db9c Show hint explaining post visibility when quoting a "quiet public" post (#36065) 2025-09-09 12:43:23 +00:00
github-actions[bot]
3c79c512fe New Crowdin Translations (automated) (#36063)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-09-09 07:42:52 +00:00
Claire
1c8990927a Move quote post fallback removal import-time (#36055) 2025-09-08 15:31:36 +00:00
renovate[bot]
13d970b5ae chore(deps): update dependency rubyzip to v3.1.0 (#36048)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-08 14:53:51 +00:00
renovate[bot]
e7d7da9511 chore(deps): update dependency rubocop-performance to v1.26.0 (#36047)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-08 14:53:30 +00:00
Claire
2347354bba Fix unresponsive areas around GIFV modals in some cases (#36059) 2025-09-08 14:11:10 +00:00
renovate[bot]
9d0e73d308 fix(deps): update dependency vite to v7.1.5 (#36056)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-08 13:51:25 +00:00
renovate[bot]
3ca4793e68 fix(deps): update dependency sass to v1.92.1 (#36046)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-08 13:04:57 +00:00
github-actions[bot]
e9e107c5a5 New Crowdin Translations (automated) (#36045)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-09-08 13:04:38 +00:00
diondiondion
c0af4581aa Visibility dialog: Add visual dropdown indicator to Dropdown component (#36052) 2025-09-08 12:53:23 +00:00
diondiondion
0153b49ef7 Visibility modal: Match dropdown width to button (#36054) 2025-09-08 12:43:38 +00:00
Echo
24fb862a65 Remove old search results with new search (#36053) 2025-09-08 12:35:59 +00:00
Echo
b99c94537b Revert change to EmojiHTML (#36051) 2025-09-08 12:08:07 +00:00
diondiondion
a5fbe2f5c1 Fix missing icons and subtitle in mobile boost/quote menu (#36038) 2025-09-08 08:50:46 +00:00
Jesse Karmani
65b4a0a6f1 Implement FEP 7888: Part 1 - publish conversation context (#35959) 2025-09-05 19:28:29 +00:00
Claire
9463a31107 Change “Posting defaults” settings page to enforce nobody quote policy for private default visibility (#36040) 2025-09-05 18:51:08 +00:00
Claire
7ddb8814e1 Change description of “Quiet public” (#36032) 2025-09-05 18:35:34 +00:00
Claire
a317bde6b8 [Glitch] Change “Boost with original visibility” to “Share again with your followers”
Port de09e33c92 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-05 20:32:34 +02:00
Claire
31df462f51 [Glitch] Fix missing beforeUnload confirmation when a quote post is being authored
Port 9a2be25199 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-05 20:32:34 +02:00
Claire
6335f3263d [Glitch] Fix missing beforeUnload confirmation when a poll is being authored
Port 0d93801bde to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-05 20:32:33 +02:00
diondiondion
cda2119af8 [Glitch] Add first-time user education hint about quote removal on Quote notifications
Port e7c30cd072 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-05 20:32:33 +02:00
Echo
fc3b4d9cc9 [Glitch] Adds DisplayName component
Port 42be0ca0eb to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-05 20:08:46 +02:00
diondiondion
7441f21b18 [Glitch] Add new plain (text-only) button variant
Port bc952ebde9 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-05 20:05:57 +02:00
Claire
6fc9febb47 Merge commit '1b664cf20dbb696cf16a42efcf59ab186cb211eb' into glitch-soc/merge-upstream 2025-09-05 20:03:42 +02:00
Matt Jankowski
1b664cf20d Relay reset delivery tracker model spec and callback (#36027) 2025-09-05 12:56:15 +00:00
Matt Jankowski
05a655f33e Convert age verification controller to system specs (#36026) 2025-09-05 12:44:09 +00:00
Matt Jankowski
3efba15b3c Use pluck on DomainAllow.allowed_domains for export (#36019) 2025-09-05 12:30:18 +00:00
Matt Jankowski
350a802851 Remove unused _index iterator in admin partial (#36018) 2025-09-05 12:29:11 +00:00
Claire
de09e33c92 Change “Boost with original visibility” to “Share again with your followers” (#36035) 2025-09-05 08:59:16 +00:00
Claire
9a2be25199 Fix missing beforeUnload confirmation when a quote post is being authored (#36034) 2025-09-05 08:51:49 +00:00
Claire
279405f2a7 Fix incorrect change of unlisted source strings (#36033) 2025-09-05 08:34:14 +00:00
Claire
497bfbc483 Fix source string for visibility dropdown hint (#36031) 2025-09-05 08:14:34 +00:00
github-actions[bot]
dd6bd681ea New Crowdin Translations (automated) (#36029)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-09-05 08:14:25 +00:00
Claire
0d93801bde Fix missing beforeUnload confirmation when a poll is being authored (#36030) 2025-09-05 08:07:59 +00:00
diondiondion
e7c30cd072 Add first-time user education hint about quote removal on Quote notifications (#35986) 2025-09-04 13:01:12 +00:00
Echo
42be0ca0eb Adds DisplayName component (#35985) 2025-09-04 10:09:27 +00:00
renovate[bot]
d7d83d44e6 fix(deps): update dependency @reduxjs/toolkit to v2.9.0 (#36000)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-04 09:44:17 +00:00
github-actions[bot]
5cb85acf2b New Crowdin Translations (automated) (#36015)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-09-04 09:41:16 +00:00
Matt Jankowski
27969c3077 Update rubocop to version 1.80.2 (#36007) 2025-09-04 08:14:01 +00:00
Emelia Smith
4c2a2c27c1 Automatically remove invalid Web::PushSubscriptions (#35987) 2025-09-04 08:00:44 +00:00
Claire
14cb5ff881 Add compatibility hack for GoToSocial interaction policies (#36004) 2025-09-03 19:35:43 +00:00
Claire
372b746dbf Merge pull request #3173 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 624c024766
2025-09-03 17:58:58 +02:00
Claire
705ea99136 Merge commit '624c024766227255c78d31bd408876c64a8b279f' into glitch-soc/merge-upstream
Conflicts:
- `app/helpers/formatting_helper.rb`:
  Upstream added an optional keyword argument where glitch-soc already had one for content-type.
  Added upstream's new option while keeping glitch-soc's.
2025-09-03 14:39:57 +02:00
diondiondion
bc952ebde9 Add new plain (text-only) button variant (#36002) 2025-09-03 12:34:29 +00:00
renovate[bot]
c1542643f5 fix(deps): update dependency sass to v1.92.0 (#36001)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-03 12:23:00 +00:00
Claire
624c024766 Prepend “RE: <url>” fallback link to Mastodon-authored quote posts (#35971) 2025-09-03 09:35:44 +00:00
github-actions[bot]
927468bce5 New Crowdin Translations (automated) (#35999)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-09-03 07:57:33 +00:00
Claire
eeb80a926c Merge pull request #3172 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 75fca715e9
2025-09-02 22:48:32 +02:00
Claire
6a71fffadf [Glitch] Change public self-quotes of private posts to be disallowed
Port 75fca715e9 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-02 19:19:48 +02:00
Claire
a06e96f99e [Glitch] Change icon variant for quotes
Port 5d9a9c76fb to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-02 19:18:40 +02:00
Claire
160c29b073 [Glitch] Change wording on quote label when disabled
Port 0e5cac8c8b to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-02 19:17:01 +02:00
Bruno Viveiros
a5662c71db [Glitch] fix: YouTube iframe being able to start at a defined time
Port bdff970a5e to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-02 19:16:37 +02:00
Emelia Smith
c5867cc98d [Glitch] Move 'add more' inside table toolbar on reports
Port 2138f3e40f to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-02 19:15:44 +02:00
Emelia Smith
ae6613db55 [Glitch] Fix batch table toolbar displaying under status media
Port 314d5f0d7a to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-02 19:14:55 +02:00
Emelia Smith
aadbfbb315 [Glitch] Support displaying polls in Admin UI
Port 15401e6988 to glitch-soc

Co-authored-by: Claire <claire.github-309c@sitedethib.com>
Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-02 19:14:11 +02:00
diondiondion
1db5d85d20 [Glitch] Update Visibility modal copy & preferences link
Port 6f8187e595 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-09-02 19:12:23 +02:00
Claire
d5b959a2ca Merge commit '75fca715e9ae8ad347edbaf6511a052f161a3de3' into glitch-soc/merge-upstream
Conflicts:
- `app/views/settings/preferences/other/show.html.haml`:
  Upstream moved some preferences to a new category, while glitch-soc had an
  extra preference there.
  Moved the extra preference like upstream did to the new category.
2025-09-02 19:07:51 +02:00
Claire
75fca715e9 Change public self-quotes of private posts to be disallowed (#35975) 2025-09-02 15:48:37 +00:00
Claire
5d9a9c76fb Change icon variant for quotes (#35991) 2025-09-02 13:52:09 +00:00
Claire
0e5cac8c8b Change wording on quote label when disabled (#35990) 2025-09-02 13:41:31 +00:00
fiona
e665cc68f4 Fix handling of edited status with new media and no text (#35970) 2025-09-02 12:25:55 +00:00
Bruno Viveiros
bdff970a5e fix: YouTube iframe being able to start at a defined time (#26584) 2025-09-02 10:04:59 +00:00
renovate[bot]
bf860c39c2 Update dependency vite to v7.1.4 (#35983)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-02 09:21:31 +00:00
renovate[bot]
b829d89757 Update dependency use-debounce to v10.0.6 (#35982)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-02 08:29:24 +00:00
renovate[bot]
5844fd3e3d Update dependency pg to v1.6.2 (#35981)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-02 08:11:39 +00:00
renovate[bot]
f51b733109 Update dependency connection_pool to v2.5.4 (#35980)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-02 08:11:28 +00:00
Emelia Smith
2138f3e40f Move 'add more' inside table toolbar on reports (#35963) 2025-09-02 07:54:58 +00:00
github-actions[bot]
fb736eaed5 New Crowdin Translations (automated) (#35979)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-09-02 07:41:43 +00:00
Matt Jankowski
786891c333 Remove unused local vars from user mailer warning (#35977) 2025-09-02 07:35:53 +00:00
Eugen Rochko
7fc884ba00 Fix banned text being able to be circumvented via unicode (#35978) 2025-09-02 07:29:03 +00:00
Claire
6e09dd10a7 Fix stale interaction counts being served for quotes over streaming (#35967) 2025-09-01 20:12:20 +00:00
Emelia Smith
314d5f0d7a Fix batch table toolbar displaying under status media (#35962) 2025-09-01 16:02:31 +00:00
Emelia Smith
15401e6988 Support displaying polls in Admin UI (#35933)
Co-authored-by: Claire <claire.github-309c@sitedethib.com>
2025-09-01 14:59:03 +00:00
diondiondion
6f8187e595 Update Visibility modal copy & preferences link (#35969) 2025-09-01 11:17:27 +00:00
Claire
ab698ff521 Move posting defaults to their own preferences sub-category (#35966) 2025-09-01 08:31:07 +00:00
renovate[bot]
f21d9f64db Update Node.js to 22.19 (#35954)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-01 07:21:09 +00:00
github-actions[bot]
e95e6064ae New Crowdin Translations (automated) (#35960)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-09-01 07:20:25 +00:00
Matt Jankowski
70da14871f Remove unused require of rubygems/package from ip blocks CLI class (#35957) 2025-09-01 06:23:39 +00:00
github-actions[bot]
c3b1dc4b1c New Crowdin Translations (automated) (#3103)
* New Crowdin translations

* Update no.yml

* Update simple_form.no.yml

---------

Co-authored-by: GitHub Actions <noreply@github.com>
Co-authored-by: Claire <claire.github-309c@sitedethib.com>
2025-08-31 16:16:20 +02:00
Claire
65723e791f Merge pull request #3170 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 40242fafee
2025-08-30 16:14:14 +02:00
Claire
a0763483b0 [Glitch] Rename unknown quote policy value to unsupported_policy
Port 4fa203e69e to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-29 18:24:50 +02:00
Kazuki Nagasawa
bf3c53661a [Glitch] Fix 404 error after deleting status from detail view
Port d93572ea90 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-29 18:24:23 +02:00
Claire
6abe6cdef5 Merge commit '40242fafee83cf9a6bcb2d0ac1e228827969402f' into glitch-soc/merge-upstream 2025-08-29 18:21:28 +02:00
Matt Jankowski
40242fafee Use partial for severed relationship download area (#35945) 2025-08-29 15:19:59 +00:00
Matt Jankowski
ee4b0a223c Add coverage for Relay model (#35950) 2025-08-29 15:18:52 +00:00
ioflow
3c578dbdcd Fix incorrect RSS feed MIME type in gzip_types directive (#35562) 2025-08-29 14:17:04 +00:00
Claire
4fa203e69e Rename unknown quote policy value to unsupported_policy (#35955) 2025-08-29 13:50:37 +00:00
Claire
8b7685d956 Add default quote policy to API (#35948) 2025-08-29 11:37:20 +00:00
Claire
4ecbaea8bb Conditionally bump API version depending on quote post feature flag (#35939) 2025-08-29 10:33:35 +00:00
Matt Jankowski
5f1e6a5886 Fix failure to verify changes in api/v1/accounts/credentials spec (#35951) 2025-08-29 08:14:23 +00:00
github-actions[bot]
97d80265b4 New Crowdin Translations (automated) (#35953)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-08-29 07:32:22 +00:00
Kazuki Nagasawa
d93572ea90 Fix 404 error after deleting status from detail view (#35800) (#35881) 2025-08-28 20:50:19 +00:00
Claire
3b6afadf55 Merge pull request #3169 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to d880f397df
2025-08-28 21:47:42 +02:00
diondiondion
5db1bbef69 [Glitch] Add hotkey Q for quoting the currently focused post
Port 229cbc6a24 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-28 20:36:00 +02:00
Claire
c1159fa712 [Glitch] Accomodate longer text in quote/reblog dropdown
Port b6cd32281f to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-28 20:24:46 +02:00
Claire
03e07d88d7 Merge commit 'd880f397dfbe95bb8c3c9ed5730fbba76398df5f' into glitch-soc/merge-upstream 2025-08-28 20:23:39 +02:00
renovate[bot]
d880f397df Update dependency @vitejs/plugin-react to v5.0.2 (#35942)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-28 14:04:38 +00:00
renovate[bot]
3ab2d14782 Update Yarn to v4.9.4 (#35837)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-28 12:39:01 +00:00
diondiondion
229cbc6a24 Add hotkey Q for quoting the currently focused post (#35941) 2025-08-28 12:33:23 +00:00
github-actions[bot]
dccd29fe25 New Crowdin Translations (automated) (#35936)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-08-28 08:47:16 +00:00
Claire
e109917119 Merge pull request #3168 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 02de05dc27
2025-08-27 20:06:34 +02:00
Claire
b6cd32281f Accomodate longer text in quote/reblog dropdown (#35930) 2025-08-27 17:20:02 +00:00
Claire
971d8af8e3 [Glitch] Add ability to list quotes of one's own posts
Port 02de05dc27 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-27 18:36:29 +02:00
Claire
9c662f83d2 [Glitch] Fix API return types for interaction API helpers
Port 66f5ad42e2 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-27 18:21:13 +02:00
Claire
a68dc4ab7a [Glitch] Enable quotes of manually-reviewed quotes with a different label
Port 9c55b2fbe4 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-27 18:17:40 +02:00
Claire
e7890c0153 [Glitch] Fix streaming and handling of quoted_update notifications
Port a6a0d982ef to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-27 18:17:13 +02:00
diondiondion
9f710449db [Glitch] Fix error alerts for deleted quotes
Port 4180f754d0 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-27 18:16:29 +02:00
Claire
884d7996b1 Merge commit '02de05dc272856c77fac5c9e1d84cf585ae20c1e' into glitch-soc/merge-upstream 2025-08-27 18:13:03 +02:00
Claire
02de05dc27 Add ability to list quotes of one's own posts (#35914) 2025-08-27 15:38:52 +00:00
Claire
9c55b2fbe4 Enable quotes of manually-reviewed quotes with a different label (#35925) 2025-08-27 14:55:39 +00:00
Claire
a6a0d982ef Fix streaming and handling of quoted_update notifications (#35924) 2025-08-27 14:53:54 +00:00
Matt Jankowski
c2b7b28919 Use strict locals and remove unused value in card partial (#35919) 2025-08-27 13:22:39 +00:00
Matt Jankowski
5cb7dfafcc Move lengthy ruby logic from mailer view to helper (#35911) 2025-08-27 13:15:33 +00:00
Matt Jankowski
35a06319fa Rely on mail_to helper default name arg value (#35913) 2025-08-27 13:05:13 +00:00
renovate[bot]
6f34db9bb7 Update dependency sass to v1.91.0 (#35906)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-27 12:51:06 +00:00
Matt Jankowski
3f1d78f3c6 Use target account from group_by result in admin/reports/index (#35920) 2025-08-27 12:50:16 +00:00
Claire
c00ed9c913 Add digest re-check before removing followers in synchronization mechanism (#34273) 2025-08-27 12:12:55 +00:00
Claire
b1e2f70934 Merge pull request #3167 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 6ad0ddebe4
2025-08-27 11:41:53 +02:00
Claire
66f5ad42e2 Fix API return types for interaction API helpers (#35915) 2025-08-27 08:13:34 +00:00
github-actions[bot]
8dcd195527 New Crowdin Translations (automated) (#35922)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-08-27 08:13:21 +00:00
Claire
f825b0cfa4 [Glitch] Fix WebUI fetching deleted quote in an endless loop
Port 3c9bde31f7 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-26 19:20:30 +02:00
Claire
0710138578 [Glitch] Add quoted_update notification type
Port f3a932d8a1 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-26 19:20:18 +02:00
Claire
7e25f6b606 Merge commit '6ad0ddebe4be9fb76b9119924674b4679e8da74a' into glitch-soc/merge-upstream 2025-08-26 19:07:52 +02:00
diondiondion
4180f754d0 Fix error alerts for deleted quotes (#35918) 2025-08-26 16:34:14 +00:00
Claire
6ad0ddebe4 Fix quotes counting (#35917) 2025-08-26 15:51:56 +00:00
Claire
676300789e Merge pull request #3166 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 7aba79ade9
2025-08-26 17:06:23 +02:00
Claire
3c9bde31f7 Fix WebUI fetching deleted quote in an endless loop (#35909) 2025-08-26 10:07:02 +00:00
Matt Jankowski
a8166d28ed Add coverage for "live TOS" and "no TOS" paths in tos/drafts spec (#35902) 2025-08-26 08:43:43 +00:00
github-actions[bot]
460043a969 New Crowdin Translations (automated) (#35908)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-08-26 08:40:16 +00:00
Matt Jankowski
4f41b7c089 Relax hard-coded attr names in system specs (#35903) 2025-08-26 08:23:45 +00:00
Claire
33085d9cf5 Get rid of leftover file 2025-08-25 22:24:58 +02:00
Claire
a17db258ea [Glitch] Ensure quote policy is displayed as “Just me” when disabled because of visibility
Port 7a76f71d99 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-25 22:22:52 +02:00
Claire
c2c0b4f347 [Glitch] Consolidate labels for quote policy settings
Port 012450e87d to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-25 22:21:30 +02:00
Claire
24e2bd2d6c [Glitch] Fix Edit as well as “Delete & Redraft” on a poll not inserting empty option
Port d8c07be021 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-25 22:20:46 +02:00
Claire
7fcd9184d2 [Glitch] Add quotes_count to statuses stats
Port 2560242972 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-25 22:18:08 +02:00
diondiondion
2b00895179 [Glitch] Fix broken custom radio buttons & checkboxes in modals
Port 94ad088482 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-25 22:17:33 +02:00
Claire
e8fe33f273 Merge commit '7aba79ade9bfeb86105aa575bc7156acef78f7da' into glitch-soc/merge-upstream
Conflicts:
- `app/views/layouts/application.html.haml`:
  Conflict because of glitch-soc's theming system.
  Updated the line as upstream did.
2025-08-25 22:15:28 +02:00
Matt Jankowski
4738a18e52 Use default action of persisted records on edit forms (#35904) 2025-08-25 17:26:25 +00:00
Claire
3c17ccab37 Rearrange posting defaults settings (#35896) 2025-08-25 15:50:22 +00:00
Claire
496370801a Add quotes_count to serializer specs (#35901) 2025-08-25 15:49:52 +00:00
Claire
f3a932d8a1 Add quoted_update notification type (#35820) 2025-08-25 15:44:18 +00:00
Claire
7aba79ade9 Fix quotes_count attribute on Status not being serialized (#35895) 2025-08-25 14:33:25 +00:00
Claire
7a76f71d99 Ensure quote policy is displayed as “Just me” when disabled because of visibility (#35894) 2025-08-25 13:08:37 +00:00
Claire
012450e87d Consolidate labels for quote policy settings (#35893) 2025-08-25 12:30:37 +00:00
Claire
d8c07be021 Fix Edit as well as “Delete & Redraft” on a poll not inserting empty option (#35892) 2025-08-25 12:25:35 +00:00
Claire
2560242972 Add quotes_count to statuses stats (#35832) 2025-08-25 12:21:28 +00:00
diondiondion
94ad088482 Fix broken custom radio buttons & checkboxes in modals (#35891) 2025-08-25 09:12:46 +00:00
github-actions[bot]
b771fc0880 New Crowdin Translations (automated) (#35878)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-08-25 06:54:53 +00:00
Shlee
61a21d6a36 Add crossorigin back to inert css (regression? of #30687) (#35876) 2025-08-25 06:54:47 +00:00
renovate[bot]
d85743576c Update dependency vite-plugin-svgr to v4.5.0 (#35885)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-25 06:46:10 +00:00
renovate[bot]
a1ca52ed8f Update dependency @types/react to v18.3.24 (#35888)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-25 06:43:24 +00:00
Claire
95709ce88b Merge pull request #3165 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to f6e822e1f5
2025-08-24 21:50:33 +02:00
Claire
a44b4e220e Merge commit 'f6e822e1f5c18553db246991ebfb8658acaef59f' into glitch-soc/merge-upstream 2025-08-24 11:43:25 +02:00
Claire
c0a48f082c Merge upstream changes up to abe5413638 (#3164)
* Update dependency vite-plugin-pwa to v1.0.3 (#35830)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* New Crowdin Translations (automated) (#35829)

Co-authored-by: GitHub Actions <noreply@github.com>

* Status quote button (#35822)

* Use `debug?` query method on httplog initializer check (#35833)

* Fix display of quotes in threads in WebUI (#35834)

* Update dependency ruby-vips to v2.2.5 (#35836)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Disable `Metrics/*` cops (#35000)

* Update dependency core-js to v3.45.1 (#35843)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* New Crowdin Translations (automated) (#35844)

Co-authored-by: GitHub Actions <noreply@github.com>

* Update dependency vite-plugin-static-copy to v3.1.2 (#35846)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Update dependency rubyzip to v3.0.2 (#35845)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Composer quote improvements (#35835)

Co-authored-by: Claire <claire.github-309c@sitedethib.com>
Co-authored-by: diondiondion <mail@diondiondion.com>

* Refactor to reuse the one status partial across moderation tools (#35644)

* Fix layout shift caused by "Who to follow" widget (#35861)

* Improvements for keyboard navigation in feeds (#35853)

* Improve feed item focus outlines (#35864)

* Visibility Modal fixes (#35865)

* New Crowdin Translations (automated) (#35859)

Co-authored-by: GitHub Actions <noreply@github.com>

* [Glitch] Status quote button

Port 8268323d7f to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>

* [Glitch] Fix display of quotes in threads in WebUI

Port 45ec4c93c0 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>

* [Glitch] Composer quote improvements

Port f85f0eee1b to glitch-soc

Co-authored-by: Claire <claire.github-309c@sitedethib.com>
Co-authored-by: diondiondion <mail@diondiondion.com>
Signed-off-by: Claire <claire.github-309c@sitedethib.com>

* [Glitch] Refactor to reuse the one status partial across moderation tools

Port 4f494781c1 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>

* [Glitch] Fix layout shift caused by "Who to follow" widget

Port 511e10df34 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>

* [Glitch] Improvements for keyboard navigation in feeds

Port 118c30fbc7 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>

* [Glitch] Improve feed item focus outlines

Port a1c7b853ec to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>

* [Glitch] Visibility Modal fixes

Port 4df50b9c7e to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>

---------

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: GitHub Actions <noreply@github.com>
Co-authored-by: Echo <ChaosExAnima@users.noreply.github.com>
Co-authored-by: Matt Jankowski <matt@jankowski.online>
Co-authored-by: diondiondion <mail@diondiondion.com>
Co-authored-by: Emelia Smith <ThisIsMissEm@users.noreply.github.com>
2025-08-24 11:42:35 +02:00
Claire
f6e822e1f5 Fix issue with Stoplight 5.3 and DragonflyDB (#35868) 2025-08-22 23:59:25 +00:00
Claire
3fd629cf84 Do not mark remote quotes of local posts as approved before request (#35860) 2025-08-22 23:59:18 +00:00
Matt Jankowski
20bc34ca52 Rely on pluck for the SELECT in RuleTranslation.languages (#35826) 2025-08-22 23:58:40 +00:00
Echo
3cc6f8813a [Glitch] Visibility Modal fixes
Port 4df50b9c7e to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-22 23:12:02 +02:00
diondiondion
f7cd193390 [Glitch] Improve feed item focus outlines
Port a1c7b853ec to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-22 23:11:22 +02:00
diondiondion
e9c1ffeb9a [Glitch] Improvements for keyboard navigation in feeds
Port 118c30fbc7 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-22 23:08:56 +02:00
diondiondion
bae04bd303 [Glitch] Fix layout shift caused by "Who to follow" widget
Port 511e10df34 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-22 23:03:39 +02:00
Emelia Smith
b52b744e6d [Glitch] Refactor to reuse the one status partial across moderation tools
Port 4f494781c1 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-22 23:00:33 +02:00
Echo
be78b64948 [Glitch] Composer quote improvements
Port f85f0eee1b to glitch-soc

Co-authored-by: Claire <claire.github-309c@sitedethib.com>
Co-authored-by: diondiondion <mail@diondiondion.com>
Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-22 22:58:39 +02:00
Claire
5cac4dfb5c Merge commit 'abe5413638043a52e4fcbb5f16aefd14e76bf96c' into glitch-soc/merge-upstream 2025-08-22 22:52:55 +02:00
Claire
0a0f57f3ec [Glitch] Fix display of quotes in threads in WebUI
Port 45ec4c93c0 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-22 22:46:03 +02:00
Echo
4e7b270365 [Glitch] Status quote button
Port 8268323d7f to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-22 22:45:40 +02:00
Claire
02134172f1 Merge commit 'e770303968dc04d20dd5f3a5d7da3b9d7ba888fc' into glitch-soc/merge-upstream
Conflicts:
- `.rubocop_todo.yml`:
  Glitch-soc had different overrides, but upstream simply disabled the rules.
  Disabled them as well.
- `app/serializers/initial_state_serializer.rb`:
  Not really a conflict, again because of a rubocop comment.
2025-08-22 22:33:11 +02:00
Claire
48a71e6ad2 Change glitch flavor to show approximate reply count by default (#3157) 2025-08-22 22:29:21 +02:00
github-actions[bot]
abe5413638 New Crowdin Translations (automated) (#35859)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-08-22 14:53:27 +00:00
Echo
4df50b9c7e Visibility Modal fixes (#35865) 2025-08-22 12:34:37 +00:00
diondiondion
a1c7b853ec Improve feed item focus outlines (#35864) 2025-08-22 12:10:07 +00:00
diondiondion
118c30fbc7 Improvements for keyboard navigation in feeds (#35853) 2025-08-22 09:57:39 +00:00
diondiondion
511e10df34 Fix layout shift caused by "Who to follow" widget (#35861) 2025-08-22 09:44:10 +00:00
Emelia Smith
4f494781c1 Refactor to reuse the one status partial across moderation tools (#35644) 2025-08-21 14:51:11 +00:00
Echo
f85f0eee1b Composer quote improvements (#35835)
Co-authored-by: Claire <claire.github-309c@sitedethib.com>
Co-authored-by: diondiondion <mail@diondiondion.com>
2025-08-21 14:07:31 +00:00
renovate[bot]
e770303968 Update dependency rubyzip to v3.0.2 (#35845)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-21 11:40:40 +00:00
renovate[bot]
23de9c7e6c Update dependency vite-plugin-static-copy to v3.1.2 (#35846)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-21 11:33:11 +00:00
github-actions[bot]
f696f794cf New Crowdin Translations (automated) (#35844)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-08-21 07:42:45 +00:00
renovate[bot]
83f151947e Update dependency core-js to v3.45.1 (#35843)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-21 07:29:58 +00:00
Matt Jankowski
20a71a5479 Disable Metrics/* cops (#35000) 2025-08-20 17:04:36 +00:00
renovate[bot]
181134153d Update dependency ruby-vips to v2.2.5 (#35836)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-20 15:31:58 +00:00
Claire
45ec4c93c0 Fix display of quotes in threads in WebUI (#35834) 2025-08-20 14:39:58 +00:00
Matt Jankowski
50cf327819 Use debug? query method on httplog initializer check (#35833) 2025-08-20 12:06:35 +00:00
Echo
8268323d7f Status quote button (#35822) 2025-08-20 10:09:57 +00:00
github-actions[bot]
54da7ff12b New Crowdin Translations (automated) (#35829)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-08-20 08:31:57 +00:00
renovate[bot]
e28fe4199d Update dependency vite-plugin-pwa to v1.0.3 (#35830)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-20 08:09:02 +00:00
Claire
183e9d953b Merge pull request #3162 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 8d3bca3bb8
2025-08-19 21:43:34 +02:00
Claire
b7c9b881e3 Merge commit '8d3bca3bb8c84e1e3735eb71bdce7acac3779bff' into glitch-soc/merge-upstream 2025-08-19 21:01:33 +02:00
Claire
c0aa21f4ad Merge pull request #3161 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to f16f8b51b8
2025-08-19 21:00:46 +02:00
Echo
72035d5faa [Glitch] Move language and visibility buttons above CW field
Port f16f8b51b8 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-19 19:14:23 +02:00
Echo
43034790a6 [Glitch] Composer Quote UI
Port d4b2e7f771 to glitch-soc

Co-authored-by: diondiondion <mail@diondiondion.com>
Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-19 19:13:58 +02:00
Claire
8d3bca3bb8 Fix serialization of quote policies in nested quotes (#35828) 2025-08-19 17:13:43 +00:00
Claire
71cee3e472 Merge commit 'f16f8b51b863d3fcadd17753004adbf8962ead01' into glitch-soc/merge-upstream
Conflicts:
- `yarn.lock`:
  Upstream updated a dependency adjacent to one that is only in glitch-soc.
  Updated as upstream did.
2025-08-19 18:46:12 +02:00
Echo
f16f8b51b8 Move language and visibility buttons above CW field (#35824) 2025-08-19 15:29:10 +00:00
Claire
831a24ae15 Fix self-destruct scheduler behavior on some Redis setups (#35823) 2025-08-19 14:16:30 +00:00
Claire
736751e5de Change indexes on quotes to efficiently list quotes of a given account or quoted status (#35819) 2025-08-19 12:50:30 +00:00
renovate[bot]
421dbf9a7f Update opentelemetry-ruby (non-major) (#35784)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-19 07:07:46 +00:00
renovate[bot]
7ac16582be Update dependency prometheus_exporter to v2.3.0 (#35791)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-19 07:07:26 +00:00
renovate[bot]
5d24cb7514 Update dependency @vitejs/plugin-react to v5.0.1 (#35817)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-19 06:51:08 +00:00
renovate[bot]
a81b6beeca Update dependency vite to v7.1.3 (#35818)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-19 06:51:05 +00:00
github-actions[bot]
10dc66be64 New Crowdin Translations (automated) (#35816)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-08-19 06:49:37 +00:00
Matt Jankowski
ce813ad144 Avoid method that makes tokens while checking for tokens (#35815) 2025-08-19 06:49:34 +00:00
Claire
76b7092062 Merge pull request #3160 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 255d8f3f8c
2025-08-18 22:56:03 +02:00
Alan
903eefd420 [Glitch] Update color alpha blending to use Sass color functions
Port 95111e88e3 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-18 22:12:05 +02:00
Claire
9871aeed20 [Glitch] Fix “Delete & Redraft” as well as “Edit” unexpectedly reseting quote policy
Port c2fcf4183c to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-18 22:06:33 +02:00
Claire
4ffcf7f7ed Merge commit '255d8f3f8c6ece6a9f1fce9ea901d71577b92099' into glitch-soc/merge-upstream 2025-08-18 22:05:19 +02:00
Echo
d4b2e7f771 Composer Quote UI (#35805)
Co-authored-by: diondiondion <mail@diondiondion.com>
2025-08-18 16:52:28 +00:00
Michael Stanclift
28bf811a07 Update Dockerfile to use Debian 'trixie' (#35768) 2025-08-18 16:45:31 +00:00
Claire
255d8f3f8c Fix e-mail confirmation bypassing username approval (#35806) 2025-08-18 16:37:13 +00:00
Alan
95111e88e3 Update color alpha blending to use Sass color functions (#35787) 2025-08-18 15:55:38 +00:00
Claire
c2fcf4183c Fix “Delete & Redraft” as well as “Edit” unexpectedly reseting quote policy (#35808) 2025-08-18 14:51:16 +00:00
Evаn Summers
f5754f2a36 Mention admin@localhost in DEVELOPMENT.md for non-Vagrant setups (#35704) 2025-08-18 14:13:44 +00:00
Claire
7ea5f622d3 Merge pull request #3159 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 72bd1ed4b3
2025-08-18 15:42:55 +02:00
Claire
8d602df786 Merge commit '72bd1ed4b3df9188a1ad3e664c86fe2e928bd134' into glitch-soc/merge-upstream 2025-08-18 13:44:06 +02:00
Claire
59dbb17bfa Merge pull request #3158 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream 651e51a82e
2025-08-18 13:43:17 +02:00
Claire
72bd1ed4b3 Fix updates to quote policy not being federated (#35804) 2025-08-18 08:34:45 +00:00
Matt Jankowski
9d15b85d3b Include update in the resources args for api/web/push_subscriptions route (#35801) 2025-08-18 07:35:56 +00:00
github-actions[bot]
a18e6199ef New Crowdin Translations (automated) (#35795)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-08-18 07:03:54 +00:00
renovate[bot]
83fcd1cf4f Update dependency rails-i18n to v8.0.2 (#35796)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-18 07:01:07 +00:00
Claire
1904d9617d Fix SCSS formatting 2025-08-17 21:17:06 +02:00
Echo
2a593bd89e [Glitch] Allow editing status quote policy
Port 651e51a82e to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-17 21:17:06 +02:00
Echo
8a7324d114 [Glitch] Move composer buttons to top
Port 49a6e4cbb5 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-17 21:17:06 +02:00
Echo
6c8a478273 [Glitch] Redirect on success for standalone compose
Port 7cf53dbf63 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-17 21:17:06 +02:00
Claire
80bc5ab5ef [Glitch] Fix reply indicator displaying wrong avatar in rare cases
Port 63d3f28b20 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-17 20:58:11 +02:00
Echo
fd2420891c [Glitch] Prevent props being added as HTML attributes
Port bf15b1d65d to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-17 20:57:18 +02:00
Claire
4d9150735a Merge commit '651e51a82eba542c4d8c3fec5edd16420ea1ff3e' into glitch-soc/merge-upstream
Conflicts:
- `yarn.lock`:
  Upstream updated a dependency textually adjacent to a glitch-soc-specific one.
  Updated the dependency as upstream did.
2025-08-17 20:52:34 +02:00
Claire
add059205f Merge pull request #3156 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to ce1680e6f9
2025-08-17 20:50:16 +02:00
github-actions[bot]
25f1a515f8 New Crowdin Translations (automated) (#35788)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-08-15 07:12:01 +00:00
Matt Jankowski
4de21056ff Update sidekiq to version 8.0.7 (#34824) 2025-08-14 15:25:31 +00:00
Echo
651e51a82e Allow editing status quote policy (#35762) 2025-08-14 15:04:32 +00:00
Claire
a2cddb9eac Disallow making private posts quotable (#35780) 2025-08-14 13:58:25 +00:00
Claire
b0ce1ce49d Fix tootctl admin create not bypassing reserved username checks (#35779) 2025-08-14 13:35:19 +00:00
renovate[bot]
ac0581fd22 Update devDependencies (non-major) (#35660)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Renaud Chaput <renchap@gmail.com>
2025-08-14 08:36:38 +00:00
Matt Jankowski
93923a4af2 First pass coverage addition for antispam class (#35771) 2025-08-14 07:57:18 +00:00
renovate[bot]
9fc81adc7b Update opentelemetry-ruby (non-major) (#35777)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-14 07:51:51 +00:00
renovate[bot]
734dbbcb14 Update dependency rubocop-rails to v2.33.3 (#35766)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-14 07:35:12 +00:00
renovate[bot]
2112416761 Update dependency @rails/ujs to v7.1.502 (#35772)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-14 07:34:30 +00:00
renovate[bot]
c0f64a6603 Update dependency rails to v8.0.2.1 (#35776)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-14 07:34:27 +00:00
Claire
e2e19544ae Update Vagrantfile (#35765) 2025-08-13 20:45:10 +00:00
Claire
2648bbdc51 Add PUT /api/v1/statuses/:status_id/interaction_policy (#35769) 2025-08-13 15:51:16 +00:00
Echo
49a6e4cbb5 Move composer buttons to top (#35749) 2025-08-13 14:09:45 +00:00
Echo
7cf53dbf63 Redirect on success for standalone compose (#35763) 2025-08-13 13:52:29 +00:00
renovate[bot]
613cbf720c Update dependency eslint-plugin-jsdoc to v54 (#35760)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-13 07:28:21 +00:00
github-actions[bot]
bce4a572cd New Crowdin Translations (automated) (#35759)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-08-13 07:26:03 +00:00
Claire
c893b82ace Remove unnecessary limitation on manual build-security workflow (#35752) 2025-08-13 07:12:11 +00:00
renovate[bot]
eda8ddddd6 Update dependency json-schema to v6 (#35754)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-12 16:38:54 +00:00
Claire
63d3f28b20 Fix reply indicator displaying wrong avatar in rare cases (#35756) 2025-08-12 16:16:03 +00:00
renovate[bot]
783b33e2da Update dependency pino to v9.8.0 (#35722)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-12 13:54:40 +00:00
renovate[bot]
5847117573 Update dependency eslint-plugin-jsdoc to v53 (#35742)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-12 13:54:22 +00:00
Claire
258e5c4938 Fix interaction policy changes in implicit updates not being saved (#35751) 2025-08-12 12:19:29 +00:00
renovate[bot]
69ee043f9d Update dependency rspec-rails to v8.0.2 (#35750)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-12 09:53:52 +00:00
renovate[bot]
28b5477c6f Update dependency rubocop-rails to v2.33.1 (#35747)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-12 09:27:07 +00:00
Matt Jankowski
5ee83a680b Update stoplight to version 5.3.1 (#35129) 2025-08-12 08:15:22 +00:00
renovate[bot]
d9d7914a8d Update dependency vite to v7.1.2 (#35746)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-12 07:44:48 +00:00
github-actions[bot]
ca3d67e88d New Crowdin Translations (automated) (#35745)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-08-12 07:40:37 +00:00
Matt Jankowski
61f0ce654f Update rubocop-rails to version 2.33.0 (#35741) 2025-08-12 07:29:02 +00:00
Renaud Chaput
379f12ea00 Update to Vite 7 (#35598) 2025-08-11 12:35:36 +00:00
Echo
bf15b1d65d Prevent props being added as HTML attributes (#35739) 2025-08-11 12:00:35 +00:00
renovate[bot]
4cabc031e6 Update dependency rubyzip to v3 (#35576)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-11 10:12:14 +00:00
renovate[bot]
9c5b4b2639 Update dependency sass to v1.90.0 (#35695)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-11 08:57:42 +00:00
Claire
8a7e84a475 Add test for Delete of inlined QuoteAuthorization (#35724) 2025-08-11 08:55:23 +00:00
Claire
0e99d428b2 Change serialization of Delete activities for QuoteAuthorization to inline the latter (#35725) 2025-08-11 08:55:18 +00:00
renovate[bot]
dbab3912bd Update dependency hiredis-client to v0.25.2 (#35732)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-11 08:08:40 +00:00
github-actions[bot]
3c6c9d650d New Crowdin Translations (automated) (#35729)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-08-11 08:08:33 +00:00
Matt Jankowski
b827a0a6a8 Allow CustomEmoji to normalize its own domain (#35726) 2025-08-11 07:33:36 +00:00
Echo
ab0a206d43 [Glitch] Update Redux to handle quote posts
Port 8ee4b3f906 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-09 23:10:41 +02:00
Claire
11902d958f Merge commit 'ce1680e6f979889ebd5c775353f3b82a8b2698bb' into glitch-soc/merge-upstream
Conflicts:
- `app/models/concerns/user/has_settings.rb`:
  Upstream added a new helper for a setting, where glitch-soc had extra ones.
  Not a real conflict, added upstream's new helper without removing glitch-soc's ones.
2025-08-09 23:02:43 +02:00
renovate[bot]
ce1680e6f9 Update dependency core-js to v3.45.0 (#35667)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-08 15:32:15 +00:00
Matt Jankowski
b8982cb881 Use around_action to preserve stored location in auth/sessions#destroy (#35716) 2025-08-08 15:31:50 +00:00
renovate[bot]
5d934c2835 Update dependency httplog to v1.7.3 (#35721)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-08 10:06:23 +00:00
David Roetzel
868c46bc76 Add delivery failure handling to FASP jobs (#35723) 2025-08-08 09:46:09 +00:00
github-actions[bot]
1fd147bf2b New Crowdin Translations (automated) (#35720)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-08-08 09:00:51 +00:00
Echo
8ee4b3f906 Update Redux to handle quote posts (#35715) 2025-08-08 08:44:05 +00:00
Claire
54134a30a7 Merge pull request #3155 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to a485f97d21
2025-08-07 18:51:05 +02:00
Claire
e68de292b4 Merge commit 'a485f97d21c3fb7da927e8fd239b301a590ee9b8' into glitch-soc/merge-upstream 2025-08-07 18:16:54 +02:00
Matt Jankowski
a485f97d21 Replace EmailHelper module with normalizes via model concern (#35702) 2025-08-07 13:47:47 +00:00
Claire
496a5f423e Inline instrument quote post in outgoing QuoteRequest activities (#35713) 2025-08-07 13:19:18 +00:00
Claire
836a2bfee0 Fix handling of inlined instrument in incoming QuoteRequest (#35714) 2025-08-07 12:52:29 +00:00
github-actions[bot]
39a3ffaf2f New Crowdin Translations (automated) (#35708)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-08-07 08:46:11 +00:00
Claire
d4e0784182 Fix quote revocation not being streamed (#35710) 2025-08-07 08:03:15 +00:00
Claire
e615d2f069 Change quote to be fetched with quoted account rather than random follower (#35709) 2025-08-07 08:02:29 +00:00
Claire
9ddb9739d1 Merge pull request #3154 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to ac59772dc6
2025-08-06 23:31:58 +02:00
Claire
9da8c9e07c [Glitch] Bundle quotes and mentions in the same quickfilter bar since quotes don't have their own icon
Port 4838085d66 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-06 22:43:44 +02:00
Claire
4b507c0f05 [Glitch] Add UI for revoking quote posts
Port 55a98580aa to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-06 22:43:44 +02:00
Claire
dbb2908eeb [Glitch] Fix quote notification filtering and add settings
Port a4c05c694f to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-06 22:34:14 +02:00
Claire
235037a3b2 Merge commit 'ac59772dc6cda646258e61debfd792f9057c1c39' into glitch-soc/merge-upstream
Conflicts:
- `app/controllers/api/v1/statuses_controller.rb`:
  Conflict because upstream added a parameter where glitch-soc had an extra one.
  Added upstream's parameter while keeping glitch-soc's.
- `app/serializers/activitypub/note_serializer.rb`:
  Conflict because upstream added an extension where glitch-soc had an extra one.
  Added upstream's extension while keeping glitch-soc's.
- `app/services/update_status_service.rb`:
  Conflict because upstream added a parameter where glitch-soc had an extra one.
  Added upstream's parameter while keeping glitch-soc's.
2025-08-06 22:02:55 +02:00
Claire
ac59772dc6 Change icon of quote notification mails (#35701) 2025-08-06 15:20:16 +00:00
Claire
4838085d66 Bundle quotes and mentions in the same quickfilter bar since quotes don't have their own icon (#35700) 2025-08-06 14:54:03 +00:00
Claire
9ec99ffef1 Add quote_approval_policy parameter when posting and editing statuses (#35699) 2025-08-06 14:23:12 +00:00
Matt Jankowski
6e48322055 Add spec for CanonicalEmailBlock.matching_email scope (#35692) 2025-08-06 12:19:43 +00:00
Claire
55a98580aa Add UI for revoking quote posts (#35689) 2025-08-06 11:52:56 +00:00
Claire
c8f263c419 Export interaction policies for local posts over ActivityPub (#35697) 2025-08-06 11:31:36 +00:00
github-actions[bot]
6f6e7d8d49 New Crowdin Translations (automated) (#35694)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-08-06 09:06:22 +00:00
renovate[bot]
fcbd4b7afb Update dependency annotaterb to v4.18.0 (#35676)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-06 08:43:14 +00:00
Matt Jankowski
4c2ddbf2c4 Update rubocop to version 1.79.2 (#35688) 2025-08-06 08:42:53 +00:00
Claire
a4c05c694f Fix quote notification filtering and add settings (#35690) 2025-08-05 16:15:16 +00:00
Matt Jankowski
a968849e9c Use normalizes api for UsernameBlock username change (#35606) 2025-08-05 14:10:28 +00:00
Claire
5c1456c97f Merge pull request #3153 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to ffeb5da991
2025-08-05 16:08:50 +02:00
Claire
3f166bb068 Merge commit 'ffeb5da9912a3b7db0deb8aec429e661ef609c59' into glitch-soc/merge-upstream 2025-08-05 15:46:33 +02:00
Claire
ffeb5da991 Bump version to v4.4.3 (#35687) 2025-08-05 13:32:20 +00:00
Claire
edece2a197 Merge commit from fork 2025-08-05 14:53:04 +02:00
Claire
1fd3510b32 Change the quote revocation REST API endpoint to return updated quote post (#35677) 2025-08-05 09:42:58 +00:00
renovate[bot]
9c0a10f662 Update dependency capybara-playwright-driver to v0.5.7 (#35675)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-05 08:19:58 +00:00
github-actions[bot]
54fd1c1f9b New Crowdin Translations (automated) (#35674)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-08-05 08:19:55 +00:00
Matt Jankowski
8131268256 Replace unprocessable_entity -> unprocessable_content (#35658) 2025-08-05 07:42:08 +00:00
Claire
ad499db397 Merge pull request #3149 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 081d38679f
2025-08-04 22:59:08 +02:00
Claire
5318957ab3 Fix serialization of quote post notification groups (#35670) 2025-08-04 20:58:59 +00:00
Claire
98685f744d [Glitch] Add quote notifications to WebUI
Port 081d38679f to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-04 21:33:45 +02:00
Echo
3fc07508ee [Glitch] Performance regression fixes
Port 570c9d16be to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-04 21:26:57 +02:00
Echo
b8f66e1d33 [Glitch] Provides legacy fallback for browser that don't support regex flag v
Port 28b0e5ee78 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-04 21:26:23 +02:00
Claire
a6f0ec160e [Glitch] Fix WebUI crashing for accounts with null URL
Port 3caa318dfe to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-04 21:25:46 +02:00
Claire
53185f5381 Merge commit '081d38679f965ac20ff1a6c72e2fc1108c34ac30' into glitch-soc/merge-upstream 2025-08-04 21:24:47 +02:00
Claire
081d38679f Add quote notifications to WebUI (#35653) 2025-08-04 18:12:37 +00:00
Echo
570c9d16be Performance regression fixes (#35664) 2025-08-04 17:16:12 +00:00
Echo
28b0e5ee78 Provides legacy fallback for browser that don't support regex flag v (#35659) 2025-08-04 17:15:46 +00:00
Claire
cb0b608fa7 Ensure quoted user is given access to see the post (#35665) 2025-08-04 16:06:59 +00:00
Claire
32791c9745 Accept remote quotes of local quotes according to set policy (#35629) 2025-08-04 15:27:46 +00:00
Claire
0153a239db Avoid nested transactions when fetching quote posts (#35657) 2025-08-04 14:34:05 +00:00
renovate[bot]
49dcbd22d6 Update eslint (non-major) (#35661)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-04 14:19:48 +00:00
Claire
5ed9410de0 Disable ActiveRecord query cache in Create critical path (#35662) 2025-08-04 14:15:02 +00:00
David Roetzel
eb273f904f Make WorkerBatch spec more robust (#35656) 2025-08-04 14:04:40 +00:00
Eugen Rochko
d8397040d7 Fix allow with approval option not working on username blocks (#35655) 2025-08-04 13:10:19 +00:00
Eugen Rochko
c8ec649830 Fix "new replies available" miscounting previously known replies (#35654) 2025-08-04 12:49:17 +00:00
Claire
80aadc55df Add missing mailer for quote notifications (#35652) 2025-08-04 10:44:59 +00:00
github-actions[bot]
f68bd21600 New Crowdin Translations (automated) (#35634)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-08-04 09:20:50 +00:00
renovate[bot]
59e729e3fe Update dependency ioredis to v5.7.0 (#35617)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-04 08:34:04 +00:00
renovate[bot]
895975e2ab Update dependency haml_lint to v0.66.0 (#35649)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-04 08:33:41 +00:00
renovate[bot]
1228e000a1 Update dependency pg to v1.6.1 (#35559)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-04 08:33:17 +00:00
renovate[bot]
3d3d2c93d6 Update DefinitelyTyped types (non-major) (#35647)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-04 08:12:11 +00:00
Claire
3caa318dfe Fix WebUI crashing for accounts with null URL (#35651) 2025-08-04 07:49:12 +00:00
Claire
927cfea5ae Update dependency ruby-saml to v1.18.1 (#35650) 2025-08-04 07:49:08 +00:00
David Roetzel
05cdd3f6eb Track delivery failures to FASP (#35628) 2025-08-04 07:43:34 +00:00
renovate[bot]
bf46cffd9e Update peter-evans/create-pull-request action to v7.0.8 (#35648)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-04 06:48:16 +00:00
renovate[bot]
ab1a5b4822 Update Node.js to 22.18 (#35621)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-04 06:46:38 +00:00
Claire
9a8bc41552 Merge pull request #3148 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 591df1f205
2025-08-02 14:47:38 +02:00
Echo
0d54a47ec3 [Glitch] Emoji Rendering Efficiency
Port 6bca52453a to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-01 22:17:21 +02:00
Echo
c5144c0c7d [Glitch] Modern Emoji: Use local storage to opt-in
Port b81670776f to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-08-01 22:13:04 +02:00
Claire
dbab707d64 Merge commit '591df1f205c654381203b56d46498efc62370776' into glitch-soc/merge-upstream 2025-08-01 22:11:59 +02:00
Claire
591df1f205 Add support for local quote stamps (#35626) 2025-08-01 14:55:25 +00:00
Matt Jankowski
483da67204 Remove unused obscured_counter helper method (#35627) 2025-08-01 14:28:45 +00:00
David Roetzel
fba24cc4eb Add minute resolution to DeliveryFailureTracker (#35625) 2025-08-01 13:29:22 +00:00
renovate[bot]
bcab6a9318 Update dependency sidekiq-scheduler to v6 (#35596)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-01 11:57:13 +00:00
Claire
6268321316 Ensure blocked users cannot quote (#35624) 2025-08-01 09:34:12 +00:00
Claire
29a5f059d2 Add notifications for inbound quotes (#35618) 2025-08-01 09:12:46 +00:00
github-actions[bot]
d09f866daa New Crowdin Translations (automated) (#35622)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-08-01 07:57:38 +00:00
renovate[bot]
1d86df685b Update dependency puma to v6.6.1 (#35620)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-01 06:34:05 +00:00
Echo
6bca52453a Emoji Rendering Efficiency (#35568) 2025-07-31 17:30:14 +00:00
Claire
0e249cba4b Revoke quote posts when those get deleted (#35614) 2025-07-31 14:23:36 +00:00
Claire
19db4cb7c1 Add example of quote post with a preview card to development sample data (#35616) 2025-07-31 13:39:26 +00:00
Echo
b81670776f Modern Emoji: Use local storage to opt-in (#35605) 2025-07-31 13:33:34 +00:00
renovate[bot]
8452ec6f3b Update dependency rubocop to v1.79.1 (#35613)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-31 12:35:22 +00:00
Claire
f7388af721 Fix Chewy::UndefinedUpdateStrategy in dev:populate_sample_data task when Elasticsearch is enabled (#35615) 2025-07-31 12:34:21 +00:00
Claire
2dfdcc7dcb Add API endpoints to view and revoke one's quoted posts (#35578) 2025-07-31 09:36:51 +00:00
Claire
572a0e128d Change quote verification to not bypass authorization flow for mentions (#35528) 2025-07-31 07:39:53 +00:00
github-actions[bot]
2131d1ff23 New Crowdin Translations (automated) (#35611)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-07-31 07:26:24 +00:00
renovate[bot]
fc1abed0dc Update dependency database_cleaner-active_record to v2.2.2 (#35610)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-31 07:14:48 +00:00
Claire
6dc0677dfc Merge pull request #3146 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to e5826777b6
2025-07-30 22:19:31 +02:00
Eugen Rochko
27fdc1258b [Glitch] Change new replies to be loaded automatically if thread previously empty
Port b80e95b2aa to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-07-30 20:12:20 +02:00
Eugen Rochko
2f8fa59b85 [Glitch] Change design of quote posts in web UI
Port 92bf55afd0 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-07-30 20:11:55 +02:00
Eugen Rochko
0f54e51777 [Glitch] Change "new replies available" notice to be above replies in web UI
Port d121007927 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-07-30 20:08:58 +02:00
Colin Dean
6f7ab952c8 [Glitch] Swap order of translation restoration and service credit on post card
Port b5cebf45ea to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-07-30 20:08:38 +02:00
william light
2e6ed97416 [Glitch] hotkeys: only match just() when no modifiers are held
Port f3786e0816 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-07-30 20:08:20 +02:00
Claire
e53421b548 Merge commit 'e5826777b6c06a32b97388657beaca1e5eccb421' into glitch-soc/merge-upstream
Conflicts:
- `config/settings.yml`:
  Not a real conflict, upstream removed settings that are identical in glitch-soc
  but textually adjacent to glitch-soc-only settings.
  Removed what upstream removed.
2025-07-30 20:05:45 +02:00
Claire
e5826777b6 Fix friends-of-friends recommendations suggesting already-requested accounts (#35604) 2025-07-30 16:28:26 +00:00
Eugen Rochko
b80e95b2aa Change new replies to be loaded automatically if thread previously empty (#35603) 2025-07-30 16:18:58 +00:00
Eugen Rochko
2257612deb Fix "new replies available" reporting a false positive for re-fetched root status (#35602) 2025-07-30 16:09:16 +00:00
Eugen Rochko
92bf55afd0 Change design of quote posts in web UI (#35584) 2025-07-30 15:53:42 +00:00
Osman
39250ab961 Sort auditable accounts (#35272) 2025-07-30 15:08:05 +00:00
Claire
efc0d237af Fix synchronous recursive fetching of deeply-nested quoted posts (#35600) 2025-07-30 14:39:30 +00:00
Claire
31ba52a57b Change StatusReachFinder to consider quotes as well as reblogs (#35601) 2025-07-30 14:07:01 +00:00
Matt Jankowski
e8e6cf9510 Add coverage to user spec for missing last_sign_in_at scenario (#35587) 2025-07-30 13:46:58 +00:00
Matt Jankowski
139025fce0 Fix wrong policy authorization in admin controllers (#35588) 2025-07-30 13:17:53 +00:00
Matt Jankowski
3146109b08 Add MediaAttachment.combined_media_file_size method (#35570) 2025-07-30 12:57:51 +00:00
Matt Jankowski
8896d6c1b1 Use attribute for User#bypass_registration_checks? (#35580) 2025-07-30 12:55:36 +00:00
renovate[bot]
25add0af31 Update dependency cross-env to v10 (#35564)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-30 12:15:56 +00:00
renovate[bot]
027657b590 Update dependency eslint-plugin-jsdoc to v52 (#35561)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-30 12:14:33 +00:00
Matt Jankowski
7e6b134222 Extract User::Activity concern (#35581) 2025-07-30 11:19:11 +00:00
Matt Jankowski
4042bc959b Use increment for User#update_sign_in! optional change (#35573) 2025-07-30 10:38:04 +00:00
Matt Jankowski
6dc55a2f4e Extract User::Confirmation concern (#35582) 2025-07-30 10:33:57 +00:00
Matt Jankowski
15b72591d4 Use attribute for User#external? (#35579) 2025-07-30 09:48:18 +00:00
Matt Jankowski
fd779c25b9 Avoid return not_found in statuses controller (#35585) 2025-07-30 09:28:20 +00:00
Matt Jankowski
ece49baa38 Use generated query method for check in admin/domain_blocks (#35589) 2025-07-30 09:27:29 +00:00
Matt Jankowski
ba9fa54f9c Add coverage for more admin/domain_blocks scenarios (#35590) 2025-07-30 08:52:47 +00:00
github-actions[bot]
1c89309db0 New Crowdin Translations (automated) (#35592)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-07-30 08:37:33 +00:00
Eugen Rochko
a368b29e27 Fix number of new replies increasing even if reply was not fetched (#35577) 2025-07-29 10:47:18 +00:00
Eugen Rochko
20bbd20ef1 Add ability to block words in usernames (#35407) 2025-07-29 10:19:15 +00:00
Eugen Rochko
8cf7a77808 Fix async refresh never being finished when status cannot be fetched (#35500) 2025-07-29 09:23:32 +00:00
Eugen Rochko
d121007927 Change "new replies available" notice to be above replies in web UI (#35575) 2025-07-29 09:00:27 +00:00
Claire
3eca8cce1c Add second set of blocked text that applies to accounts regardless of account age (#35563) 2025-07-29 08:59:16 +00:00
github-actions[bot]
d299b0d576 New Crowdin Translations (automated) (#35574)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-07-29 08:59:00 +00:00
Matt Jankowski
ea976a5ffb Fix unnecessary account note addition for already-muted moved-to users (#35566) 2025-07-29 08:23:19 +00:00
Matt Jankowski
bedbab74b9 Use bundler version 2.7.1 (#35567) 2025-07-29 08:22:04 +00:00
Matt Jankowski
c587c44975 Fix Lint/NonLocalExitFromIterator cop in JSON-LD helper (#34948) 2025-07-28 15:35:37 +00:00
David Roetzel
f1b9868980 Bypass registration checks for seeded admin user (#35565) 2025-07-28 13:25:16 +00:00
Matt Jankowski
8d6f033326 Fix Style/GuardClause in move worker (#35520) 2025-07-28 12:55:05 +00:00
Colin Dean
b5cebf45ea Swap order of translation restoration and service credit on post card (#33619) 2025-07-28 11:33:11 +00:00
renovate[bot]
513b6289d6 chore(deps): update dependency strong_migrations to v2.5.0 (#35560)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-28 09:34:14 +00:00
Matt Jankowski
040a638ab9 Fix Style/GuardClause in Tag (#35522) 2025-07-28 08:54:29 +00:00
Matt Jankowski
eb73ae2f86 Fix Style/GuardClause in User#regenerate_feed! (#35523) 2025-07-28 08:53:52 +00:00
Matt Jankowski
916cc1365e Fix Style/GuardClause in User#wrap_email_confirmation (#35524) 2025-07-28 08:52:59 +00:00
Matt Jankowski
86ef4d4884 Add skip_* methods to check move worker process (#35538) 2025-07-28 08:50:19 +00:00
renovate[bot]
456c3bda0b chore(deps): update dependency omniauth-cas to v3.0.2 (#35558)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-28 08:41:31 +00:00
Matt Jankowski
63daf6b317 Fix Style/GuardClause in PreviewCard (#35525) 2025-07-28 08:40:37 +00:00
Matt Jankowski
e183d7dd9a Fix Style/GuardClause in app/helpers (#35526) 2025-07-28 08:40:20 +00:00
Matt Jankowski
2acc942bb4 Fix Style/GuardClause in WebfingerResource (#35531) 2025-07-28 08:39:11 +00:00
Matt Jankowski
038de44110 Fix Style/GuardClause in Webfinger lib (#35532) 2025-07-28 08:38:55 +00:00
renovate[bot]
3b01f98c11 fix(deps): update dependency vite-plugin-pwa to v1.0.2 (#35529)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-28 08:32:47 +00:00
Matt Jankowski
7cd3738c19 Add with_list_account scope to List model (#35539) 2025-07-28 08:26:29 +00:00
Eugen Rochko
018e5e303f Fix jobs being added to batch after they might already execute (#35496) 2025-07-28 08:20:12 +00:00
github-actions[bot]
a57a9505d4 New Crowdin Translations (automated) (#35537)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-07-28 08:14:11 +00:00
Matt Jankowski
720ee96969 Move repeated snowflake ID gather to base classes (#35554) 2025-07-28 08:14:06 +00:00
Matt Jankowski
73f72ec8fe Use attribute for defining rate_limit boolean (#35555) 2025-07-28 08:08:31 +00:00
Matt Jankowski
5d69157e62 Prefer delegated nil-wrapping methods to safe navigation (#35541) 2025-07-28 08:03:23 +00:00
Matt Jankowski
b464b87c2b Use moved? query method where relevant (#35542) 2025-07-28 08:02:21 +00:00
Matt Jankowski
9d0d6f011c Add coverage for AnnouncementReaction model (#35543) 2025-07-28 07:59:32 +00:00
william light
f3786e0816 hotkeys: only match just() when no modifiers are held (#35535) 2025-07-26 05:51:50 +00:00
Claire
3c2cbbb4a6 Merge pull request #3144 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to e93efe0e13
2025-07-25 23:43:35 +02:00
Claire
8649681c51 Merge commit 'e93efe0e131481635e88d7ad114ef66148626f90' into glitch-soc/merge-upstream
Conflicts:
- `app/serializers/activitypub/note_serializer.rb`:
  Conflict because upstream added context extensions where glitch-soc had its own.
  Added upstream's new context extension while keeping ours.
2025-07-25 21:45:00 +02:00
Claire
e93efe0e13 Fix unnecessary duplication in vite code for finding entrypoints (#35515) 2025-07-25 16:38:21 +00:00
Claire
5a88b7f683 Add experimental basic quote post authoring (#35355) 2025-07-25 12:35:24 +00:00
Roni Laukkarinen
81da377d8e Fix Vite build failure on Node.js v20 due to undefined file.parentPath (#35509) 2025-07-25 07:59:49 +00:00
github-actions[bot]
d950298d29 New Crowdin Translations (automated) (#35514)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-07-25 07:29:48 +00:00
Matt Jankowski
2e35defeec Update rubocop to version 1.79.0 (#35502) 2025-07-25 07:22:05 +00:00
Matt Jankowski
960f693219 Use field partial in admin account show view (#35503) 2025-07-25 07:21:08 +00:00
Matt Jankowski
e5e977c24f Fix Style/GuardClause in worker rescues (#35508) 2025-07-25 07:18:46 +00:00
Claire
cac693d0eb Merge pull request #3142 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to a863e68d17
2025-07-24 21:51:04 +02:00
Echo
ad0f2c5e02 [Glitch] Force modern emoji experimental to be dev mode only
Port dfaca794bf to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-07-24 18:21:51 +02:00
diondiondion
3f980d6751 [Glitch] fix: Fix TypeError on pages with empty feeds
Port 6fc77a545b to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-07-24 18:16:23 +02:00
Mayank
d235b2ce62 [Glitch] remove redundant title text from media modal images in web UI
Port 8baed8b90e to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-07-24 18:14:52 +02:00
Echo
ec412e1748 [Glitch] Enables cross-origin Web Workers
Port 7f9ad7eabf to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-07-24 18:14:25 +02:00
Claire
cee41da8d8 [Glitch] Fix “Expand this post” link including user @undefined
Port a6794c066d to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-07-24 18:13:22 +02:00
Claire
72affd6b45 Merge commit 'a863e68d174b176dc350d8e3472c010cd37b7807' into glitch-soc/merge-upstream
Conflicts:
- `app/models/trends/statuses.rb`:
  Conflict because of glitch-soc's setting to allow CWs in trends.
  Kept glitch-soc's setting but followed upstream's refactor.
- `docker-compose.yml`:
  Conflict because of upstream VS glitch-soc repos.
  Updated version number as upstream did, but kept glitch-soc repos.
2025-07-24 18:10:38 +02:00
Claire
a863e68d17 Add restrictions on which quote posts can trend (#35507) 2025-07-24 15:45:12 +00:00
renovate[bot]
847b37552a chore(deps): update dependency httplog to v1.7.2 (#35506)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-24 15:08:50 +00:00
Echo
dfaca794bf Force modern emoji experimental to be dev mode only (#35505) 2025-07-24 14:55:00 +00:00
diondiondion
6fc77a545b fix: Fix TypeError on pages with empty feeds (#35504) 2025-07-24 14:30:56 +00:00
renovate[bot]
c871c7398e fix(deps): update dependency @vitejs/plugin-react to v4.7.0 (#35421)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-24 09:00:32 +00:00
Mayank
8baed8b90e remove redundant title text from media modal images in web UI (#35468) 2025-07-24 08:58:22 +00:00
David Roetzel
8a1c43bf3b Use default for preselected default privacy post setting (#35422) 2025-07-24 08:23:41 +00:00
Matt Jankowski
5c01ccc31f Set flash options via redirect where possible (#35370) 2025-07-24 08:03:28 +00:00
renovate[bot]
67be8208db chore(deps): update dependency haml_lint to v0.65.1 (#35497)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-24 07:52:34 +00:00
David Roetzel
7d136feccf Bump version to v4.4.2 (#35498) 2025-07-24 07:51:56 +00:00
Matt Jankowski
e54e96d61f Extract params hash for api/v1/push/subscriptions#create (#35475) 2025-07-24 07:49:20 +00:00
github-actions[bot]
469304359a New Crowdin Translations (automated) (#35495)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-07-24 07:49:09 +00:00
Matt Jankowski
290e36d7e8 Finish migration of api/web/push_subscriptions controller->request spec (#35482) 2025-07-24 07:46:09 +00:00
Matt Jankowski
4241ce9888 Silence json key duplicate warning from api/web/push_subscriptions (#35481) 2025-07-24 07:33:53 +00:00
Echo
7f9ad7eabf Enables cross-origin Web Workers (#35483) 2025-07-24 07:14:27 +00:00
Claire
a6794c066d Fix “Expand this post” link including user @undefined (#35478) 2025-07-23 23:09:24 +00:00
Claire
dfdd844882 Merge pull request #3141 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 7d3ef27a8d
2025-07-23 20:58:41 +02:00
Echo
afa217da97 [Glitch] Fix accidentally instantiating Web Worker
Port 7d3ef27a8d to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-07-23 19:05:46 +02:00
Echo
8a8453e3b1 [Glitch] Emoji Rendering
Port 760d00b7f7 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-07-23 19:05:04 +02:00
Eugen Rochko
a8432560ba [Glitch] Add button to load new replies in web UI
Port 14a781fa24 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-07-23 18:49:25 +02:00
diondiondion
d9c1e45739 [Glitch] fix: Fix glitchy status keyboard navigation
Port d36236cbcd to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-07-23 18:45:47 +02:00
Claire
63af7ecb1f Merge commit '7d3ef27a8dc8fb281bae959b245d3db63aa82260' into glitch-soc/merge-upstream 2025-07-23 18:43:56 +02:00
Echo
7d3ef27a8d Fix accidentally instantiating Web Worker (#35473) 2025-07-23 14:01:45 +00:00
Eugen Rochko
14a781fa24 Add button to load new replies in web UI (#35210) 2025-07-23 13:42:07 +00:00
Claire
a93a67a4d9 Merge pull request #3138 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 0af2c4829f
2025-07-23 13:58:43 +02:00
Claire
d69c5f1a6e Fix glitch assets not being found 2025-07-23 12:48:45 +02:00
diondiondion
26ba2db53f [Glitch] fix: Don't submit post when pressing Enter in CW field
Port ee21f72211 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-07-23 12:28:15 +02:00
diondiondion
0ae7c7e406 [Glitch] refactor: Replace react-hotkeys with custom hook
Port 4de5cbd6f5 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-07-23 12:22:42 +02:00
Claire
105315a2e3 Rename GlitchThemes plugin on import to reduce changes with upstream 2025-07-23 12:10:29 +02:00
Claire
45d79427c4 Merge commit '0af2c4829ff86cf84ed9e7804d023f31e805542b' into glitch-soc/merge-upstream
Conflicts:
- `vite.config.mts`:
  Conflict because of differently-named theme plugins.
  Updated to go with upstream's changes.
2025-07-23 12:08:59 +02:00
renovate[bot]
cec26d58c8 chore(deps): update dependency json-ld-preloaded to v3.3.2 (#35470)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-23 08:13:04 +00:00
renovate[bot]
593cdae404 fix(deps): update dependency axios to v1.11.0 (#35471)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-23 08:12:16 +00:00
Matt Jankowski
d2ef9ac04a Use report_range method in admin/tags to generate reporting period (#35465) 2025-07-23 08:02:07 +00:00
Matt Jankowski
d065ec9298 Combine assignment params in admin/accounts#batch action (#35463) 2025-07-23 07:59:14 +00:00
Matt Jankowski
b19131202f Extract constants for captcha directives/sources (#35439) 2025-07-23 07:55:54 +00:00
Matt Jankowski
70058ae49d Add Form::BaseBatch class for "batch form update" objects (#35458) 2025-07-23 07:50:35 +00:00
renovate[bot]
62a23b1985 chore(deps): update dependency rspec-sidekiq to v5.2.0 (#35436)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-23 07:42:48 +00:00
renovate[bot]
6917cd2f40 chore(deps): update dependency propshaft to v1.2.1 (#35451)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-23 07:40:24 +00:00
diondiondion
d36236cbcd fix: Fix glitchy status keyboard navigation (#35455) 2025-07-23 07:39:36 +00:00
Claire
b3809ffa31 Merge pull request #3137 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to fab95b8dae
2025-07-22 23:53:05 +02:00
diondiondion
82f1bb4191 [Glitch] fix: Fix quote posts styling on notifications page
Port 3771f9e04b to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-07-22 23:20:30 +02:00
diondiondion
40de31ddad [Glitch] refactor: Disable useDrag hook when main menu is not openable
Port a842b14c84 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-07-22 23:20:11 +02:00
diondiondion
696ad9d414 [Glitch] fix: Add lang attribute to current composer language in alt text modal
Port 138746bdcc to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-07-22 23:19:55 +02:00
Claire
5ff0039d7b Merge commit 'fab95b8dae3db411318638804a01675dd5b38a01' into glitch-soc/merge-upstream 2025-07-22 23:17:48 +02:00
Claire
889c0b3a1f Merge commit '9e6a9efe101b36291897ae9fd4dbc5163a6cef38' into glitch-soc/merge-upstream
Conflicts:
- `package.json`:
  Upstream added/updated dependency adjacent to glitch-soc-only dependency.
  Updated as upstream did.
- `vite.config.mts`:
  Upstream reworked the config file while using a different plugin for themes.
  Adapted upstream's changes.
- `yarn.lock`:
  Same as `package.json`
2025-07-22 23:07:30 +02:00
Echo
760d00b7f7 Emoji Rendering (#35424) 2025-07-22 14:43:15 +00:00
Echo
0af2c4829f Creates Vite plugin to generate assets file (#35454) 2025-07-22 13:58:04 +00:00
github-actions[bot]
be3dc5b508 New Crowdin Translations (automated) (#35453)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-07-22 10:10:37 +00:00
Claire
9c9bca713b Merge pull request #3136 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 19626ad89f
2025-07-21 22:40:28 +02:00
diondiondion
9c918e31e3 [Glitch] fix: Improve a11y of custom select menus in notifications settings
Port faffb73cbd to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-07-21 21:21:03 +02:00
Claire
4bc361546e Merge commit '19626ad89f66a32a3ddecb4f43a7b84e3236d287' into glitch-soc/merge-upstream 2025-07-21 21:19:53 +02:00
renovate[bot]
ae13063460 chore(deps): update dependency eslint-plugin-jsdoc to v51 (#35026)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-21 16:31:10 +00:00
renovate[bot]
1ed58aaaf2 fix(deps): update dependency axios to v1.10.0 (#35050)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-21 16:28:49 +00:00
renovate[bot]
bf17895d19 chore(deps): update dependency chromatic to v13 (#35064)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-21 16:28:01 +00:00
Matt Jankowski
20b3c43dde Update playwright-ruby-client to version 1.54.0 (#35448) 2025-07-21 16:24:55 +00:00
diondiondion
ee21f72211 fix: Don't submit post when pressing Enter in CW field (#35445) 2025-07-21 15:57:20 +00:00
diondiondion
4de5cbd6f5 refactor: Replace react-hotkeys with custom hook (#35425) 2025-07-21 14:43:38 +00:00
Matt Jankowski
fab95b8dae Add coverage for api/v1/invites scenarios (#35389) 2025-07-21 14:17:53 +00:00
renovate[bot]
4d2655490c chore(deps): update dependency nokogiri to v1.18.9 (#35433)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-21 12:25:28 +00:00
github-actions[bot]
6bb4113d0a New Crowdin Translations (automated) (#35428)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-07-21 09:01:34 +00:00
Matt Jankowski
3e76f01db4 Use bundler version 2.7.0 (#35430) 2025-07-21 08:07:53 +00:00
diondiondion
cf580d8c90 Don't require JSDoc params & return in TS (#35426) 2025-07-18 18:34:04 +00:00
github-actions[bot]
dbd0c3cbd9 New Crowdin Translations (automated) (#35420)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-07-18 07:52:05 +00:00
diondiondion
3771f9e04b fix: Fix quote posts styling on notifications page (#35411) 2025-07-17 17:28:30 +00:00
diondiondion
a842b14c84 refactor: Disable useDrag hook when main menu is not openable (#35414) 2025-07-17 12:39:40 +00:00
diondiondion
138746bdcc fix: Add lang attribute to current composer language in alt text modal (#35412) 2025-07-17 11:12:54 +00:00
Echo
9e6a9efe10 Replace Ruby Vite plugins (#35195)
Co-authored-by: Renaud Chaput <renchap@gmail.com>
2025-07-17 10:04:04 +00:00
renovate[bot]
19626ad89f chore(deps): update dependency httplog to v1.7.1 (#35406)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-17 09:32:57 +00:00
github-actions[bot]
7e2d92284c New Crowdin Translations (automated) (#35408)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-07-17 09:31:22 +00:00
renovate[bot]
20fb6bd788 chore(deps): update docker.io/ruby docker tag to v3.4.5 (#35397)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-17 09:03:40 +00:00
diondiondion
faffb73cbd fix: Improve a11y of custom select menus in notifications settings (#35403) 2025-07-17 08:56:00 +00:00
renovate[bot]
02a4e30594 chore(deps): update dependency propshaft to v1.2.0 (#35398)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-17 08:48:10 +00:00
renovate[bot]
f10b522f0c chore(deps): update dependency ruby to v3.4.5 (#35395)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-17 08:47:39 +00:00
Claire
e4a22e8068 Fix links in posts always having noreferrer in glitch flavor (#3135)
Fixes #3128
2025-07-16 22:56:36 +02:00
Claire
cfd2acfdd2 Merge pull request #3134 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 331599fa2b
2025-07-16 22:15:45 +02:00
diondiondion
6628faaa6a [Glitch] fix: Fix selected item in poll select menus is unreadable in Firefox
Port 558b9c90a6 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-07-16 21:33:20 +02:00
Claire
d6ce7de2d3 Merge commit '331599fa2b335a7b832adcab594a833f09b808f0' into glitch-soc/merge-upstream
Conflicts:
- `.github/ISSUE_TEMPLATE/1.web_bug_report.yml`:
  We don't use the github features that upstream does, so kept our version.
- `.github/ISSUE_TEMPLATE/2.server_bug_report.yml`:
  We don't use the github features that upstream does, so kept our version.
2025-07-16 21:31:28 +02:00
github-actions[bot]
331599fa2b New Crowdin Translations (automated) (#35399)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-07-16 12:24:09 +00:00
diondiondion
558b9c90a6 fix: Fix selected item in poll select menus is unreadable in Firefox (#35402) 2025-07-16 12:03:39 +00:00
Renaud Chaput
7d2dda97b3 Remove the "to triage" label status (#35394) 2025-07-16 07:17:21 +00:00
Claire
5c6133c20b Merge pull request #3133 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 74fc4dbacf
2025-07-15 22:59:06 +02:00
diondiondion
16caa6e387 [Glitch] refactor: Only remove pointer-events when necessary
Port 74fc4dbacf to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-07-15 18:22:12 +02:00
diondiondion
dc5693fde3 [Glitch] fix: Improve Dropdown component accessibility
Port 82a6ff091f to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-07-15 18:21:53 +02:00
Claire
eeffe580d8 Merge commit '74fc4dbacf5a9168074e91fc2d75309dc42ff1ed' into glitch-soc/merge-upstream 2025-07-15 18:19:32 +02:00
diondiondion
74fc4dbacf refactor: Only remove pointer-events when necessary (#35390) 2025-07-15 15:57:31 +00:00
diondiondion
07912a1cb7 Update age limit wording (#35387) 2025-07-15 15:46:44 +00:00
Claire
d36bf3b6fb Fix support for quote verification in implicit status updates (#35384) 2025-07-15 15:36:12 +00:00
Claire
594976a538 Refactor ActivityPub::Activity::Accept and ActivityPub::Activity::Reject specs (#35382) 2025-07-15 13:18:37 +00:00
Matt Jankowski
0efb889a9c Extract constant for attribution domains limit in account (#35350) 2025-07-15 13:08:24 +00:00
Claire
c0eabe289b Always give local quote of remote posts a quote request URI (#35383) 2025-07-15 13:01:03 +00:00
Claire
5bbc3c5ebb Fix quoteAuthorization type in JSON-LD context (#35380) 2025-07-15 09:32:02 +00:00
github-actions[bot]
d5e2cf5d3c New Crowdin Translations (automated) (#35379)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-07-15 08:16:56 +00:00
diondiondion
82a6ff091f fix: Improve Dropdown component accessibility (#35373) 2025-07-15 07:52:34 +00:00
renovate[bot]
4b8e60682d fix(deps): update dependency react-select to v5.10.2 (#35352)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-15 06:32:38 +00:00
renovate[bot]
6c2db9b1cf fix(deps): update dependency vite-plugin-static-copy to v3.1.1 (#35367)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-15 06:32:00 +00:00
Matt Jankowski
30344d6abf Confirm User#login_activities in auth/sessions spec (#35372) 2025-07-15 06:31:00 +00:00
Matt Jankowski
1637297085 Add coverage for CustomFilterStatus model (#35374) 2025-07-15 06:28:40 +00:00
Matt Jankowski
dec1fb71f4 Add coverage for FollowRecommendationMute model (#35376) 2025-07-15 06:27:36 +00:00
Claire
6206e6756a Merge pull request #3132 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 7273f6c03c
2025-07-14 22:30:54 +02:00
Claire
ad38168b77 Merge commit '7273f6c03cfc7fb74cc29ca9df610d1efb16417d' into glitch-soc/merge-upstream 2025-07-14 20:50:55 +02:00
Matt Jankowski
7273f6c03c Move shared params to common method in admin/reports/actions (#35353) 2025-07-14 09:23:18 +00:00
Matt Jankowski
a3ffd2edf8 Use sequence for unique names on webauthn cred fabricator (#35356) 2025-07-14 09:20:50 +00:00
renovate[bot]
a2c5eace88 chore(deps): update dependency annotaterb to v4.17.0 (#35368)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-14 07:07:21 +00:00
github-actions[bot]
a643d9d498 New Crowdin Translations (automated) (#35358)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-07-14 06:21:56 +00:00
Claire
70b5ec4349 Merge pull request #3129 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 3b52dca405
2025-07-11 20:33:12 +02:00
Echo
500e7eccc6 [Glitch] Make bio hashtags open the local page instead of the remote instance
Port 853a0c466e to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-07-11 19:00:16 +02:00
Echo
1dcf6a3937 [Glitch] Expose enabled features to the frontend
Port 94bceb8683 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-07-11 18:59:43 +02:00
Claire
1716f8da71 Merge commit '3b52dca4057560c58b260433722d91650fcd5040' into glitch-soc/merge-upstream
Conflicts:
- `app/serializers/initial_state_serializer.rb`:
  Upstream added a `features` attribute where glitch-soc had extra ones.
  Added `features` like upstream did.
2025-07-11 18:53:47 +02:00
Claire
3b52dca405 Fix quote attributes missing from Mastodon's context (#35354) 2025-07-11 16:35:06 +00:00
Echo
853a0c466e Make bio hashtags open the local page instead of the remote instance (#35349) 2025-07-11 15:18:34 +00:00
Echo
94bceb8683 Expose enabled features to the frontend (#35348) 2025-07-11 13:15:22 +00:00
Claire
88b0f3a172 Simplify DatabaseViewRecord.refresh (#35252) 2025-07-11 08:36:05 +00:00
github-actions[bot]
b69b5ba775 New Crowdin Translations (automated) (#35344)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-07-11 08:14:39 +00:00
Matt Jankowski
c442589593 Use ActiveModel::Attributes in FollowLimitable concern (#35327) 2025-07-10 07:40:56 +00:00
renovate[bot]
28633a504a chore(deps): update dependency json-schema to v5.2.1 (#35337)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-10 07:38:07 +00:00
Matt Jankowski
ad78701b6f Mark private methods in AnnualReport::TopStatuses (#35256) 2025-07-10 07:35:40 +00:00
Matt Jankowski
1496488771 Add Status#not_replying_to_account scope for annual report classes (#35257) 2025-07-10 07:35:04 +00:00
renovate[bot]
dd3d958e75 fix(deps): update dependency core-js to v3.44.0 (#35284)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-10 07:23:54 +00:00
github-actions[bot]
b363a3651d New Crowdin Translations (automated) (#35335)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-07-10 07:23:27 +00:00
renovate[bot]
86645fc14c chore(deps): update dependency rubocop to v1.78.0 (#35289)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-10 07:23:23 +00:00
Matt Jankowski
f9beecb343 Improve Accounts CLI prune spec (#35302) 2025-07-10 07:23:09 +00:00
Matt Jankowski
4ecfbd3920 Add Status.only_polls (and without polls) scope (#35330) 2025-07-10 07:13:22 +00:00
Claire
a315934314 Fix styling of external log-in button (#35320) 2025-07-10 06:56:40 +00:00
Claire
4dbdc436ed Merge pull request #3127 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to e9170e2de1
2025-07-10 02:07:17 +02:00
Claire
55914c6434 [Glitch] Fix replying from media modal or pop-in-player tagging user @undefined
Port e7c5c25dce81bd4e32a4bf599c759303420c47e3 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-07-10 01:22:14 +02:00
Echo
c2d76e8994 [Glitch] Emoji Indexing and Search
Port a1e8813522 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-07-10 01:21:51 +02:00
Claire
e2a867507c Merge commit 'e9170e2de1d75e02f04ad39f2af131c70189fb50' into glitch-soc/merge-upstream 2025-07-10 01:10:32 +02:00
Claire
e9170e2de1 Bump version to v4.4.1 (#35329) 2025-07-09 16:22:25 +00:00
Claire
5cfc1fabcf Fix nearly every sub-directory being crawled as part of Vite build (#35323) 2025-07-09 14:34:16 +00:00
David Roetzel
786b12e379 Relax error restriction in initializer (#35321) 2025-07-09 14:22:47 +00:00
Claire
e7c5c25de8 Fix replying from media modal or pop-in-player tagging user @undefined (#35317) 2025-07-09 12:13:51 +00:00
Echo
a1e8813522 Emoji Indexing and Search (#35253) 2025-07-09 09:55:41 +00:00
github-actions[bot]
76c1446416 New Crowdin Translations (automated) (#35310)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-07-09 09:10:55 +00:00
Claire
8bd2c87399 Fix support for special characters in various environment variables (#35314)
Co-authored-by: Matt Jankowski <matt@jankowski.online>
2025-07-09 08:58:41 +00:00
Matt Jankowski
1e2d77f2c7 Use if_exists: true when removing duplicate indexes (#35309) 2025-07-09 08:45:29 +00:00
Matt Jankowski
fb6c22f5c2 Use touch to record viewing annual report (#35296) 2025-07-09 08:04:00 +00:00
Matt Jankowski
f7259f625f Prefer on: :update in Tag validation declaration (#35297) 2025-07-09 08:03:39 +00:00
Claire
e783f796c9 Merge pull request #3124 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to b628a98d32
2025-07-08 17:47:27 +02:00
Claire
f7d1d73073 Merge commit 'b628a98d323902cdcc08fb8d612887dff4dbcd89' into glitch-soc/merge-upstream
Conflicts:
- `app/models/user_settings.rb`:
  Upstream added a new user setting, directly next to a glitch-soc-only one.
  The upstream setting would actually replace the glitch-soc one but it is not
  fully implemented yet, so have them side by side now.
- `app/views/settings/preferences/appearance/show.html.haml`:
  Ditto.
- `docker-compose.yml`:
  Conflict due to different registry names. Updated the version while keeping
  glitch-soc's registry.
2025-07-08 17:27:19 +02:00
Claire
5c5f30ed7e Merge pull request #3122 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 8ee6cee36e
2025-07-08 17:23:09 +02:00
diondiondion
615896c8ea [Glitch] fix: Fix can't skip search field by tabbing
Port b5eebd4d2b to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-07-08 16:44:19 +02:00
diondiondion
d9380857db [Glitch] fix: Remove focus highlight when status is clicked in light mode
Port 3c0767f543 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-07-08 16:43:56 +02:00
Echo
1c89eb2250 [Glitch] Import Emojibase data
Port 52bc2f64f4 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-07-08 16:43:23 +02:00
Claire
3efc857fbc Merge commit '8ee6cee36e313fcc39763210dfcd3b871b47cacb' into glitch-soc/merge-upstream 2025-07-08 16:41:01 +02:00
Claire
b628a98d32 Bump version to v4.4.0 (#35291) 2025-07-08 14:26:43 +00:00
Miguel Landaeta
d8fa807998 Bump linzer to 0.7.7 (#35258) 2025-07-08 13:04:16 +00:00
Echo
ef66d8379c Add option to set emoji preferences behind feature flag (#35282) 2025-07-08 10:51:11 +00:00
David Roetzel
8ee6cee36e Better error response to malformed headers (#35278) 2025-07-08 09:31:04 +00:00
github-actions[bot]
71b2120e5c New Crowdin Translations (automated) (#35286)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-07-08 09:22:38 +00:00
renovate[bot]
b10078633c chore(deps): update dependency libvips to v8.17.1 (#35283)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-08 08:35:54 +00:00
diondiondion
b5eebd4d2b fix: Fix can't skip search field by tabbing (#35281) 2025-07-07 15:10:51 +00:00
Claire
fdefc4d2b4 Add ability to manually trigger i18n uploads (#35279) 2025-07-07 09:22:22 +00:00
github-actions[bot]
f6b2609353 New Crowdin Translations (automated) (#35269)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-07-07 08:21:51 +00:00
Matt Jankowski
bdffdcb12f Remove unused scopes in Account model (#35276) 2025-07-07 08:07:01 +00:00
Claire
1ebb87a6a8 Fix incorrect name in scheduler configuration (#35263) 2025-07-04 07:51:01 +00:00
github-actions[bot]
83660ee381 New Crowdin Translations (automated) (#35261)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-07-04 07:34:54 +00:00
David Roetzel
1fa72d6c44 Raise better exception on FASP error responses (#35262) 2025-07-04 07:25:42 +00:00
Andy Piper
5a7c0d42f7 Add specific language confirming that we test with BrowserStack and Chromatic (#35248)
Signed-off-by: Andy Piper <andypiper@users.noreply.github.com>
2025-07-03 20:51:32 +00:00
Matt Jankowski
e8d2432e6a Fix intermittent failure of TOS model spec from effective date collision (#35244) 2025-07-03 16:28:47 +00:00
Matt Jankowski
2af17adc34 Use ActiveModel::Attributes in admin/status_batch_action (#35255) 2025-07-03 14:43:36 +00:00
Claire
e97f43399b Fix error handling for blank actions in account moderation action form (#35246) 2025-07-03 14:42:48 +00:00
github-actions[bot]
c66c5fd73d New Crowdin Translations (automated) (#35250)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-07-03 09:47:57 +00:00
diondiondion
3c0767f543 fix: Remove focus highlight when status is clicked in light mode (#35251) 2025-07-03 07:51:12 +00:00
renovate[bot]
70cd1fdc63 fix(deps): update dependency vite-plugin-pwa to v1.0.1 (#35223)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-03 07:32:51 +00:00
renovate[bot]
39028dde40 chore(deps): update dependency scenic to v1.9.0 (#35226)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-03 07:32:15 +00:00
Matt Jankowski
6e39b5ef04 Use ActiveModel::Attributes for admin/account_action boolean values (#35247) 2025-07-03 07:28:07 +00:00
Matt Jankowski
49db8a9662 Use Account#targeted_reports association where needed (#35249) 2025-07-03 07:28:03 +00:00
Andy Piper
2cfa6cb0e0 Update README with testing tool references. (#35236)
Signed-off-by: Andy Piper <andypiper@users.noreply.github.com>
2025-07-02 12:00:15 +00:00
Matt Jankowski
1ae3510ede Add coverage for TOS interstitial interruption flow of web app controller concern (#35235) 2025-07-02 09:21:32 +00:00
github-actions[bot]
6f1135d763 New Crowdin Translations (automated) (#35238)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-07-02 09:17:03 +00:00
Echo
52bc2f64f4 Import Emojibase data (#35229) 2025-07-02 08:58:39 +00:00
renovate[bot]
b1375328e1 chore(deps): update dependency faker to v3.5.2 (#35239)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-02 08:02:33 +00:00
renovate[bot]
9443e2cc4b chore(deps): update dependency opentelemetry-instrumentation-http to v0.25.1 (#35240)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-02 08:02:30 +00:00
Renaud Chaput
3a533c6c8d Bump version to 4.5.0-alpha.1 (#35231) 2025-07-02 08:00:43 +00:00
Matt Jankowski
c047014214 Add coverage for valid_locale_or_nil languages helper method (#34866) 2025-07-02 07:34:42 +00:00
Claire
68b05e994f Fix error on log-in from old users requiring ToS interstitial when said ToS has been removed (#35233) 2025-07-01 17:43:59 +00:00
1113 changed files with 38070 additions and 11611 deletions

View File

@@ -5,6 +5,7 @@
.gitattributes
.gitignore
.github
.vscode
public/system
public/assets
public/packs
@@ -20,6 +21,7 @@ postgres14
redis
elasticsearch
chart
storybook-static
.yarn/
!.yarn/patches
!.yarn/plugins

View File

@@ -6,6 +6,7 @@
':labels(dependencies)',
':prConcurrentLimitNone', // Remove limit for open PRs at any time.
':prHourlyLimit2', // Rate limit PR creation to a maximum of two per hour.
':enableVulnerabilityAlertsWithLabel(security)',
],
rebaseWhen: 'conflicted',
minimumReleaseAge: '3', // Wait 3 days after the package has been published before upgrading it
@@ -23,7 +24,6 @@
matchManagers: ['npm'],
matchPackageNames: [
'tesseract.js', // Requires code changes
'react-hotkeys', // Requires code changes
// react-router: Requires manual upgrade
'history',
@@ -94,6 +94,19 @@
matchUpdateTypes: ['patch', 'minor'],
groupName: 'eslint (non-major)',
},
{
// Group all Storybook-related packages in the same PR
matchManagers: ['npm'],
matchPackageNames: [
'chromatic',
'storybook',
'@storybook/*',
'msw',
'msw-storybook-addon',
],
matchUpdateTypes: ['patch', 'minor'],
groupName: 'storybook (non-major)',
},
{
// Group actions/*-artifact in the same PR
matchManagers: ['github-actions'],
@@ -142,6 +155,12 @@
matchUpdateTypes: ['patch', 'minor'],
groupName: 'opentelemetry-ruby (non-major)',
},
{
// Group Playwright Ruby & JS deps in the same PR, as they need to be in sync
matchManagers: ['bundler', 'npm'],
matchPackageNames: ['playwright-ruby-client', 'playwright'],
groupName: 'Playwright',
},
// Add labels depending on package manager
{ matchManagers: ['npm', 'nvm'], addLabels: ['javascript'] },
{ matchManagers: ['bundler', 'ruby-version'], addLabels: ['ruby'] },

View File

@@ -25,8 +25,8 @@ jobs:
strategy:
fail-fast: false
matrix:
language: ['javascript', 'ruby']
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
language: ['actions', 'javascript', 'ruby']
# CodeQL supports [ 'actions', 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
steps:

View File

@@ -51,7 +51,7 @@ jobs:
# Create or update the pull request
- name: Create Pull Request
uses: peter-evans/create-pull-request@v7.0.6
uses: peter-evans/create-pull-request@v7.0.8
with:
commit-message: 'New Crowdin translations'
title: 'New Crowdin Translations for ${{ github.base_ref || github.ref_name }} (automated)'

View File

@@ -14,6 +14,7 @@ on:
- config/locales-glitch/devise.en.yml
- config/locales-glitch/doorkeeper.en.yml
- .github/workflows/crowdin-upload.yml
workflow_dispatch:
jobs:
upload-translations:

2
.nvmrc
View File

@@ -1 +1 @@
22.17
22.19

View File

@@ -1,17 +1,21 @@
---
Metrics/AbcSize:
Exclude:
- lib/mastodon/cli/*.rb
Enabled: false
Metrics/BlockLength:
Enabled: false
Metrics/BlockNesting:
Enabled: false
Metrics/ClassLength:
Enabled: false
Metrics/CollectionLiteralLength:
Enabled: false
Metrics/CyclomaticComplexity:
Exclude:
- lib/mastodon/cli/*.rb
Enabled: false
Metrics/MethodLength:
Enabled: false
@@ -20,4 +24,7 @@ Metrics/ModuleLength:
Enabled: false
Metrics/ParameterLists:
CountKeywordArgs: false
Enabled: false
Metrics/PerceivedComplexity:
Enabled: false

View File

@@ -1,32 +1,11 @@
# This configuration was generated by
# `rubocop --auto-gen-config --auto-gen-only-exclude --no-offense-counts --no-auto-gen-timestamp`
# using RuboCop version 1.77.0.
# using RuboCop version 1.80.2.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.
Lint/NonLocalExitFromIterator:
Exclude:
- 'app/helpers/json_ld_helper.rb'
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
Metrics/AbcSize:
Max: 90
# Configuration parameters: CountBlocks, CountModifierForms, Max.
Metrics/BlockNesting:
Exclude:
- 'lib/tasks/mastodon.rake'
# Configuration parameters: AllowedMethods, AllowedPatterns.
Metrics/CyclomaticComplexity:
Max: 25
# Configuration parameters: AllowedMethods, AllowedPatterns.
Metrics/PerceivedComplexity:
Max: 27
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: AllowedVars, DefaultToNil.
Style/FetchEnvVar:

View File

@@ -1 +1 @@
3.4.4
3.4.6

View File

@@ -1,3 +1,5 @@
import { resolve } from 'node:path';
import type { StorybookConfig } from '@storybook/react-vite';
const config: StorybookConfig = {
@@ -26,6 +28,12 @@ const config: StorybookConfig = {
'oops.png',
].map((path) => ({ from: `../public/${path}`, to: `/${path}` })),
],
viteFinal(config) {
// For an unknown reason, Storybook does not use the root
// from the Vite config so we need to set it manually.
config.root = resolve(__dirname, '../app/javascript');
return config;
},
};
export default config;

View File

@@ -0,0 +1,2 @@
<html class="no-reduce-motion">
</html>

View File

@@ -12,13 +12,14 @@ import { initialize, mswLoader } from 'msw-storybook-addon';
import { action } from 'storybook/actions';
import type { LocaleData } from '@/mastodon/locales';
import { reducerWithInitialState, rootReducer } from '@/mastodon/reducers';
import { reducerWithInitialState } from '@/mastodon/reducers';
import { defaultMiddleware } from '@/mastodon/store/store';
import { mockHandlers, unhandledRequestHandler } from '@/testing/api';
// If you want to run the dark theme during development,
// you can change the below to `/application.scss`
import '../app/javascript/styles/mastodon-light.scss';
import './styles.css';
const localeFiles = import.meta.glob('@/mastodon/locales/*.json', {
query: { as: 'json' },
@@ -49,12 +50,17 @@ const preview: Preview = {
locale: 'en',
},
decorators: [
(Story, { parameters }) => {
(Story, { parameters, globals }) => {
const { locale } = globals as { locale: string };
const { state = {} } = parameters;
let reducer = rootReducer;
if (typeof state === 'object' && state) {
reducer = reducerWithInitialState(state as Record<string, unknown>);
}
const reducer = reducerWithInitialState(
{
meta: {
locale,
},
},
state as Record<string, unknown>,
);
const store = configureStore({
reducer,
middleware(getDefaultMiddleware) {

View File

@@ -7,8 +7,8 @@
* - Please do NOT modify this file.
*/
const PACKAGE_VERSION = '2.10.2'
const INTEGRITY_CHECKSUM = 'f5825c521429caf22a4dd13b66e243af'
const PACKAGE_VERSION = '2.11.3'
const INTEGRITY_CHECKSUM = '4db4a41e972cec1b64cc569c66952d82'
const IS_MOCKED_RESPONSE = Symbol('isMockedResponse')
const activeClientIds = new Set()
@@ -71,11 +71,6 @@ addEventListener('message', async function (event) {
break
}
case 'MOCK_DEACTIVATE': {
activeClientIds.delete(clientId)
break
}
case 'CLIENT_CLOSED': {
activeClientIds.delete(clientId)
@@ -94,6 +89,8 @@ addEventListener('message', async function (event) {
})
addEventListener('fetch', function (event) {
const requestInterceptedAt = Date.now()
// Bypass navigation requests.
if (event.request.mode === 'navigate') {
return
@@ -110,23 +107,29 @@ addEventListener('fetch', function (event) {
// Bypass all requests when there are no active clients.
// Prevents the self-unregistered worked from handling requests
// after it's been deleted (still remains active until the next reload).
// after it's been terminated (still remains active until the next reload).
if (activeClientIds.size === 0) {
return
}
const requestId = crypto.randomUUID()
event.respondWith(handleRequest(event, requestId))
event.respondWith(handleRequest(event, requestId, requestInterceptedAt))
})
/**
* @param {FetchEvent} event
* @param {string} requestId
* @param {number} requestInterceptedAt
*/
async function handleRequest(event, requestId) {
async function handleRequest(event, requestId, requestInterceptedAt) {
const client = await resolveMainClient(event)
const requestCloneForEvents = event.request.clone()
const response = await getResponse(event, client, requestId)
const response = await getResponse(
event,
client,
requestId,
requestInterceptedAt,
)
// Send back the response clone for the "response:*" life-cycle events.
// Ensure MSW is active and ready to handle the message, otherwise
@@ -204,7 +207,7 @@ async function resolveMainClient(event) {
* @param {string} requestId
* @returns {Promise<Response>}
*/
async function getResponse(event, client, requestId) {
async function getResponse(event, client, requestId, requestInterceptedAt) {
// Clone the request because it might've been already used
// (i.e. its body has been read and sent to the client).
const requestClone = event.request.clone()
@@ -255,6 +258,7 @@ async function getResponse(event, client, requestId) {
type: 'REQUEST',
payload: {
id: requestId,
interceptedAt: requestInterceptedAt,
...serializedRequest,
},
},

8
.storybook/styles.css Normal file
View File

@@ -0,0 +1,8 @@
a {
color: inherit;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}

View File

@@ -2,7 +2,87 @@
All notable changes to this project will be documented in this file.
## [4.4.0] - UNRELEASED
## [4.4.4] - 2025-09-16
### Security
- Update dependencies
### Fixed
- Fix missing memoization in `Web::PushNotificationWorker` (#36085 by @ClearlyClaire)
- Fix unresponsive areas around GIFV modals in some cases (#36059 by @ClearlyClaire)
- Fix missing `beforeUnload` confirmation when a poll is being authored (#36030 by @ClearlyClaire)
- Fix processing of remote edited statuses with new media and no text (#35970 by @unfokus)
- Fix polls not being displayed in moderation interface (#35644 and #35933 by @ThisIsMissEm)
- Fix WebUI handling of deleted quoted posts (#35909 and #35918 by @ClearlyClaire and @diondiondion)
- Fix “Edit” and “Delete & Redraft” on a poll not inserting empty option (#35892 by @ClearlyClaire)
- Fix loading of some compatibility CSS on some configurations (#35876 by @shleeable)
- Fix HttpLog not being enabled with `RAILS_LOG_LEVEL=debug` (#35833 by @mjankowski)
- Fix self-destruct scheduler behavior on some Redis setups (#35823 by @ClearlyClaire)
- Fix `tootctl admin create` not bypassing reserved username checks (#35779 by @ClearlyClaire)
- Fix interaction policy changes in implicit updates not being saved (#35751 by @ClearlyClaire)
- Fix quote revocation not being streamed (#35710 by @ClearlyClaire)
- Fix export of large user archives by enabling Zip64 (#35850 by @ClearlyClaire)
### Changed
- Change labels for quote policy settings (#35893 by @ClearlyClaire)
- Change standalone “Share” page to redirect to web interface after posting (#35763 by @ChaosExAnima)
## [4.4.3] - 2025-08-05
### Security
- Update dependencies
- Fix incorrect rate-limit handling [GHSA-84ch-6436-c7mg](https://github.com/mastodon/mastodon/security/advisories/GHSA-84ch-6436-c7mg)
### Fixed
- Fix race condition caused by ActiveRecord query cache in `Create` critical path (#35662 by @ClearlyClaire)
- Fix race condition caused by quote post processing (#35657 by @ClearlyClaire)
- Fix WebUI crashing for accounts with `null` URL (#35651 by @ClearlyClaire)
- Fix friends-of-friends recommendations suggesting already-requested accounts (#35604 by @ClearlyClaire)
- Fix synchronous recursive fetching of deeply-nested quoted posts (#35600 by @ClearlyClaire)
- Fix “Expand this post” link including user `@undefined` (#35478 by @ClearlyClaire)
### Changed
- Change `StatusReachFinder` to consider quotes as well as reblogs (#35601 by @ClearlyClaire)
- Add restrictions on which quote posts can trend (#35507 by @ClearlyClaire)
- Change quote verification to not bypass authorization flow for mentions (#35528 by @ClearlyClaire)
## [4.4.2] - 2025-07-23
### Security
- Update dependencies
### Fixed
- Fix menu not clickable in Firefox (#35390 and #35414 by @diondiondion)
- Add `lang` attribute to current composer language in alt text modal (#35412 by @diondiondion)
- Fix quote posts styling on notifications page (#35411 by @diondiondion)
- Improve a11y of custom select menus in notifications settings (#35403 by @diondiondion)
- Fix selected item in poll select menus is unreadable in Firefox (#35402 by @diondiondion)
- Update age limit wording (#35387 by @diondiondion)
- Fix support for quote verification in implicit status updates (#35384 by @ClearlyClaire)
- Improve `Dropdown` component accessibility (#35373 by @diondiondion)
- Fix processing some incoming quotes failing because of missing JSON-LD context (#35354 and #35380 by @ClearlyClaire)
- Make bio hashtags open the local page instead of the remote instance (#35349 by @ChaosExAnima)
- Fix styling of external log-in button (#35320 by @ClearlyClaire)
## [4.4.1] - 2025-07-09
### Fixed
- Fix nearly every sub-directory being crawled as part of Vite build (#35323 by @ClearlyClaire)
- Fix assets not building when Redis is unavailable (#35321 by @oneiros)
- Fix replying from media modal or pop-in-player tagging user `@undefined` (#35317 by @ClearlyClaire)
- Fix support for special characters in various environment variables (#35314 by @mjankowski and @ClearlyClaire)
- Fix some database migrations failing for indexes manually removed by admins (#35309 by @mjankowski)
## [4.4.0] - 2025-07-08
### Added
@@ -38,7 +118,7 @@ All notable changes to this project will be documented in this file.
Server administrators can now chose to opt in to transmit referrer information when following an external link. Only the domain name is transmitted, not the referrer path.
- Add double tap to zoom and swipe to dismiss to media modal in web UI (#34210 by @Gargron)
- Add link from Web UI for Hashtags to the Moderation UI (#31448 by @ThisIsMissEm)
- **Add terms of service** (#33055, #33233, #33230, #33703, #33699, #33994, #33993, #34105, #34122, #34200, #34527, #35053, #35115, #35126 and #35127 by @ClearlyClaire, @Gargron, @mjankowski, and @oneiros)\
- **Add terms of service** (#33055, #33233, #33230, #33703, #33699, #33994, #33993, #34105, #34122, #34200, #34527, #35053, #35115, #35126, #35127 and #35233 by @ClearlyClaire, @Gargron, @mjankowski, and @oneiros)\
Server administrators can now fill in Terms of Service and notify their users of upcoming changes.
- Add optional bulk mailer settings (#35191 and #35203 by @oneiros)\
This adds the optional environment variables `BULK_SMTP_PORT`, `BULK_SMTP_SERVER`, `BULK_SMTP_LOGIN` and so on analogous to `SMTP_PORT`, `SMTP_SERVER`, `SMTP_LOGIN` and related SMTP configuration environment variables.\
@@ -51,7 +131,7 @@ All notable changes to this project will be documented in this file.
- Add ability to dismiss alt text badge by tapping it in web UI (#33737 by @Gargron)
- Add loading indicator to timeline gap indicators in web UI (#33762 by @Gargron)
- Add interaction modal when trying to interact with a poll while logged out (#32609 by @ThisIsMissEm)
- **Add experimental FASP support** (#34031, #34415, #34765, #34965, #34964, #34033 and #35218 by @oneiros)\
- **Add experimental FASP support** (#34031, #34415, #34765, #34965, #34964, #34033, #35218, #35262 and #35263 by @oneiros)\
This is a first step towards supporting “Fediverse Auxiliary Service Providers” (https://github.com/mastodon/fediverse_auxiliary_service_provider_specifications). This is mostly interesting to developers who would like to implement their own FASP, but also includes the capability to share data with a discovery provider (see https://www.fediscovery.org).
- Add ability for admins to send announcements to all users via email (#33928 and #34411 by @ClearlyClaire)\
This is meant for critical announcements only, as this will potentially send a lot of emails and cannot be opted out of by users.
@@ -64,7 +144,7 @@ All notable changes to this project will be documented in this file.
- Add dropdown menu with quick actions to lists of accounts in web UI (#34391, #34709, and #34767 by @Gargron, @diondiondion, and @mkljczk)
- Add support for displaying “year in review” notification in web UI (#32710, #32765, #32709, #32807, #32914, #33148, and #33882 by @Gargron and @mjankowski)\
Note that the notification is currently not generated automatically, and at the moment requires a manual undocumented administrator action.
- Add experimental support for receiving HTTP Message Signatures (RFC9421) (#34814, #35033 and #35109 by @oneiros)\
- Add experimental support for receiving HTTP Message Signatures (RFC9421) (#34814, #35033, #35109 and #35278 by @oneiros)\
For now, this needs to be explicitly enabled through the `http_message_signatures` feature flag (`EXPERIMENTAL_FEATURES=http_message_signatures`). This currently only covers verifying such signatures (inbound HTTP requests), not issuing them (outbound HTTP requests).
- Add experimental Async Refreshes API (#34918 by @oneiros)
- Add experimental server-side feature to fetch remote replies (#32615, #34147, #34149, #34151, #34615, #34682, and #34702 by @ClearlyClaire and @sneakers-the-rat)\
@@ -218,6 +298,7 @@ All notable changes to this project will be documented in this file.
- Fix admin dashboard crash on specific Elasticsearch connection errors (#34683 by @ClearlyClaire)
- Fix OIDC account creation failing for long display names (#34639 by @defnull)
- Fix use of the deprecated `/api/v1/instance` endpoint in the moderation interface (#34613 by @renchap)
- Fix inaccessible Clear search button (#35152 and #35281 by @diondiondion)
- Fix search operators sometimes getting lost (#35190 by @ClearlyClaire)
- Fix directory scroll position reset (#34560 by @przucidlo)
- Fix needlessly complex SVG paths for oEmbed and logo (#34538 by @edent)
@@ -232,7 +313,7 @@ All notable changes to this project will be documented in this file.
- Fix extra space under left-indented vertical videos (#34313 by @ClearlyClaire)
- Fix glitchy iOS media attachment drag interactions (#35057 by @diondiondion)
- Fix zoomed images being blurry in Safari (#35052 by @diondiondion)
- Fix redundant focus stop within status component in Web UI and make focus style more noticeable (#35037, #35051, #35096 and #35150 by @diondiondion)
- Fix redundant focus stop within status component in Web UI and make focus style more noticeable (#35037, #35051, #35096, #35150 and #35251 by @diondiondion)
- Fix digits in media player time readout not having a consistent width (#35038 by @diondiondion)
- Fix wrong text color for Open in advanced web interface banner in high-contrast theme (#35032 by @diondiondion)
- Fix hover card for limited accounts not hiding information as expected (#35024 by @diondiondion)
@@ -530,7 +611,6 @@ The following changelog entries focus on changes visible to users, administrator
You can now separately filter or drop notifications from people you don't follow, people who don't follow you, accounts created within the past 30 days, as well as unsolicited private mentions, and accounts limited by the moderation.\
Instead of being outright dropped, notifications that you chose to filter are put in a separate Filtered notifications box that you can review separately without it clogging your main notifications.\
This adds the following REST API endpoints:
- `GET /api/v2/notifications/policy`: https://docs.joinmastodon.org/methods/notifications/#get-policy
- `PATCH /api/v2/notifications/policy`: https://docs.joinmastodon.org/methods/notifications/#update-the-filtering-policy-for-notifications
- `GET /api/v1/notifications/requests`: https://docs.joinmastodon.org/methods/notifications/#get-requests
@@ -542,7 +622,6 @@ The following changelog entries focus on changes visible to users, administrator
- `GET /api/v1/notifications/requests/merged`: https://docs.joinmastodon.org/methods/notifications/#requests-merged
In addition, accepting one or more notification requests generates a new streaming event:
- `notifications_merged`: an event of this type indicates accepted notification requests have finished merging, and the notifications list should be refreshed
- **Add notifications of severed relationships** (#27511, #29665, #29668, #29670, #29700, #29714, #29712, and #29731 by @ClearlyClaire and @Gargron)\

View File

@@ -1,4 +1,4 @@
# syntax=docker/dockerfile:1.12
# syntax=docker/dockerfile:1.18
# This file is designed for production server deployment, not local development work
# For a containerized local dev environment, see: https://github.com/mastodon/mastodon/blob/main/docs/DEVELOPMENT.md#docker
@@ -13,15 +13,15 @@ ARG BASE_REGISTRY="docker.io"
# Ruby image to use for base image, change with [--build-arg RUBY_VERSION="3.4.x"]
# renovate: datasource=docker depName=docker.io/ruby
ARG RUBY_VERSION="3.4.4"
ARG RUBY_VERSION="3.4.6"
# # Node.js version to use in base image, change with [--build-arg NODE_MAJOR_VERSION="20"]
# renovate: datasource=node-version depName=node
ARG NODE_MAJOR_VERSION="22"
# Debian image to use for base image, change with [--build-arg DEBIAN_VERSION="bookworm"]
ARG DEBIAN_VERSION="bookworm"
# Node.js image to use for base image based on combined variables (ex: 20-bookworm-slim)
# Debian image to use for base image, change with [--build-arg DEBIAN_VERSION="trixie"]
ARG DEBIAN_VERSION="trixie"
# Node.js image to use for base image based on combined variables (ex: 20-trixie-slim)
FROM ${BASE_REGISTRY}/node:${NODE_MAJOR_VERSION}-${DEBIAN_VERSION}-slim AS node
# Ruby image to use for base image based on combined variables (ex: 3.4.x-slim-bookworm)
# Ruby image to use for base image based on combined variables (ex: 3.4.x-slim-trixie)
FROM ${BASE_REGISTRY}/ruby:${RUBY_VERSION}-slim-${DEBIAN_VERSION} AS ruby
# Resulting version string is vX.X.X-MASTODON_VERSION_PRERELEASE+MASTODON_VERSION_METADATA
@@ -96,9 +96,6 @@ RUN \
# Set /opt/mastodon as working directory
WORKDIR /opt/mastodon
# Add backport repository for some specific packages where we need the latest version
RUN echo 'deb http://deb.debian.org/debian bookworm-backports main' >> /etc/apt/sources.list
# hadolint ignore=DL3008,DL3005
RUN \
# Mount Apt cache and lib directories from Docker buildx caches
@@ -161,11 +158,11 @@ RUN \
libexif-dev \
libexpat1-dev \
libgirepository1.0-dev \
libheif-dev/bookworm-backports \
libheif-dev \
libhwy-dev \
libimagequant-dev \
libjpeg62-turbo-dev \
liblcms2-dev \
liborc-dev \
libspng-dev \
libtiff-dev \
libwebp-dev \
@@ -186,7 +183,7 @@ FROM build AS libvips
# libvips version to compile, change with [--build-arg VIPS_VERSION="8.15.2"]
# renovate: datasource=github-releases depName=libvips packageName=libvips/libvips
ARG VIPS_VERSION=8.17.0
ARG VIPS_VERSION=8.17.2
# libvips download URL, change with [--build-arg VIPS_URL="https://github.com/libvips/libvips/releases/download"]
ARG VIPS_URL=https://github.com/libvips/libvips/releases/download
@@ -209,7 +206,7 @@ FROM build AS ffmpeg
# ffmpeg version to compile, change with [--build-arg FFMPEG_VERSION="7.0.x"]
# renovate: datasource=repology depName=ffmpeg packageName=openpkg_current/ffmpeg
ARG FFMPEG_VERSION=7.1
ARG FFMPEG_VERSION=8.0
# ffmpeg download URL, change with [--build-arg FFMPEG_URL="https://ffmpeg.org/releases"]
ARG FFMPEG_URL=https://ffmpeg.org/releases
@@ -327,28 +324,28 @@ RUN \
# Apt update install non-dev versions of necessary components
apt-get install -y --no-install-recommends \
libexpat1 \
libglib2.0-0 \
libicu72 \
libglib2.0-0t64 \
libicu76 \
libidn12 \
libpq5 \
libreadline8 \
libssl3 \
libreadline8t64 \
libssl3t64 \
libyaml-0-2 \
# libvips components
libcgif0 \
libexif12 \
libheif1/bookworm-backports \
libheif1 \
libhwy1t64 \
libimagequant0 \
libjpeg62-turbo \
liblcms2-2 \
liborc-0.4-0 \
libspng0 \
libtiff6 \
libwebp7 \
libwebpdemux2 \
libwebpmux3 \
# ffmpeg components
libdav1d6 \
libdav1d7 \
libmp3lame0 \
libopencore-amrnb0 \
libopencore-amrwb0 \
@@ -358,9 +355,9 @@ RUN \
libvorbis0a \
libvorbisenc2 \
libvorbisfile3 \
libvpx7 \
libvpx9 \
libx264-164 \
libx265-199 \
libx265-215 \
;
# Copy Mastodon sources into final layer

27
Gemfile
View File

@@ -62,7 +62,7 @@ gem 'inline_svg'
gem 'irb', '~> 1.8'
gem 'kaminari', '~> 1.2'
gem 'link_header', '~> 0.0'
gem 'linzer', '~> 0.7.2'
gem 'linzer', '~> 0.7.7'
gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock'
gem 'mime-types', '~> 3.7.0', require: 'mime/types/columnar'
gem 'mutex_m'
@@ -82,13 +82,13 @@ gem 'rqrcode', '~> 3.0'
gem 'ruby-progressbar', '~> 1.13'
gem 'sanitize', '~> 7.0'
gem 'scenic', '~> 1.7'
gem 'sidekiq', '< 8'
gem 'sidekiq', '< 9'
gem 'sidekiq-bulk', '~> 0.2.0'
gem 'sidekiq-scheduler', '~> 5.0'
gem 'sidekiq-scheduler', '~> 6.0'
gem 'sidekiq-unique-jobs', '> 8'
gem 'simple_form', '~> 5.2'
gem 'simple-navigation', '~> 4.4'
gem 'stoplight', '~> 4.1'
gem 'stoplight'
gem 'strong_migrations'
gem 'tty-prompt', '~> 0.23', require: false
gem 'twitter-text', '~> 3.1.0'
@@ -102,21 +102,21 @@ gem 'rdf-normalize', '~> 0.5'
gem 'prometheus_exporter', '~> 2.2', require: false
gem 'opentelemetry-api', '~> 1.5.0'
gem 'opentelemetry-api', '~> 1.7.0'
group :opentelemetry do
gem 'opentelemetry-exporter-otlp', '~> 0.30.0', require: false
gem 'opentelemetry-instrumentation-active_job', '~> 0.8.0', require: false
gem 'opentelemetry-instrumentation-active_model_serializers', '~> 0.22.0', require: false
gem 'opentelemetry-instrumentation-concurrent_ruby', '~> 0.22.0', require: false
gem 'opentelemetry-instrumentation-excon', '~> 0.23.0', require: false
gem 'opentelemetry-instrumentation-faraday', '~> 0.27.0', require: false
gem 'opentelemetry-instrumentation-excon', '~> 0.24.0', require: false
gem 'opentelemetry-instrumentation-faraday', '~> 0.28.0', require: false
gem 'opentelemetry-instrumentation-http', '~> 0.25.0', require: false
gem 'opentelemetry-instrumentation-http_client', '~> 0.23.0', require: false
gem 'opentelemetry-instrumentation-net_http', '~> 0.23.0', require: false
gem 'opentelemetry-instrumentation-http_client', '~> 0.24.0', require: false
gem 'opentelemetry-instrumentation-net_http', '~> 0.24.0', require: false
gem 'opentelemetry-instrumentation-pg', '~> 0.30.0', require: false
gem 'opentelemetry-instrumentation-rack', '~> 0.26.0', require: false
gem 'opentelemetry-instrumentation-rails', '~> 0.36.0', require: false
gem 'opentelemetry-instrumentation-rack', '~> 0.27.0', require: false
gem 'opentelemetry-instrumentation-rails', '~> 0.37.0', require: false
gem 'opentelemetry-instrumentation-redis', '~> 0.26.0', require: false
gem 'opentelemetry-instrumentation-sidekiq', '~> 0.26.0', require: false
gem 'opentelemetry-sdk', '~> 1.4', require: false
@@ -138,6 +138,7 @@ group :test do
# Browser integration testing
gem 'capybara', '~> 3.39'
gem 'capybara-playwright-driver'
gem 'playwright-ruby-client', '1.55.0', require: false # Pinning the exact version as it needs to be kept in sync with the installed npm package
# Used to reset the database between system tests
gem 'database_cleaner-active_record'
@@ -146,7 +147,7 @@ group :test do
gem 'climate_control'
# Validate schemas in specs
gem 'json-schema', '~> 5.0'
gem 'json-schema', '~> 6.0'
# Test harness fo rack components
gem 'rack-test', '~> 2.1'
@@ -223,7 +224,7 @@ gem 'connection_pool', require: false
gem 'xorcist', '~> 1.1'
gem 'net-http', '~> 0.6.0'
gem 'rubyzip', '~> 2.3'
gem 'rubyzip', '~> 3.0'
gem 'hcaptcha', '~> 7.1'

View File

@@ -10,29 +10,29 @@ GIT
GEM
remote: https://rubygems.org/
specs:
actioncable (8.0.2)
actionpack (= 8.0.2)
activesupport (= 8.0.2)
actioncable (8.0.2.1)
actionpack (= 8.0.2.1)
activesupport (= 8.0.2.1)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
zeitwerk (~> 2.6)
actionmailbox (8.0.2)
actionpack (= 8.0.2)
activejob (= 8.0.2)
activerecord (= 8.0.2)
activestorage (= 8.0.2)
activesupport (= 8.0.2)
actionmailbox (8.0.2.1)
actionpack (= 8.0.2.1)
activejob (= 8.0.2.1)
activerecord (= 8.0.2.1)
activestorage (= 8.0.2.1)
activesupport (= 8.0.2.1)
mail (>= 2.8.0)
actionmailer (8.0.2)
actionpack (= 8.0.2)
actionview (= 8.0.2)
activejob (= 8.0.2)
activesupport (= 8.0.2)
actionmailer (8.0.2.1)
actionpack (= 8.0.2.1)
actionview (= 8.0.2.1)
activejob (= 8.0.2.1)
activesupport (= 8.0.2.1)
mail (>= 2.8.0)
rails-dom-testing (~> 2.2)
actionpack (8.0.2)
actionview (= 8.0.2)
activesupport (= 8.0.2)
actionpack (8.0.2.1)
actionview (= 8.0.2.1)
activesupport (= 8.0.2.1)
nokogiri (>= 1.8.5)
rack (>= 2.2.4)
rack-session (>= 1.0.1)
@@ -40,15 +40,15 @@ GEM
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
useragent (~> 0.16)
actiontext (8.0.2)
actionpack (= 8.0.2)
activerecord (= 8.0.2)
activestorage (= 8.0.2)
activesupport (= 8.0.2)
actiontext (8.0.2.1)
actionpack (= 8.0.2.1)
activerecord (= 8.0.2.1)
activestorage (= 8.0.2.1)
activesupport (= 8.0.2.1)
globalid (>= 0.6.0)
nokogiri (>= 1.8.5)
actionview (8.0.2)
activesupport (= 8.0.2)
actionview (8.0.2.1)
activesupport (= 8.0.2.1)
builder (~> 3.1)
erubi (~> 1.11)
rails-dom-testing (~> 2.2)
@@ -58,22 +58,22 @@ GEM
activemodel (>= 4.1)
case_transform (>= 0.2)
jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
activejob (8.0.2)
activesupport (= 8.0.2)
activejob (8.0.2.1)
activesupport (= 8.0.2.1)
globalid (>= 0.3.6)
activemodel (8.0.2)
activesupport (= 8.0.2)
activerecord (8.0.2)
activemodel (= 8.0.2)
activesupport (= 8.0.2)
activemodel (8.0.2.1)
activesupport (= 8.0.2.1)
activerecord (8.0.2.1)
activemodel (= 8.0.2.1)
activesupport (= 8.0.2.1)
timeout (>= 0.4.0)
activestorage (8.0.2)
actionpack (= 8.0.2)
activejob (= 8.0.2)
activerecord (= 8.0.2)
activesupport (= 8.0.2)
activestorage (8.0.2.1)
actionpack (= 8.0.2.1)
activejob (= 8.0.2.1)
activerecord (= 8.0.2.1)
activesupport (= 8.0.2.1)
marcel (~> 1.0)
activesupport (8.0.2)
activesupport (8.0.2.1)
base64
benchmark (>= 0.3)
bigdecimal
@@ -90,13 +90,13 @@ GEM
public_suffix (>= 2.0.2, < 7.0)
aes_key_wrap (1.1.0)
android_key_attestation (0.3.0)
annotaterb (4.16.0)
annotaterb (4.19.0)
activerecord (>= 6.0.0)
activesupport (>= 6.0.0)
ast (2.4.3)
attr_required (1.0.2)
aws-eventstream (1.3.2)
aws-partitions (1.1103.0)
aws-eventstream (1.4.0)
aws-partitions (1.1135.0)
aws-sdk-core (3.215.1)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.992.0)
@@ -109,9 +109,9 @@ GEM
aws-sdk-core (~> 3, >= 3.210.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.5)
aws-sigv4 (1.11.0)
aws-sigv4 (1.12.1)
aws-eventstream (~> 1, >= 1.0.2)
azure-blob (0.5.8)
azure-blob (0.5.9.1)
rexml
base64 (0.3.0)
bcp47_spec (0.2.1)
@@ -121,7 +121,7 @@ GEM
erubi (>= 1.0.0)
rack (>= 0.9.0)
rouge (>= 1.0.0)
bigdecimal (3.2.2)
bigdecimal (3.2.3)
bindata (2.5.1)
binding_of_caller (1.0.1)
debug_inspector (>= 1.2.0)
@@ -144,7 +144,7 @@ GEM
rack-test (>= 0.6.3)
regexp_parser (>= 1.5, < 3.0)
xpath (~> 3.2)
capybara-playwright-driver (0.5.6)
capybara-playwright-driver (0.5.7)
addressable
capybara
playwright-ruby-client (>= 1.16.0)
@@ -164,7 +164,7 @@ GEM
cocoon (1.2.15)
color_diff (0.1)
concurrent-ruby (1.3.5)
connection_pool (2.5.3)
connection_pool (2.5.4)
cose (1.3.1)
cbor (~> 0.5.9)
openssl-signature_algorithm (~> 1.0)
@@ -175,9 +175,9 @@ GEM
css_parser (1.21.1)
addressable
csv (3.3.5)
database_cleaner-active_record (2.2.1)
database_cleaner-active_record (2.2.2)
activerecord (>= 5.a)
database_cleaner-core (~> 2.0.0)
database_cleaner-core (~> 2.0)
database_cleaner-core (2.0.1)
date (3.4.1)
debug (1.11.0)
@@ -224,16 +224,16 @@ GEM
mail (~> 2.7)
email_validator (2.2.4)
activemodel
erb (5.0.1)
erb (5.0.2)
erubi (1.13.1)
et-orbi (1.2.11)
tzinfo
excon (1.2.5)
excon (1.2.8)
logger
fabrication (3.0.0)
faker (3.5.1)
faker (3.5.2)
i18n (>= 1.8.11, < 2)
faraday (2.13.1)
faraday (2.13.4)
faraday-net_http (>= 2.0, < 3.5)
json
logger
@@ -241,7 +241,7 @@ GEM
faraday (>= 1, < 3)
faraday-httpclient (2.0.2)
httpclient (>= 2.2)
faraday-net_http (3.4.0)
faraday-net_http (3.4.1)
net-http (>= 0.5.0)
fast_blank (1.0.1)
fastimage (2.4.0)
@@ -266,14 +266,14 @@ GEM
fog-openstack (1.1.5)
fog-core (~> 2.1)
fog-json (>= 1.0)
formatador (1.1.0)
formatador (1.1.1)
forwardable (1.3.3)
fugit (1.11.1)
et-orbi (~> 1, >= 1.2.11)
raabro (~> 1.4)
globalid (1.2.1)
activesupport (>= 6.1)
google-protobuf (4.31.0)
google-protobuf (4.31.1)
bigdecimal
rake (>= 13)
googleapis-common-protos-types (1.20.0)
@@ -287,21 +287,21 @@ GEM
activesupport (>= 5.1)
haml (>= 4.0.6)
railties (>= 5.1)
haml_lint (0.64.0)
haml_lint (0.66.0)
haml (>= 5.0)
parallel (~> 1.10)
rainbow
rubocop (>= 1.0)
sysexits (~> 1.1)
hashdiff (1.1.2)
hashdiff (1.2.0)
hashie (5.0.0)
hcaptcha (7.1.0)
json
highline (3.1.2)
reline
hiredis (0.6.3)
hiredis-client (0.24.0)
redis-client (= 0.24.0)
hiredis-client (0.25.3)
redis-client (= 0.25.3)
hkdf (0.3.0)
htmlentities (4.3.4)
http (5.3.1)
@@ -315,7 +315,7 @@ GEM
http_accept_language (2.1.1)
httpclient (2.9.0)
mutex_m
httplog (1.7.0)
httplog (1.7.3)
rack (>= 2.0)
rainbow (>= 2.0.0)
i18n (1.14.7)
@@ -335,7 +335,7 @@ GEM
inline_svg (1.10.0)
activesupport (>= 3.0)
nokogiri (>= 1.6)
io-console (0.8.0)
io-console (0.8.1)
irb (1.15.2)
pp (>= 0.6.0)
rdoc (>= 4.0.0)
@@ -345,7 +345,7 @@ GEM
azure-blob (~> 0.5.2)
hashie (~> 5.0)
jmespath (1.6.2)
json (2.12.2)
json (2.13.2)
json-canonicalization (1.0.0)
json-jwt (1.16.7)
activesupport (>= 4.2)
@@ -362,14 +362,14 @@ GEM
rack (>= 2.2, < 4)
rdf (~> 3.3)
rexml (~> 3.2)
json-ld-preloaded (3.3.1)
json-ld-preloaded (3.3.2)
json-ld (~> 3.3)
rdf (~> 3.3)
json-schema (5.1.1)
json-schema (6.0.0)
addressable (~> 2.8)
bigdecimal (~> 3.1)
jsonapi-renderer (0.2.2)
jwt (2.10.1)
jwt (2.10.2)
base64
kaminari (1.2.2)
activesupport (>= 4.1.0)
@@ -403,7 +403,7 @@ GEM
rexml
link_header (0.0.8)
lint_roller (1.1.0)
linzer (0.7.3)
linzer (0.7.7)
cgi (~> 0.4.2)
forwardable (~> 1.3, >= 1.3.3)
logger (~> 1.7, >= 1.7.0)
@@ -433,24 +433,26 @@ GEM
marcel (1.0.4)
mario-redis-lock (1.2.1)
redis (>= 3.0.5)
matrix (0.4.2)
matrix (0.4.3)
memory_profiler (1.1.0)
mime-types (3.7.0)
logger
mime-types-data (~> 3.2025, >= 3.2025.0507)
mime-types-data (3.2025.0514)
mime-types-data (3.2025.0916)
mini_mime (1.1.5)
mini_portile2 (2.8.9)
minitest (5.25.5)
msgpack (1.8.0)
multi_json (1.15.0)
multi_json (1.17.0)
mutex_m (0.3.0)
net-http (0.6.0)
uri
net-imap (0.5.8)
net-imap (0.5.9)
date
net-protocol
net-ldap (0.19.0)
net-ldap (0.20.0)
base64
ostruct
net-pop (0.1.2)
net-protocol
net-protocol (0.2.2)
@@ -458,7 +460,7 @@ GEM
net-smtp (0.5.1)
net-protocol
nio4r (2.7.4)
nokogiri (1.18.8)
nokogiri (1.18.10)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
oj (3.16.11)
@@ -468,7 +470,7 @@ GEM
hashie (>= 3.4.6)
rack (>= 2.2.3)
rack-protection
omniauth-cas (3.0.1)
omniauth-cas (3.0.2)
addressable (~> 2.8)
nokogiri (~> 1.12)
omniauth (~> 2.1)
@@ -497,7 +499,7 @@ GEM
openssl (3.3.0)
openssl-signature_algorithm (1.3.0)
openssl (> 2.0)
opentelemetry-api (1.5.0)
opentelemetry-api (1.7.0)
opentelemetry-common (0.22.0)
opentelemetry-api (~> 1.0)
opentelemetry-exporter-otlp (0.30.0)
@@ -515,7 +517,7 @@ GEM
opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-active_support (~> 0.7)
opentelemetry-instrumentation-base (~> 0.23.0)
opentelemetry-instrumentation-action_pack (0.12.1)
opentelemetry-instrumentation-action_pack (0.13.0)
opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-base (~> 0.23.0)
opentelemetry-instrumentation-rack (~> 0.21)
@@ -547,19 +549,19 @@ GEM
opentelemetry-instrumentation-concurrent_ruby (0.22.0)
opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-base (~> 0.23.0)
opentelemetry-instrumentation-excon (0.23.0)
opentelemetry-instrumentation-excon (0.24.0)
opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-base (~> 0.23.0)
opentelemetry-instrumentation-faraday (0.27.0)
opentelemetry-instrumentation-faraday (0.28.0)
opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-base (~> 0.23.0)
opentelemetry-instrumentation-http (0.25.0)
opentelemetry-instrumentation-http (0.25.1)
opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-base (~> 0.23.0)
opentelemetry-instrumentation-http_client (0.23.0)
opentelemetry-instrumentation-http_client (0.24.0)
opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-base (~> 0.23.0)
opentelemetry-instrumentation-net_http (0.23.0)
opentelemetry-instrumentation-net_http (0.24.0)
opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-base (~> 0.23.0)
opentelemetry-instrumentation-pg (0.30.1)
@@ -567,13 +569,13 @@ GEM
opentelemetry-helpers-sql
opentelemetry-helpers-sql-obfuscation
opentelemetry-instrumentation-base (~> 0.23.0)
opentelemetry-instrumentation-rack (0.26.0)
opentelemetry-instrumentation-rack (0.27.1)
opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-base (~> 0.23.0)
opentelemetry-instrumentation-rails (0.36.0)
opentelemetry-instrumentation-rails (0.37.0)
opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-action_mailer (~> 0.4.0)
opentelemetry-instrumentation-action_pack (~> 0.12.0)
opentelemetry-instrumentation-action_pack (~> 0.13.0)
opentelemetry-instrumentation-action_view (~> 0.9.0)
opentelemetry-instrumentation-active_job (~> 0.8.0)
opentelemetry-instrumentation-active_record (~> 0.9.0)
@@ -589,28 +591,28 @@ GEM
opentelemetry-instrumentation-base (~> 0.23.0)
opentelemetry-registry (0.4.0)
opentelemetry-api (~> 1.1)
opentelemetry-sdk (1.8.0)
opentelemetry-sdk (1.9.0)
opentelemetry-api (~> 1.1)
opentelemetry-common (~> 0.20)
opentelemetry-registry (~> 0.2)
opentelemetry-semantic_conventions
opentelemetry-semantic_conventions (1.11.0)
opentelemetry-semantic_conventions (1.36.0)
opentelemetry-api (~> 1.0)
orm_adapter (0.5.0)
ostruct (0.6.1)
ostruct (0.6.3)
ox (2.14.23)
bigdecimal (>= 3.0)
parallel (1.27.0)
parser (3.3.8.0)
parser (3.3.9.0)
ast (~> 2.4.1)
racc
parslet (2.0.0)
pastel (0.8.0)
tty-color (~> 0.5)
pg (1.5.9)
pg (1.6.2)
pghero (3.7.0)
activerecord (>= 7.1)
playwright-ruby-client (1.52.0)
playwright-ruby-client (1.55.0)
concurrent-ruby (>= 1.1.6)
mime-types (>= 3.0)
pp (0.6.2)
@@ -625,20 +627,19 @@ GEM
premailer (~> 1.7, >= 1.7.9)
prettyprint (0.2.0)
prism (1.4.0)
prometheus_exporter (2.2.0)
prometheus_exporter (2.3.0)
webrick
propshaft (1.1.0)
propshaft (1.2.1)
actionpack (>= 7.0.0)
activesupport (>= 7.0.0)
rack
railties (>= 7.0.0)
psych (5.2.6)
date
stringio
public_suffix (6.0.2)
puma (6.6.0)
puma (6.6.1)
nio4r (~> 2.0)
pundit (2.5.0)
pundit (2.5.1)
activesupport (>= 3.0.0)
raabro (1.4.0)
racc (1.8.1)
@@ -668,33 +669,33 @@ GEM
rack (>= 1.3)
rackup (2.2.1)
rack (>= 3)
rails (8.0.2)
actioncable (= 8.0.2)
actionmailbox (= 8.0.2)
actionmailer (= 8.0.2)
actionpack (= 8.0.2)
actiontext (= 8.0.2)
actionview (= 8.0.2)
activejob (= 8.0.2)
activemodel (= 8.0.2)
activerecord (= 8.0.2)
activestorage (= 8.0.2)
activesupport (= 8.0.2)
rails (8.0.2.1)
actioncable (= 8.0.2.1)
actionmailbox (= 8.0.2.1)
actionmailer (= 8.0.2.1)
actionpack (= 8.0.2.1)
actiontext (= 8.0.2.1)
actionview (= 8.0.2.1)
activejob (= 8.0.2.1)
activemodel (= 8.0.2.1)
activerecord (= 8.0.2.1)
activestorage (= 8.0.2.1)
activesupport (= 8.0.2.1)
bundler (>= 1.15.0)
railties (= 8.0.2)
rails-dom-testing (2.2.0)
railties (= 8.0.2.1)
rails-dom-testing (2.3.0)
activesupport (>= 5.0.0)
minitest
nokogiri (>= 1.6)
rails-html-sanitizer (1.6.2)
loofah (~> 2.21)
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
rails-i18n (8.0.1)
rails-i18n (8.0.2)
i18n (>= 0.7, < 2)
railties (>= 8.0.0, < 9)
railties (8.0.2)
actionpack (= 8.0.2)
activesupport (= 8.0.2)
railties (8.0.2.1)
actionpack (= 8.0.2.1)
activesupport (= 8.0.2.1)
irb (~> 1.13)
rackup (>= 1.0.0)
rake (>= 12.2)
@@ -702,42 +703,45 @@ GEM
zeitwerk (~> 2.6)
rainbow (3.1.1)
rake (13.3.0)
rdf (3.3.2)
rdf (3.3.4)
bcp47_spec (~> 0.2)
bigdecimal (~> 3.1, >= 3.1.5)
link_header (~> 0.0, >= 0.0.8)
logger (~> 1.5)
ostruct (~> 0.6)
readline (~> 0.0)
rdf-normalize (0.7.0)
rdf (~> 3.3)
rdoc (6.14.1)
rdoc (6.14.2)
erb
psych (>= 4.0.0)
readline (0.0.4)
reline
redcarpet (3.6.1)
redis (4.8.1)
redis-client (0.24.0)
redis-client (0.25.3)
connection_pool
redlock (1.3.2)
redis (>= 3.0.0, < 6.0)
regexp_parser (2.10.0)
reline (0.6.1)
regexp_parser (2.11.2)
reline (0.6.2)
io-console (~> 0.5)
request_store (1.7.0)
rack (>= 1.4)
responders (3.1.1)
actionpack (>= 5.2)
railties (>= 5.2)
rexml (3.4.1)
rexml (3.4.4)
rotp (6.3.0)
rouge (4.5.2)
rouge (4.6.0)
rpam2 (4.0.2)
rqrcode (3.1.0)
chunky_png (~> 1.0)
rqrcode_core (~> 2.0)
rqrcode_core (2.0.0)
rspec (3.13.0)
rspec (3.13.1)
rspec-core (~> 3.13.0)
rspec-expectations (~> 3.13.0)
rspec-mocks (~> 3.13.0)
rspec-core (3.13.4)
rspec-core (3.13.5)
rspec-support (~> 3.13.0)
rspec-expectations (3.13.5)
diff-lcs (>= 1.2.0, < 2.0)
@@ -747,7 +751,7 @@ GEM
rspec-mocks (3.13.5)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0)
rspec-rails (8.0.1)
rspec-rails (8.0.2)
actionpack (>= 7.2)
activesupport (>= 7.2)
railties (>= 7.2)
@@ -755,13 +759,13 @@ GEM
rspec-expectations (~> 3.13)
rspec-mocks (~> 3.13)
rspec-support (~> 3.13)
rspec-sidekiq (5.1.0)
rspec-sidekiq (5.2.0)
rspec-core (~> 3.0)
rspec-expectations (~> 3.0)
rspec-mocks (~> 3.0)
sidekiq (>= 5, < 9)
rspec-support (3.13.4)
rubocop (1.77.0)
rubocop (1.80.2)
json (~> 2.3)
language_server-protocol (~> 3.17.0.2)
lint_roller (~> 1.1.0)
@@ -769,10 +773,10 @@ GEM
parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 2.9.3, < 3.0)
rubocop-ast (>= 1.45.1, < 2.0)
rubocop-ast (>= 1.46.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 4.0)
rubocop-ast (1.45.1)
rubocop-ast (1.46.0)
parser (>= 3.3.7.2)
prism (~> 1.4)
rubocop-capybara (2.22.1)
@@ -781,17 +785,17 @@ GEM
rubocop-i18n (3.2.3)
lint_roller (~> 1.1)
rubocop (>= 1.72.1)
rubocop-performance (1.25.0)
rubocop-performance (1.26.0)
lint_roller (~> 1.1)
rubocop (>= 1.75.0, < 2.0)
rubocop-ast (>= 1.38.0, < 2.0)
rubocop-rails (2.32.0)
rubocop-ast (>= 1.44.0, < 2.0)
rubocop-rails (2.33.3)
activesupport (>= 4.2.0)
lint_roller (~> 1.1)
rack (>= 1.1)
rubocop (>= 1.75.0, < 2.0)
rubocop-ast (>= 1.44.0, < 2.0)
rubocop-rspec (3.6.0)
rubocop-rspec (3.7.0)
lint_roller (~> 1.1)
rubocop (~> 1.72, >= 1.72.1)
rubocop-rspec_rails (2.31.0)
@@ -801,13 +805,13 @@ GEM
ruby-prof (1.7.2)
base64
ruby-progressbar (1.13.0)
ruby-saml (1.18.0)
ruby-saml (1.18.1)
nokogiri (>= 1.13.10)
rexml
ruby-vips (2.2.4)
ruby-vips (2.2.5)
ffi (~> 1.12)
logger
rubyzip (2.4.1)
rubyzip (3.1.0)
rufus-scheduler (3.9.2)
fugit (~> 1.1, >= 1.11.1)
safety_net_attestation (0.4.0)
@@ -815,24 +819,23 @@ GEM
sanitize (7.0.0)
crass (~> 1.0.2)
nokogiri (>= 1.16.8)
scenic (1.8.0)
scenic (1.9.0)
activerecord (>= 4.0.0)
railties (>= 4.0.0)
securerandom (0.4.1)
shoulda-matchers (6.5.0)
activesupport (>= 5.2.0)
sidekiq (7.3.9)
base64
connection_pool (>= 2.3.0)
logger
rack (>= 2.2.4)
redis-client (>= 0.22.2)
sidekiq (8.0.7)
connection_pool (>= 2.5.0)
json (>= 2.9.0)
logger (>= 1.6.2)
rack (>= 3.1.0)
redis-client (>= 0.23.2)
sidekiq-bulk (0.2.0)
sidekiq
sidekiq-scheduler (5.0.6)
sidekiq-scheduler (6.0.1)
rufus-scheduler (~> 3.2)
sidekiq (>= 6, < 8)
tilt (>= 1.4.0, < 3)
sidekiq (>= 7.3, < 9)
sidekiq-unique-jobs (8.0.11)
concurrent-ruby (~> 1.0, >= 1.0.5)
sidekiq (>= 7.0.0, < 9.0.0)
@@ -846,16 +849,16 @@ GEM
docile (~> 1.1)
simplecov-html (~> 0.11)
simplecov_json_formatter (~> 0.1)
simplecov-html (0.13.1)
simplecov-lcov (0.8.0)
simplecov-html (0.13.2)
simplecov-lcov (0.9.0)
simplecov_json_formatter (0.1.4)
stackprof (0.2.27)
starry (0.2.0)
base64
stoplight (4.1.1)
redlock (~> 1.0)
stoplight (5.3.8)
zeitwerk
stringio (3.1.7)
strong_migrations (2.4.0)
strong_migrations (2.5.0)
activerecord (>= 7.1)
swd (2.0.3)
activesupport (>= 3)
@@ -863,14 +866,14 @@ GEM
faraday (~> 2.0)
faraday-follow_redirects
sysexits (1.2.0)
temple (0.10.3)
temple (0.10.4)
terminal-table (4.0.0)
unicode-display_width (>= 1.1.1, < 4)
terrapin (1.1.0)
terrapin (1.1.1)
climate_control
test-prof (1.4.4)
thor (1.3.2)
tilt (2.6.0)
thor (1.4.0)
tilt (2.6.1)
timeout (0.4.3)
tpm-key_attestation (0.14.1)
bindata (~> 2.4)
@@ -896,7 +899,7 @@ GEM
unf (0.1.4)
unf_ext
unf_ext (0.0.9.1)
unicode-display_width (3.1.4)
unicode-display_width (3.1.5)
unicode-emoji (~> 4.0, >= 4.0.4)
unicode-emoji (4.0.4)
uri (1.0.3)
@@ -932,7 +935,7 @@ GEM
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
webrick (1.9.1)
websocket-driver (0.7.7)
websocket-driver (0.8.0)
base64
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
@@ -1002,13 +1005,13 @@ DEPENDENCIES
jd-paperclip-azure (~> 3.0)
json-ld
json-ld-preloaded (~> 3.2)
json-schema (~> 5.0)
json-schema (~> 6.0)
kaminari (~> 1.2)
kt-paperclip (~> 7.2)
letter_opener (~> 1.8)
letter_opener_web (~> 3.0)
link_header (~> 0.0)
linzer (~> 0.7.2)
linzer (~> 0.7.7)
lograge (~> 0.12)
mail (~> 2.8)
mario-redis-lock (~> 1.2)
@@ -1024,19 +1027,19 @@ DEPENDENCIES
omniauth-rails_csrf_protection (~> 1.0)
omniauth-saml (~> 2.0)
omniauth_openid_connect (~> 0.8.0)
opentelemetry-api (~> 1.5.0)
opentelemetry-api (~> 1.7.0)
opentelemetry-exporter-otlp (~> 0.30.0)
opentelemetry-instrumentation-active_job (~> 0.8.0)
opentelemetry-instrumentation-active_model_serializers (~> 0.22.0)
opentelemetry-instrumentation-concurrent_ruby (~> 0.22.0)
opentelemetry-instrumentation-excon (~> 0.23.0)
opentelemetry-instrumentation-faraday (~> 0.27.0)
opentelemetry-instrumentation-excon (~> 0.24.0)
opentelemetry-instrumentation-faraday (~> 0.28.0)
opentelemetry-instrumentation-http (~> 0.25.0)
opentelemetry-instrumentation-http_client (~> 0.23.0)
opentelemetry-instrumentation-net_http (~> 0.23.0)
opentelemetry-instrumentation-http_client (~> 0.24.0)
opentelemetry-instrumentation-net_http (~> 0.24.0)
opentelemetry-instrumentation-pg (~> 0.30.0)
opentelemetry-instrumentation-rack (~> 0.26.0)
opentelemetry-instrumentation-rails (~> 0.36.0)
opentelemetry-instrumentation-rack (~> 0.27.0)
opentelemetry-instrumentation-rails (~> 0.37.0)
opentelemetry-instrumentation-redis (~> 0.26.0)
opentelemetry-instrumentation-sidekiq (~> 0.26.0)
opentelemetry-sdk (~> 1.4)
@@ -1044,6 +1047,7 @@ DEPENDENCIES
parslet
pg (~> 1.5)
pghero
playwright-ruby-client (= 1.55.0)
premailer-rails
prometheus_exporter (~> 2.2)
propshaft
@@ -1072,20 +1076,20 @@ DEPENDENCIES
ruby-prof
ruby-progressbar (~> 1.13)
ruby-vips (~> 2.2)
rubyzip (~> 2.3)
rubyzip (~> 3.0)
sanitize (~> 7.0)
scenic (~> 1.7)
shoulda-matchers
sidekiq (< 8)
sidekiq (< 9)
sidekiq-bulk (~> 0.2.0)
sidekiq-scheduler (~> 5.0)
sidekiq-scheduler (~> 6.0)
sidekiq-unique-jobs (> 8)
simple-navigation (~> 4.4)
simple_form (~> 5.2)
simplecov (~> 0.22)
simplecov-lcov (~> 0.8)
stackprof
stoplight (~> 4.1)
stoplight
strong_migrations
test-prof
thor (~> 1.2)
@@ -1102,4 +1106,4 @@ RUBY VERSION
ruby 3.4.1p0
BUNDLED WITH
2.6.9
2.7.1

View File

@@ -33,71 +33,71 @@ Mastodon Glitch Edition is a fork of [Mastodon](https://github.com/mastodon/mast
<img src="https://d322cqt584bo4o.cloudfront.net/mastodon/localized.svg" alt="Crowdin" /></a>
</p>
Mastodon is a **free, open-source social network server** based on ActivityPub where users can follow friends and discover new ones. On Mastodon, users can publish anything they want: links, pictures, text, and video. All Mastodon servers are interoperable as a federated network (users on one server can seamlessly communicate with users from another one, including non-Mastodon software that implements ActivityPub!)
Mastodon is a **free, open-source social network server** based on [ActivityPub](https://www.w3.org/TR/activitypub/) where users can follow friends and discover new ones. On Mastodon, users can publish anything they want: links, pictures, text, and video. All Mastodon servers are interoperable as a federated network (users on one server can seamlessly communicate with users from another one, including non-Mastodon software that implements ActivityPub!)
## Navigation
- [Project homepage 🐘](https://joinmastodon.org)
- [Support the development via Patreon][patreon]
- [View sponsors](https://joinmastodon.org/sponsors)
- [Blog](https://blog.joinmastodon.org)
- [Documentation](https://docs.joinmastodon.org)
- [Roadmap](https://joinmastodon.org/roadmap)
- [Official Docker image](https://github.com/mastodon/mastodon/pkgs/container/mastodon)
- [Browse Mastodon servers](https://joinmastodon.org/communities)
- [Browse Mastodon apps](https://joinmastodon.org/apps)
[patreon]: https://www.patreon.com/mastodon
- [Donate to support development 🎁](https://joinmastodon.org/sponsors#donate)
- [View sponsors](https://joinmastodon.org/sponsors)
- [Blog 📰](https://blog.joinmastodon.org)
- [Documentation 📚](https://docs.joinmastodon.org)
- [Official container image 🚢](https://github.com/mastodon/mastodon/pkgs/container/mastodon)
## Features
<img src="/app/javascript/images/elephant_ui_working.svg?raw=true" align="right" width="30%" />
<img src="./app/javascript/images/elephant_ui_working.svg?raw=true" align="right" width="30%" />
**No vendor lock-in: Fully interoperable with any conforming platform** - It doesn't have to be Mastodon; whatever implements ActivityPub is part of the social network! [Learn more](https://blog.joinmastodon.org/2018/06/why-activitypub-is-the-future/)
**Part of the Fediverse. Based on open standards, with no vendor lock-in.** - the network goes beyond just Mastodon; anything that implements ActivityPub is part of a broader social network known as [the Fediverse](https://jointhefediverse.net/). You can follow and interact with users on other servers (including those running different software), and they can follow you back.
**Real-time, chronological timeline updates** - updates of people you're following appear in real-time in the UI via WebSockets. There's a firehose view as well!
**Real-time, chronological timeline updates** - updates of people you're following appear in real-time in the UI.
**Media attachments like images and short videos** - upload and view images and WebM/MP4 videos attached to the updates. Videos with no audio track are treated like GIFs; normal videos loop continuously!
**Media attachments** - upload and view images and videos attached to the updates. Videos with no audio track are treated like animated GIFs; normal videos loop continuously.
**Safety and moderation tools** - Mastodon includes private posts, locked accounts, phrase filtering, muting, blocking, and all sorts of other features, along with a reporting and moderation system. [Learn more](https://blog.joinmastodon.org/2018/07/cage-the-mastodon/)
**Safety and moderation tools** - Mastodon includes private posts, locked accounts, phrase filtering, muting, blocking, and many other features, along with a reporting and moderation system.
**OAuth2 and a straightforward REST API** - Mastodon acts as an OAuth2 provider, so 3rd party apps can use the REST and Streaming APIs. This results in a rich app ecosystem with a lot of choices!
**OAuth2 and a straightforward REST API** - Mastodon acts as an OAuth2 provider, and third party apps can use the REST and Streaming APIs. This results in a [rich app ecosystem](https://joinmastodon.org/apps) with a variety of choices!
## Deployment
### Tech stack
- **Ruby on Rails** powers the REST API and other web pages
- **React.js** and **Redux** are used for the dynamic parts of the interface
- **Node.js** powers the streaming API
- [Ruby on Rails](https://github.com/rails/rails) powers the REST API and other web pages.
- [PostgreSQL](https://www.postgresql.org/) is the main database.
- [Redis](https://redis.io/) and [Sidekiq](https://sidekiq.org/) are used for caching and queueing.
- [Node.js](https://nodejs.org/) powers the streaming API.
- [React.js](https://reactjs.org/) and [Redux](https://redux.js.org/) are used for the dynamic parts of the interface.
- [BrowserStack](https://www.browserstack.com/) supports testing on real devices and browsers. (This project is tested with BrowserStack)
- [Chromatic](https://www.chromatic.com/) provides visual regression testing. (This project is tested with Chromatic)
### Requirements
- **PostgreSQL** 13+
- **Redis** 6.2+
- **Ruby** 3.2+
- **PostgreSQL** 13+
- **Redis** 7.0+
- **Node.js** 20+
The repository includes deployment configurations for **Docker and docker-compose** as well as specific platforms like **Heroku**, and **Scalingo**. For Helm charts, reference the [mastodon/chart repository](https://github.com/mastodon/chart). The [**standalone** installation guide](https://docs.joinmastodon.org/admin/install/) is available in the documentation.
This repository includes deployment configurations for **Docker and docker-compose**, as well as for other environments like Heroku and Scalingo. For Helm charts, reference the [mastodon/chart repository](https://github.com/mastodon/chart). A [**standalone** installation guide](https://docs.joinmastodon.org/admin/install/) is available in the main documentation.
## Contributing
Mastodon is **free, open-source software** licensed under **AGPLv3**.
Mastodon is **free, open-source software** licensed under **AGPLv3**. We welcome contributions and help from anyone who wants to improve the project.
You can open issues for bugs you've found or features you think are missing. You
can also submit pull requests to this repository or translations via Crowdin. To
get started, look at the [CONTRIBUTING] and [DEVELOPMENT] guides. For changes
accepted into Mastodon, you can request to be paid through our [OpenCollective].
You should read the overall [CONTRIBUTING](https://github.com/mastodon/.github/blob/main/CONTRIBUTING.md) guide, which covers our development processes.
**IRC channel**: #mastodon on [`irc.libera.chat`](https://libera.chat)
You should also read and understand the [CODE OF CONDUCT](https://github.com/mastodon/.github/blob/main/CODE_OF_CONDUCT.md) that enables us to maintain a welcoming and inclusive community. Collaboration begins with mutual respect and understanding.
## License
You can learn about setting up a development environment in the [DEVELOPMENT](docs/DEVELOPMENT.md) documentation.
If you would like to help with translations 🌐 you can do so on [Crowdin](https://crowdin.com/project/mastodon).
## LICENSE
Copyright (c) 2016-2025 Eugen Rochko (+ [`mastodon authors`](AUTHORS.md))
Licensed under GNU Affero General Public License as stated in the [LICENSE](LICENSE):
```
```text
Copyright (c) 2016-2025 Eugen Rochko & other Mastodon contributors
This program is free software: you can redistribute it and/or modify it under
@@ -113,7 +113,3 @@ details.
You should have received a copy of the GNU Affero General Public License along
with this program. If not, see https://www.gnu.org/licenses/
```
[CONTRIBUTING]: CONTRIBUTING.md
[DEVELOPMENT]: docs/DEVELOPMENT.md
[OpenCollective]: https://opencollective.com/mastodon

View File

@@ -13,8 +13,9 @@ A "vulnerability in Mastodon" is a vulnerability in the code distributed through
## Supported Versions
| Version | Supported |
| ------- | --------- |
| 4.3.x | Yes |
| 4.2.x | Yes |
| < 4.2 | No |
| Version | Supported |
| ------- | ---------------- |
| 4.4.x | Yes |
| 4.3.x | Yes |
| 4.2.x | Until 2026-01-08 |
| < 4.2 | No |

3
Vagrantfile vendored
View File

@@ -54,6 +54,7 @@ sudo apt-get install \
pkg-config \
protobuf-compiler \
zlib1g-dev \
libvips42t64 \
-y
# Install rvm
@@ -134,7 +135,7 @@ VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "ubuntu/focal64"
config.vm.box = "bento/ubuntu-24.04"
config.vm.provider :virtualbox do |vb|
vb.name = "mastodon"

View File

@@ -0,0 +1,82 @@
# frozen_string_literal: true
class ActivityPub::ContextsController < ActivityPub::BaseController
vary_by -> { 'Signature' if authorized_fetch_mode? }
before_action :require_account_signature!, if: :authorized_fetch_mode?
before_action :set_conversation
before_action :set_items
DESCENDANTS_LIMIT = 60
def show
expires_in 3.minutes, public: public_fetch_mode?
render_with_cache json: context_presenter, serializer: ActivityPub::ContextSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json'
end
def items
expires_in 3.minutes, public: public_fetch_mode?
render_with_cache json: items_collection_presenter, serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json'
end
private
def account_required?
false
end
def set_conversation
account_id, status_id = params[:id].split('-')
@conversation = Conversation.local.find_by(parent_account_id: account_id, parent_status_id: status_id)
end
def set_items
@items = @conversation.statuses.distributable_visibility.paginate_by_min_id(DESCENDANTS_LIMIT, params[:min_id])
end
def context_presenter
first_page = ActivityPub::CollectionPresenter.new(
id: items_context_url(@conversation, page_params),
type: :unordered,
part_of: items_context_url(@conversation),
next: next_page,
items: @items.map { |status| status.local? ? ActivityPub::TagManager.instance.uri_for(status) : status.uri }
)
ActivityPub::ContextPresenter.from_conversation(@conversation).tap do |presenter|
presenter.first = first_page
end
end
def items_collection_presenter
page = ActivityPub::CollectionPresenter.new(
id: items_context_url(@conversation, page_params),
type: :unordered,
part_of: items_context_url(@conversation),
next: next_page,
items: @items.map { |status| status.local? ? ActivityPub::TagManager.instance.uri_for(status) : status.uri }
)
return page if page_requested?
ActivityPub::CollectionPresenter.new(
id: items_context_url(@conversation),
type: :unordered,
first: page
)
end
def page_requested?
truthy_param?(:page)
end
def next_page
return nil if @items.size < DESCENDANTS_LIMIT
items_context_url(@conversation, page: true, min_id: @items.last.id)
end
def page_params
params.permit(:page, :min_id)
end
end

View File

@@ -0,0 +1,30 @@
# frozen_string_literal: true
class ActivityPub::QuoteAuthorizationsController < ActivityPub::BaseController
include Authorization
vary_by -> { 'Signature' if authorized_fetch_mode? }
before_action :require_account_signature!, if: :authorized_fetch_mode?
before_action :set_quote_authorization
def show
expires_in 30.seconds, public: true if @quote.status.distributable? && public_fetch_mode?
render json: @quote, serializer: ActivityPub::QuoteAuthorizationSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json'
end
private
def pundit_user
signed_request_account
end
def set_quote_authorization
@quote = Quote.accepted.where(quoted_account: @account).find(params[:id])
return not_found unless @quote.status.present? && @quote.quoted_status.present?
authorize @quote.status, :show?
rescue Mastodon::NotPermittedError
not_found
end
end

View File

@@ -14,16 +14,20 @@ module Admin
def create
authorize @account, :show?
account_action = Admin::AccountAction.new(resource_params)
account_action.target_account = @account
account_action.current_account = current_account
@account_action = Admin::AccountAction.new(resource_params)
@account_action.target_account = @account
@account_action.current_account = current_account
account_action.save!
if account_action.with_report?
redirect_to admin_reports_path, notice: I18n.t('admin.reports.processed_msg', id: resource_params[:report_id])
if @account_action.save
if @account_action.with_report?
redirect_to admin_reports_path, notice: I18n.t('admin.reports.processed_msg', id: resource_params[:report_id])
else
redirect_to admin_account_path(@account.id)
end
else
redirect_to admin_account_path(@account.id)
@warning_presets = AccountWarningPreset.all
render :new
end
end

View File

@@ -16,11 +16,14 @@ module Admin
def batch
authorize :account, :index?
@form = Form::AccountBatch.new(form_account_batch_params)
@form.current_account = current_account
@form.action = action_from_button
@form.select_all_matching = params[:select_all_matching]
@form.query = filtered_accounts
@form = Form::AccountBatch.new(
form_account_batch_params.merge(
action: action_from_button,
current_account:,
query: filtered_accounts,
select_all_matching: params[:select_all_matching]
)
)
@form.save
rescue ActionController::ParameterMissing
flash[:alert] = I18n.t('admin.accounts.no_account_selected')

View File

@@ -6,7 +6,7 @@ module Admin
def index
authorize :audit_log, :index?
@auditable_accounts = Account.auditable.select(:id, :username)
@auditable_accounts = Account.auditable.select(:id, :username).order(username: :asc)
end
private

View File

@@ -19,15 +19,13 @@ module Admin
log_action :resend, @user
flash[:notice] = I18n.t('admin.accounts.resend_confirmation.success')
redirect_to admin_accounts_path
redirect_to admin_accounts_path, notice: t('admin.accounts.resend_confirmation.success')
end
private
def redirect_confirmed_user
flash[:error] = I18n.t('admin.accounts.resend_confirmation.already_confirmed')
redirect_to admin_accounts_path
redirect_to admin_accounts_path, flash: { error: t('admin.accounts.resend_confirmation.already_confirmed') }
end
def user_confirmed?

View File

@@ -18,7 +18,7 @@ class Admin::Disputes::AppealsController < Admin::BaseController
end
def reject
authorize @appeal, :approve?
authorize @appeal, :reject?
log_action :reject, @appeal
@appeal.reject!(current_account)
UserMailer.appeal_rejected(@appeal.account.user, @appeal).deliver_later

View File

@@ -36,7 +36,7 @@ module Admin
end
def edit
authorize :domain_block, :create?
authorize :domain_block, :update?
end
def create
@@ -129,7 +129,7 @@ module Admin
end
def requires_confirmation?
@domain_block.valid? && (@domain_block.new_record? || @domain_block.severity_changed?) && @domain_block.severity.to_s == 'suspend' && !params[:confirm]
@domain_block.valid? && (@domain_block.new_record? || @domain_block.severity_changed?) && @domain_block.suspend? && !params[:confirm]
end
end
end

View File

@@ -49,8 +49,8 @@ module Admin
def export_data
CSV.generate(headers: export_headers, write_headers: true) do |content|
DomainAllow.allowed_domains.each do |instance|
content << [instance.domain]
DomainAllow.allowed_domains.each do |domain|
content << [domain]
end
end
end

View File

@@ -13,27 +13,9 @@ class Admin::Reports::ActionsController < Admin::BaseController
case action_from_button
when 'delete', 'mark_as_sensitive'
status_batch_action = Admin::StatusBatchAction.new(
type: action_from_button,
status_ids: @report.status_ids,
current_account: current_account,
report_id: @report.id,
send_email_notification: !@report.spam?,
text: params[:text]
)
status_batch_action.save!
Admin::StatusBatchAction.new(status_batch_action_params).save!
when 'silence', 'suspend'
account_action = Admin::AccountAction.new(
type: action_from_button,
report_id: @report.id,
target_account: @report.target_account,
current_account: current_account,
send_email_notification: !@report.spam?,
text: params[:text]
)
account_action.save!
Admin::AccountAction.new(account_action_params).save!
else
return redirect_to admin_report_path(@report), alert: I18n.t('admin.reports.unknown_action_msg', action: action_from_button)
end
@@ -43,6 +25,26 @@ class Admin::Reports::ActionsController < Admin::BaseController
private
def status_batch_action_params
shared_params
.merge(status_ids: @report.status_ids)
end
def account_action_params
shared_params
.merge(target_account: @report.target_account)
end
def shared_params
{
current_account: current_account,
report_id: @report.id,
send_email_notification: !@report.spam?,
text: params[:text],
type: action_from_button,
}
end
def set_report
@report = Report.find(params[:report_id])
end

View File

@@ -14,8 +14,7 @@ module Admin
@admin_settings = Form::AdminSettings.new(settings_params)
if @admin_settings.save
flash[:notice] = I18n.t('generic.changes_saved_msg')
redirect_to after_update_redirect_path
redirect_to after_update_redirect_path, notice: t('generic.changes_saved_msg')
else
render :show
end

View File

@@ -5,6 +5,7 @@ module Admin
before_action :set_tag, except: [:index]
PER_PAGE = 20
PERIOD_DAYS = 6.days
def index
authorize :tag, :index?
@@ -15,7 +16,7 @@ module Admin
def show
authorize @tag, :show?
@time_period = (6.days.ago.to_date...Time.now.utc.to_date)
@time_period = report_range
end
def update
@@ -24,7 +25,7 @@ module Admin
if @tag.update(tag_params.merge(reviewed_at: Time.now.utc))
redirect_to admin_tag_path(@tag.id), notice: I18n.t('admin.tags.updated_msg')
else
@time_period = (6.days.ago.to_date...Time.now.utc.to_date)
@time_period = report_range
render :show
end
@@ -36,6 +37,10 @@ module Admin
@tag = Tag.find(params[:id])
end
def report_range
(PERIOD_DAYS.ago.to_date...Time.now.utc.to_date)
end
def tag_params
params
.expect(tag: [:name, :display_name, :trendable, :usable, :listable])

View File

@@ -0,0 +1,77 @@
# frozen_string_literal: true
class Admin::UsernameBlocksController < Admin::BaseController
before_action :set_username_block, only: [:edit, :update]
def index
authorize :username_block, :index?
@username_blocks = UsernameBlock.order(username: :asc).page(params[:page])
@form = Form::UsernameBlockBatch.new
end
def batch
authorize :username_block, :index?
@form = Form::UsernameBlockBatch.new(form_username_block_batch_params.merge(current_account: current_account, action: action_from_button))
@form.save
rescue ActionController::ParameterMissing
flash[:alert] = I18n.t('admin.username_blocks.no_username_block_selected')
rescue Mastodon::NotPermittedError
flash[:alert] = I18n.t('admin.username_blocks.not_permitted')
ensure
redirect_to admin_username_blocks_path
end
def new
authorize :username_block, :create?
@username_block = UsernameBlock.new(exact: true)
end
def edit
authorize @username_block, :update?
end
def create
authorize :username_block, :create?
@username_block = UsernameBlock.new(resource_params)
if @username_block.save
log_action :create, @username_block
redirect_to admin_username_blocks_path, notice: I18n.t('admin.username_blocks.created_msg')
else
render :new
end
end
def update
authorize @username_block, :update?
if @username_block.update(resource_params)
log_action :update, @username_block
redirect_to admin_username_blocks_path, notice: I18n.t('admin.username_blocks.updated_msg')
else
render :new
end
end
private
def set_username_block
@username_block = UsernameBlock.find(params[:id])
end
def form_username_block_batch_params
params
.expect(form_username_block_batch: [username_block_ids: []])
end
def resource_params
params
.expect(username_block: [:username, :comparison, :allow_with_approval])
end
def action_from_button
'delete' if params[:delete]
end
end

View File

@@ -48,6 +48,7 @@ class Api::V1::Accounts::CredentialsController < Api::BaseController
default_privacy: source_params.fetch(:privacy, @account.user.setting_default_privacy),
default_sensitive: source_params.fetch(:sensitive, @account.user.setting_default_sensitive),
default_language: source_params.fetch(:language, @account.user.setting_default_language),
default_quote_policy: source_params.fetch(:quote_policy, @account.user.setting_default_quote_policy),
},
}
end

View File

@@ -2,6 +2,7 @@
class Api::V1::Admin::TagsController < Api::BaseController
include Authorization
before_action -> { authorize_if_got_token! :'admin:read' }, only: [:index, :show]
before_action -> { authorize_if_got_token! :'admin:write' }, only: :update

View File

@@ -7,6 +7,7 @@ class Api::V1::InvitesController < Api::BaseController
skip_around_action :set_locale
before_action :set_invite
before_action :check_valid_usage!
before_action :check_enabled_registrations!
# Override `current_user` to avoid reading session cookies
@@ -22,9 +23,11 @@ class Api::V1::InvitesController < Api::BaseController
@invite = Invite.find_by!(code: params[:invite_code])
end
def check_enabled_registrations!
return render json: { error: I18n.t('invites.invalid') }, status: 401 unless @invite.valid_for_use?
def check_valid_usage!
render json: { error: I18n.t('invites.invalid') }, status: 401 unless @invite.valid_for_use?
end
def check_enabled_registrations!
raise Mastodon::NotPermittedError unless allowed_registration?(request.remote_ip, @invite)
end
end

View File

@@ -16,16 +16,7 @@ class Api::V1::Push::SubscriptionsController < Api::BaseController
def create
with_redis_lock("push_subscription:#{current_user.id}") do
destroy_web_push_subscriptions!
@push_subscription = Web::PushSubscription.create!(
endpoint: subscription_params[:endpoint],
key_p256dh: subscription_params[:keys][:p256dh],
key_auth: subscription_params[:keys][:auth],
standard: subscription_params[:standard] || false,
data: data_params,
user_id: current_user.id,
access_token_id: doorkeeper_token.id
)
@push_subscription = Web::PushSubscription.create!(web_push_subscription_params)
end
render json: @push_subscription, serializer: REST::WebPushSubscriptionSerializer
@@ -55,6 +46,18 @@ class Api::V1::Push::SubscriptionsController < Api::BaseController
not_found if @push_subscription.nil?
end
def web_push_subscription_params
{
access_token_id: doorkeeper_token.id,
data: data_params,
endpoint: subscription_params[:endpoint],
key_auth: subscription_params[:keys][:auth],
key_p256dh: subscription_params[:keys][:p256dh],
standard: subscription_params[:standard] || false,
user_id: current_user.id,
}
end
def subscription_params
params.expect(subscription: [:endpoint, :standard, keys: [:auth, :p256dh]])
end

View File

@@ -0,0 +1,33 @@
# frozen_string_literal: true
class Api::V1::Statuses::InteractionPoliciesController < Api::V1::Statuses::BaseController
include Api::InteractionPoliciesConcern
before_action -> { doorkeeper_authorize! :write, :'write:statuses' }
before_action -> { check_feature_enabled }
def update
authorize @status, :update?
@status.update!(quote_approval_policy: quote_approval_policy)
broadcast_updates! if @status.quote_approval_policy_previously_changed?
render json: @status, serializer: REST::StatusSerializer
end
private
def status_params
params.permit(:quote_approval_policy)
end
def check_feature_enabled
raise ActionController::RoutingError unless Mastodon::Feature.outgoing_quotes_enabled?
end
def broadcast_updates!
DistributionWorker.perform_async(@status.id, { 'update' => true })
ActivityPub::StatusUpdateDistributionWorker.perform_async(@status.id, { 'updated_at' => Time.now.utc.iso8601 })
end
end

View File

@@ -0,0 +1,72 @@
# frozen_string_literal: true
class Api::V1::Statuses::QuotesController < Api::V1::Statuses::BaseController
before_action -> { doorkeeper_authorize! :read, :'read:statuses' }, only: :index
before_action -> { doorkeeper_authorize! :write, :'write:statuses' }, only: :revoke
before_action :check_owner!
before_action :set_quote, only: :revoke
after_action :insert_pagination_headers, only: :index
def index
cache_if_unauthenticated!
@statuses = load_statuses
render json: @statuses, each_serializer: REST::StatusSerializer
end
def revoke
authorize @quote, :revoke?
RevokeQuoteService.new.call(@quote)
render json: @quote.status, serializer: REST::StatusSerializer
end
private
def check_owner!
authorize @status, :list_quotes?
end
def set_quote
@quote = @status.quotes.find_by!(status_id: params[:id])
end
def load_statuses
scope = default_statuses
scope = scope.not_excluded_by_account(current_account) unless current_account.nil?
scope.merge(paginated_quotes).to_a
end
def default_statuses
Status.includes(:quote).references(:quote)
end
def paginated_quotes
@status.quotes.accepted.paginate_by_max_id(
limit_param(DEFAULT_STATUSES_LIMIT),
params[:max_id],
params[:since_id]
)
end
def next_path
api_v1_status_quotes_url pagination_params(max_id: pagination_max_id) if records_continue?
end
def prev_path
api_v1_status_quotes_url pagination_params(since_id: pagination_since_id) unless @statuses.empty?
end
def pagination_max_id
@statuses.last.quote.id
end
def pagination_since_id
@statuses.first.quote.id
end
def records_continue?
@statuses.size == limit_param(DEFAULT_STATUSES_LIMIT)
end
end

View File

@@ -2,6 +2,8 @@
class Api::V1::StatusesController < Api::BaseController
include Authorization
include AsyncRefreshesConcern
include Api::InteractionPoliciesConcern
before_action -> { authorize_if_got_token! :read, :'read:statuses' }, except: [:create, :update, :destroy]
before_action -> { doorkeeper_authorize! :write, :'write:statuses' }, only: [:create, :update, :destroy]
@@ -9,6 +11,7 @@ class Api::V1::StatusesController < Api::BaseController
before_action :set_statuses, only: [:index]
before_action :set_status, only: [:show, :context]
before_action :set_thread, only: [:create]
before_action :set_quoted_status, only: [:create]
before_action :check_statuses_limit, only: [:index]
override_rate_limit_headers :create, family: :statuses
@@ -57,9 +60,21 @@ class Api::V1::StatusesController < Api::BaseController
@context = Context.new(ancestors: loaded_ancestors, descendants: loaded_descendants)
statuses = [@status] + @context.ancestors + @context.descendants
render json: @context, serializer: REST::ContextSerializer, relationships: StatusRelationshipsPresenter.new(statuses, current_user&.account_id)
refresh_key = "context:#{@status.id}:refresh"
async_refresh = AsyncRefresh.new(refresh_key)
ActivityPub::FetchAllRepliesWorker.perform_async(@status.id) if !current_account.nil? && @status.should_fetch_replies?
if async_refresh.running?
add_async_refresh_header(async_refresh)
elsif !current_account.nil? && @status.should_fetch_replies?
add_async_refresh_header(AsyncRefresh.create(refresh_key))
WorkerBatch.new.within do |batch|
batch.connect(refresh_key, threshold: 1.0)
ActivityPub::FetchAllRepliesWorker.perform_async(@status.id, { 'batch_id' => batch.id })
end
end
render json: @context, serializer: REST::ContextSerializer, relationships: StatusRelationshipsPresenter.new(statuses, current_user&.account_id)
end
def create
@@ -67,6 +82,8 @@ class Api::V1::StatusesController < Api::BaseController
current_user.account,
text: status_params[:status],
thread: @thread,
quoted_status: @quoted_status,
quote_approval_policy: quote_approval_policy,
media_ids: status_params[:media_ids],
sensitive: status_params[:sensitive],
spoiler_text: status_params[:spoiler_text],
@@ -100,6 +117,7 @@ class Api::V1::StatusesController < Api::BaseController
language: status_params[:language],
spoiler_text: status_params[:spoiler_text],
poll: status_params[:poll],
quote_approval_policy: quote_approval_policy,
content_type: status_params[:content_type]
)
@@ -140,6 +158,16 @@ class Api::V1::StatusesController < Api::BaseController
render json: { error: I18n.t('statuses.errors.in_reply_not_found') }, status: 404
end
def set_quoted_status
return unless Mastodon::Feature.outgoing_quotes_enabled?
@quoted_status = Status.find(status_params[:quoted_status_id]) if status_params[:quoted_status_id].present?
authorize(@quoted_status, :quote?) if @quoted_status.present?
rescue ActiveRecord::RecordNotFound, Mastodon::NotPermittedError
# TODO: distinguish between non-existing and non-quotable posts
render json: { error: I18n.t('statuses.errors.quoted_status_not_found') }, status: 404
end
def check_statuses_limit
raise(Mastodon::ValidationError) if status_ids.size > DEFAULT_STATUSES_LIMIT
end
@@ -156,6 +184,8 @@ class Api::V1::StatusesController < Api::BaseController
params.permit(
:status,
:in_reply_to_id,
:quoted_status_id,
:quote_approval_policy,
:sensitive,
:spoiler_text,
:visibility,

View File

@@ -20,7 +20,7 @@ class Api::V2::SearchController < Api::BaseController
@search = Search.new(search_results)
render json: @search, serializer: REST::SearchSerializer
rescue Mastodon::SyntaxError
unprocessable_entity
unprocessable_content
rescue ActiveRecord::RecordNotFound
not_found
end

View File

@@ -49,7 +49,7 @@ class Api::Web::PushSubscriptionsController < Api::Web::BaseController
{
policy: 'all',
alerts: Notification::TYPES.index_with { alerts_enabled },
}
}.deep_stringify_keys
end
def alerts_enabled

View File

@@ -31,7 +31,7 @@ class ApplicationController < ActionController::Base
rescue_from Mastodon::NotPermittedError, with: :forbidden
rescue_from ActionController::RoutingError, ActiveRecord::RecordNotFound, with: :not_found
rescue_from ActionController::UnknownFormat, with: :not_acceptable
rescue_from ActionController::InvalidAuthenticityToken, with: :unprocessable_entity
rescue_from ActionController::InvalidAuthenticityToken, with: :unprocessable_content
rescue_from Mastodon::RateLimitExceededError, with: :too_many_requests
rescue_from(*Mastodon::HTTP_CONNECTION_ERRORS, with: :internal_server_error)
@@ -126,7 +126,7 @@ class ApplicationController < ActionController::Base
respond_with_error(410)
end
def unprocessable_entity
def unprocessable_content
respond_with_error(422)
end

View File

@@ -38,8 +38,7 @@ class Auth::OmniauthCallbacksController < Devise::OmniauthCallbacksController
private
def record_login_activity
LoginActivity.create(
user: @user,
@user.login_activities.create(
success: true,
authentication_method: :omniauth,
provider: @provider,

View File

@@ -19,8 +19,7 @@ class Auth::PasswordsController < Devise::PasswordsController
private
def redirect_invalid_reset_token
flash[:error] = I18n.t('auth.invalid_reset_password_token')
redirect_to new_password_path(resource_name)
redirect_to new_password_path(resource_name), flash: { error: t('auth.invalid_reset_password_token') }
end
def reset_password_token_is_valid?

View File

@@ -23,11 +23,11 @@ class Auth::RegistrationsController < Devise::RegistrationsController
super(&:build_invite_request)
end
def edit # rubocop:disable Lint/UselessMethodDefinition
def edit
super
end
def create # rubocop:disable Lint/UselessMethodDefinition
def create
super
end

View File

@@ -12,6 +12,8 @@ class Auth::SessionsController < Devise::SessionsController
skip_before_action :require_functional!
skip_before_action :update_user_sign_in
around_action :preserve_stored_location, only: :destroy, if: :continue_after?
prepend_before_action :check_suspicious!, only: [:create]
include Auth::TwoFactorAuthenticationConcern
@@ -31,11 +33,9 @@ class Auth::SessionsController < Devise::SessionsController
end
def destroy
tmp_stored_location = stored_location_for(:user)
super
session.delete(:challenge_passed_at)
flash.delete(:notice)
store_location_for(:user, tmp_stored_location) if continue_after?
end
def webauthn_options
@@ -96,6 +96,12 @@ class Auth::SessionsController < Devise::SessionsController
private
def preserve_stored_location
original_stored_location = stored_location_for(:user)
yield
store_location_for(:user, original_stored_location)
end
def check_suspicious!
user = find_user
@login_is_suspicious = suspicious_sign_in?(user) unless user.nil?
@@ -151,12 +157,11 @@ class Auth::SessionsController < Devise::SessionsController
sign_in(user)
flash.delete(:notice)
LoginActivity.create(
user: user,
success: true,
authentication_method: security_measure,
ip: request.remote_ip,
user_agent: request.user_agent
user.login_activities.create(
request_details.merge(
authentication_method: security_measure,
success: true
)
)
UserMailer.suspicious_sign_in(user, request.remote_ip, request.user_agent, Time.now.utc).deliver_later! if @login_is_suspicious
@@ -167,13 +172,12 @@ class Auth::SessionsController < Devise::SessionsController
end
def on_authentication_failure(user, security_measure, failure_reason)
LoginActivity.create(
user: user,
success: false,
authentication_method: security_measure,
failure_reason: failure_reason,
ip: request.remote_ip,
user_agent: request.user_agent
user.login_activities.create(
request_details.merge(
authentication_method: security_measure,
failure_reason: failure_reason,
success: false
)
)
# Only send a notification email every hour at most
@@ -182,6 +186,13 @@ class Auth::SessionsController < Devise::SessionsController
UserMailer.failed_2fa(user, request.remote_ip, request.user_agent, Time.now.utc).deliver_later!
end
def request_details
{
ip: request.remote_ip,
user_agent: request.user_agent,
}
end
def second_factor_attempts_key(user)
"2fa_auth_attempts:#{user.id}:#{Time.now.utc.hour}"
end

View File

@@ -0,0 +1,21 @@
# frozen_string_literal: true
module Api::InteractionPoliciesConcern
extend ActiveSupport::Concern
def quote_approval_policy
return nil unless Mastodon::Feature.outgoing_quotes_enabled?
case status_params[:quote_approval_policy].presence || current_user.setting_default_quote_policy
when 'public'
Status::QUOTE_APPROVAL_POLICY_FLAGS[:public] << 16
when 'followers'
Status::QUOTE_APPROVAL_POLICY_FLAGS[:followers] << 16
when 'nobody'
0
else
# TODO: raise more useful message
raise ActiveRecord::RecordInvalid
end
end
end

View File

@@ -5,6 +5,18 @@ module Auth::CaptchaConcern
include Hcaptcha::Adapters::ViewMethods
CAPTCHA_DIRECTIVES = %w(
connect_src
frame_src
script_src
style_src
).freeze
CAPTCHA_SOURCES = %w(
https://*.hcaptcha.com
https://hcaptcha.com
).freeze
included do
helper_method :render_captcha
end
@@ -42,20 +54,9 @@ module Auth::CaptchaConcern
end
def extend_csp_for_captcha!
policy = request.content_security_policy&.clone
return unless captcha_required? && request.content_security_policy.present?
return unless captcha_required? && policy.present?
%w(script_src frame_src style_src connect_src).each do |directive|
values = policy.send(directive)
values << 'https://hcaptcha.com' unless values.include?('https://hcaptcha.com') || values.include?('https:')
values << 'https://*.hcaptcha.com' unless values.include?('https://*.hcaptcha.com') || values.include?('https:')
policy.send(directive, *values)
end
request.content_security_policy = policy
request.content_security_policy = captcha_adjusted_policy
end
def render_captcha
@@ -63,4 +64,24 @@ module Auth::CaptchaConcern
hcaptcha_tags
end
private
def captcha_adjusted_policy
request.content_security_policy.clone.tap do |policy|
populate_captcha_policy(policy)
end
end
def populate_captcha_policy(policy)
CAPTCHA_DIRECTIVES.each do |directive|
values = policy.send(directive)
CAPTCHA_SOURCES.each do |source|
values << source unless values.include?(source) || values.include?('https:')
end
policy.send(directive, *values)
end
end
end

View File

@@ -9,6 +9,8 @@ module SignatureVerification
EXPIRATION_WINDOW_LIMIT = 12.hours
CLOCK_SKEW_MARGIN = 1.hour
STOPLIGHT_COOL_OFF_TIME = 5.minutes.seconds
STOPLIGHT_THRESHOLD = 1
def require_account_signature!
render json: signature_verification_failure_reason, status: signature_verification_failure_code unless signed_request_account
@@ -64,6 +66,9 @@ module SignatureVerification
return (@signed_request_actor = actor) if signed_request.verified?(actor)
fail_with! "Verification failed for #{actor.to_log_human_identifier} #{actor.uri}"
rescue Mastodon::MalformedHeaderError => e
@signature_verification_failure_code = 400
fail_with! e.message
rescue Mastodon::SignatureVerificationError => e
fail_with! e.message
rescue *Mastodon::HTTP_CONNECTION_ERRORS => e
@@ -104,10 +109,12 @@ module SignatureVerification
end
def stoplight_wrapper
Stoplight("source:#{request.remote_ip}")
.with_threshold(1)
.with_cool_off_time(5.minutes.seconds)
.with_error_handler { |error, handle| error.is_a?(HTTP::Error) || error.is_a?(OpenSSL::SSL::SSLError) ? handle.call(error) : raise(error) }
Stoplight(
"source:#{request.remote_ip}",
cool_off_time: STOPLIGHT_COOL_OFF_TIME,
threshold: STOPLIGHT_THRESHOLD,
tracked_errors: [HTTP::Error, OpenSSL::SSL::SSLError]
)
end
def actor_refresh_key!(actor)

View File

@@ -50,6 +50,13 @@ module WebAppControllerConcern
return unless current_user&.require_tos_interstitial?
@terms_of_service = TermsOfService.published.first
# Handle case where terms of service have been removed from the database
if @terms_of_service.nil?
current_user.update(require_tos_interstitial: false)
return
end
render 'terms_of_service_interstitial/show', layout: 'auth'
end

View File

@@ -5,6 +5,6 @@ class Settings::LoginActivitiesController < Settings::BaseController
skip_before_action :require_functional!
def index
@login_activities = LoginActivity.where(user: current_user).order(id: :desc).page(params[:page])
@login_activities = current_user.login_activities.order(id: :desc).page(params[:page])
end
end

View File

@@ -22,7 +22,7 @@ class Settings::Migration::RedirectsController < Settings::BaseController
end
def destroy
if current_account.moved_to_account_id.present?
if current_account.moved?
current_account.update!(moved_to_account: nil)
ActivityPub::UpdateDistributionWorker.perform_async(current_account.id)
end

View File

@@ -0,0 +1,15 @@
# frozen_string_literal: true
class Settings::Preferences::PostingDefaultsController < Settings::Preferences::BaseController
private
def after_update_redirect_path
settings_preferences_posting_defaults_path
end
def user_params
super.tap do |params|
params[:settings_attributes][:default_quote_policy] = 'nobody' if params[:settings_attributes][:default_privacy] == 'private'
end
end
end

View File

@@ -8,8 +8,7 @@ class Settings::SessionsController < Settings::BaseController
def destroy
@session.destroy!
flash[:notice] = I18n.t('sessions.revoke_success')
redirect_to edit_user_registration_path
redirect_to edit_user_registration_path, notice: t('sessions.revoke_success')
end
private

View File

@@ -52,7 +52,7 @@ module Settings
end
else
flash[:error] = I18n.t('webauthn_credentials.create.error')
status = :unprocessable_entity
status = :unprocessable_content
end
else
flash[:error] = t('webauthn_credentials.create.error')
@@ -86,13 +86,11 @@ module Settings
private
def redirect_invalid_otp
flash[:error] = t('webauthn_credentials.otp_required')
redirect_to settings_two_factor_authentication_methods_path
redirect_to settings_two_factor_authentication_methods_path, flash: { error: t('webauthn_credentials.otp_required') }
end
def redirect_invalid_webauthn
flash[:error] = t('webauthn_credentials.not_enabled')
redirect_to settings_two_factor_authentication_methods_path
redirect_to settings_two_factor_authentication_methods_path, flash: { error: t('webauthn_credentials.not_enabled') }
end
end
end

View File

@@ -11,6 +11,7 @@ class StatusesController < ApplicationController
before_action :require_account_signature!, only: [:show, :activity], if: -> { request.format == :json && authorized_fetch_mode? }
before_action :set_status
before_action :redirect_to_original, only: :show
before_action :verify_embed_allowed, only: :embed
after_action :set_link_headers
@@ -40,8 +41,6 @@ class StatusesController < ApplicationController
end
def embed
return not_found if @status.hidden? || @status.reblog?
expires_in 180, public: true
response.headers.delete('X-Frame-Options')
@@ -50,6 +49,10 @@ class StatusesController < ApplicationController
private
def verify_embed_allowed
not_found if @status.hidden? || @status.reblog?
end
def set_link_headers
response.headers['Link'] = LinkHeader.new(
[[ActivityPub::TagManager.instance.uri_for(@status), [%w(rel alternate), %w(type application/activity+json)]]]

View File

@@ -13,6 +13,8 @@ module Admin::ActionLogsHelper
end
when 'UserRole'
link_to log.human_identifier, admin_roles_path(log.target_id)
when 'UsernameBlock'
link_to log.human_identifier, edit_admin_username_block_path(log.target_id)
when 'Report'
link_to "##{log.human_identifier.presence || log.target_id}", admin_report_path(log.target_id)
when 'Instance', 'DomainBlock', 'DomainAllow', 'UnavailableDomain'

View File

@@ -66,7 +66,7 @@ module ApplicationHelper
def provider_sign_in_link(provider)
label = Devise.omniauth_configs[provider]&.strategy&.display_name.presence || I18n.t("auth.providers.#{provider}", default: provider.to_s.chomp('_oauth2').capitalize)
link_to label, omniauth_authorize_path(:user, provider), class: "button button-#{provider}", method: :post
link_to label, omniauth_authorize_path(:user, provider), class: "btn button-#{provider}", method: :post
end
def locale_direction
@@ -102,6 +102,16 @@ module ApplicationHelper
policy(record).public_send(:"#{action}?")
end
def conditional_link_to(condition, name, options = {}, html_options = {}, &block)
if condition && !current_page?(block_given? ? name : options)
link_to(name, options, html_options, &block)
elsif block_given?
content_tag(:span, options, html_options, &block)
else
content_tag(:span, name, html_options)
end
end
def material_symbol(icon, attributes = {})
safe_join(
[
@@ -234,6 +244,10 @@ module ApplicationHelper
tag.input(type: :text, maxlength: 999, spellcheck: false, readonly: true, **options)
end
def recent_tag_users(tag)
tag.statuses.public_visibility.joins(:account).merge(Account.without_suspended.without_silenced).includes(:account).limit(3).map(&:account)
end
def recent_tag_usage(tag)
people = tag.history.aggregate(2.days.ago.to_date..Time.zone.today).accounts
I18n.t 'user_mailer.welcome.hashtags_recent_count', people: number_with_delimiter(people), count: people
@@ -247,6 +261,10 @@ module ApplicationHelper
'https://play.google.com/store/apps/details?id=org.joinmastodon.android'
end
def within_authorization_flow?
session[:user_return_to].present? && Rails.application.routes.recognize_path(session[:user_return_to])[:controller] == 'oauth/authorizations'
end
# glitch-soc addition to handle the multiple flavors
def flavoured_vite_typescript_tag(pack_name, **)
vite_typescript_tag("#{Themes.instance.flavour(current_flavour)['pack_directory'].delete_prefix('app/javascript/')}/#{pack_name}", **)

View File

@@ -27,6 +27,12 @@ module ContextHelper
suspended: { 'toot' => 'http://joinmastodon.org/ns#', 'suspended' => 'toot:suspended' },
attribution_domains: { 'toot' => 'http://joinmastodon.org/ns#', 'attributionDomains' => { '@id' => 'toot:attributionDomains', '@type' => '@id' } },
quote_requests: { 'QuoteRequest' => 'https://w3id.org/fep/044f#QuoteRequest' },
quotes: {
'quote' => 'https://w3id.org/fep/044f#quote',
'quoteUri' => 'http://fedibird.com/ns#quoteUri',
'_misskey_quote' => 'https://misskey-hub.net/ns#_misskey_quote',
'quoteAuthorization' => { '@id' => 'https://w3id.org/fep/044f#quoteAuthorization', '@type' => '@id' },
},
interaction_policies: {
'gts' => 'https://gotosocial.org/ns#',
'interactionPolicy' => { '@id' => 'gts:interactionPolicy', '@type' => '@id' },
@@ -34,6 +40,12 @@ module ContextHelper
'automaticApproval' => { '@id' => 'gts:automaticApproval', '@type' => '@id' },
'manualApproval' => { '@id' => 'gts:manualApproval', '@type' => '@id' },
},
quote_authorizations: {
'gts' => 'https://gotosocial.org/ns#',
'quoteAuthorization' => { '@id' => 'https://w3id.org/fep/044f#quoteAuthorization', '@type' => '@id' },
'interactingObject' => { '@id' => 'gts:interactingObject' },
'interactionTarget' => { '@id' => 'gts:interactionTarget' },
},
}.freeze
def full_context

View File

@@ -1,18 +0,0 @@
# frozen_string_literal: true
module EmailHelper
def self.included(base)
base.extend(self)
end
def email_to_canonical_email(str)
username, domain = str.downcase.split('@', 2)
username, = username.delete('.').split('+', 2)
"#{username}@#{domain}"
end
def email_to_canonical_email_hash(str)
Digest::SHA2.new(256).hexdigest(email_to_canonical_email(str))
end
end

View File

@@ -27,7 +27,9 @@ module FormattingHelper
module_function :extract_status_plain_text
def status_content_format(status)
html_aware_format(status.text, status.local?, preloaded_accounts: [status.account] + (status.respond_to?(:active_mentions) ? status.active_mentions.map(&:account) : []), content_type: status.content_type)
quoted_status = status.quote&.quoted_status if status.local?
html_aware_format(status.text, status.local?, preloaded_accounts: [status.account] + (status.respond_to?(:active_mentions) ? status.active_mentions.map(&:account) : []), quoted_status: quoted_status, content_type: status.content_type)
end
def rss_status_content_format(status)
@@ -65,12 +67,12 @@ module FormattingHelper
end
def rss_content_preroll(status)
if status.spoiler_text?
safe_join [
tag.p { spoiler_with_warning(status) },
tag.hr,
]
end
return unless status.spoiler_text?
safe_join [
tag.p { spoiler_with_warning(status) },
tag.hr,
]
end
def spoiler_with_warning(status)
@@ -81,10 +83,10 @@ module FormattingHelper
end
def rss_content_postroll(status)
if status.preloadable_poll
tag.p do
poll_option_tags(status)
end
return unless status.preloadable_poll
tag.p do
poll_option_tags(status)
end
end

View File

@@ -39,18 +39,8 @@ module HomeHelper
end
end
def obscured_counter(count)
if count <= 0
'0'
elsif count == 1
'1'
else
'1+'
end
end
def custom_field_classes(field)
if field.verified?
def field_verified_class(verified)
if verified
'verified'
else
'emojify'

View File

@@ -134,7 +134,7 @@ module JsonLdHelper
patch_for_forwarding!(value, compacted_value)
elsif value.is_a?(Array)
compacted_value = [compacted_value] unless compacted_value.is_a?(Array)
return if value.size != compacted_value.size
return nil if value.size != compacted_value.size
compacted[key] = value.zip(compacted_value).map do |v, vc|
if v.is_a?(Hash) && vc.is_a?(Hash)

View File

@@ -107,6 +107,7 @@ module LanguagesHelper
mk: ['Macedonian', 'македонски јазик'].freeze,
ml: ['Malayalam', 'മലയാളം'].freeze,
mn: ['Mongolian', 'Монгол хэл'].freeze,
'mn-Mong': ['Traditional Mongolian', 'ᠮᠣᠩᠭᠣᠯ ᠬᠡᠯᠡ'].freeze,
mr: ['Marathi', 'मराठी'].freeze,
ms: ['Malay', 'Bahasa Melayu'].freeze,
'ms-Arab': ['Jawi Malay', 'بهاس ملايو'].freeze,

View File

@@ -64,4 +64,16 @@ module StatusesHelper
def prefers_autoplay?
ActiveModel::Type::Boolean.new.cast(params[:autoplay]) || current_user&.setting_auto_play_gif
end
def render_seo_schema(status)
json = ActiveModelSerializers::SerializableResource.new(
status,
serializer: SEO::SocialMediaPostingSerializer,
adapter: SEO::Adapter
).to_json
# rubocop:disable Rails/OutputSafety
content_tag(:script, json_escape(json).html_safe, type: 'application/ld+json')
# rubocop:enable Rails/OutputSafety
end
end

View File

@@ -28,24 +28,24 @@ module ThemeHelper
end
def custom_stylesheet
if active_custom_stylesheet.present?
stylesheet_link_tag(
custom_css_path(active_custom_stylesheet),
host: root_url,
media: :all,
skip_pipeline: true
)
end
return if active_custom_stylesheet.blank?
stylesheet_link_tag(
custom_css_path(active_custom_stylesheet),
host: root_url,
media: :all,
skip_pipeline: true
)
end
private
def active_custom_stylesheet
if cached_custom_css_digest.present?
[:custom, cached_custom_css_digest.to_s.first(8)]
.compact_blank
.join('-')
end
return if cached_custom_css_digest.blank?
[:custom, cached_custom_css_digest.to_s.first(8)]
.compact_blank
.join('-')
end
def cached_custom_css_digest

View File

@@ -145,6 +145,10 @@ function loaded() {
);
});
updateDefaultQuotePrivacyFromPrivacy(
document.querySelector('#user_settings_attributes_default_privacy'),
);
const reactComponents = document.querySelectorAll('[data-component]');
if (reactComponents.length > 0) {
@@ -347,6 +351,31 @@ const setInputDisabled = (
}
};
const setInputHint = (
input: HTMLInputElement | HTMLSelectElement,
hintPrefix: string,
) => {
const fieldWrapper = input.closest<HTMLElement>('.fields-group > .input');
if (!fieldWrapper) return;
const hint = fieldWrapper.dataset[`${hintPrefix}Hint`];
const hintElement =
fieldWrapper.querySelector<HTMLSpanElement>(':scope > .hint');
if (hint) {
if (hintElement) {
hintElement.textContent = hint;
} else {
const newHintElement = document.createElement('span');
newHintElement.className = 'hint';
newHintElement.textContent = hint;
fieldWrapper.appendChild(newHintElement);
}
} else {
hintElement?.remove();
}
};
Rails.delegate(
document,
'#account_statuses_cleanup_policy_enabled',
@@ -364,6 +393,36 @@ Rails.delegate(
},
);
const updateDefaultQuotePrivacyFromPrivacy = (
privacySelect: EventTarget | null,
) => {
if (!(privacySelect instanceof HTMLSelectElement) || !privacySelect.form)
return;
const select = privacySelect.form.querySelector<HTMLSelectElement>(
'select#user_settings_attributes_default_quote_policy',
);
if (!select) return;
setInputHint(select, privacySelect.value);
if (privacySelect.value === 'private') {
select.value = 'nobody';
setInputDisabled(select, true);
} else {
setInputDisabled(select, false);
}
};
Rails.delegate(
document,
'#user_settings_attributes_default_privacy',
'change',
({ target }) => {
updateDefaultQuotePrivacyFromPrivacy(target);
},
);
// Empty the honeypot fields in JS in case something like an extension
// automatically filled them.
Rails.delegate(document, '#registration_new_user,#new_user', 'submit', () => {

View File

@@ -89,6 +89,7 @@ export const COMPOSE_FOCUS = 'COMPOSE_FOCUS';
const messages = defineMessages({
uploadErrorLimit: { id: 'upload_error.limit', defaultMessage: 'File upload limit exceeded.' },
uploadErrorPoll: { id: 'upload_error.poll', defaultMessage: 'File upload not allowed with polls.' },
uploadQuote: { id: 'upload_error.quote', defaultMessage: 'File upload not allowed with quotes.' },
open: { id: 'compose.published.open', defaultMessage: 'Open' },
published: { id: 'compose.published.body', defaultMessage: 'Post published.' },
saved: { id: 'compose.saved.body', defaultMessage: 'Post saved.' },
@@ -101,13 +102,18 @@ export const ensureComposeIsVisible = (getState) => {
};
export function setComposeToStatus(status, text, spoiler_text, content_type) {
return{
type: COMPOSE_SET_STATUS,
status,
text,
spoiler_text,
content_type,
};
return (dispatch, getState) => {
const maxOptions = getState().server.getIn(['server', 'configuration', 'polls', 'max_options']);
dispatch({
type: COMPOSE_SET_STATUS,
status,
text,
spoiler_text,
content_type,
maxOptions,
});
}
}
export function changeCompose(text) {
@@ -154,7 +160,7 @@ export function resetCompose() {
};
}
export const focusCompose = (defaultText) => (dispatch, getState) => {
export const focusCompose = (defaultText = '') => (dispatch, getState) => {
dispatch({
type: COMPOSE_FOCUS,
defaultText,
@@ -193,8 +199,9 @@ export function directCompose(account) {
/**
* @param {null | string} overridePrivacy
* @param {undefined | Function} successCallback
*/
export function submitCompose(overridePrivacy = null) {
export function submitCompose(overridePrivacy = null, successCallback = undefined) {
return function (dispatch, getState) {
let status = getState().getIn(['compose', 'text'], '');
const media = getState().getIn(['compose', 'media_attachments']);
@@ -232,6 +239,7 @@ export function submitCompose(overridePrivacy = null) {
});
}
const visibility = overridePrivacy || getState().getIn(['compose', 'privacy']);
api().request({
url: statusId === null ? '/api/v1/statuses' : `/api/v1/statuses/${statusId}`,
method: statusId === null ? 'post' : 'put',
@@ -243,9 +251,11 @@ export function submitCompose(overridePrivacy = null) {
media_attributes,
sensitive: getState().getIn(['compose', 'sensitive']) || (spoilerText.length > 0 && media.size !== 0),
spoiler_text: spoilerText,
visibility: overridePrivacy || getState().getIn(['compose', 'privacy']),
visibility: visibility,
poll: getState().getIn(['compose', 'poll'], null),
language: getState().getIn(['compose', 'language']),
quoted_status_id: getState().getIn(['compose', 'quoted_status_id']),
quote_approval_policy: visibility === 'private' || visibility === 'direct' ? 'nobody' : getState().getIn(['compose', 'quote_policy']),
},
headers: {
'Idempotency-Key': getState().getIn(['compose', 'idempotencyKey']),
@@ -259,6 +269,9 @@ export function submitCompose(overridePrivacy = null) {
dispatch(insertIntoTagHistory(response.data.tags, status));
dispatch(submitComposeSuccess({ ...response.data }));
if (typeof successCallback === 'function') {
successCallback(response.data);
}
// To make the app more responsive, immediately push the status
// into the columns
@@ -330,6 +343,11 @@ export function doodleSet(options) {
export function uploadCompose(files) {
return function (dispatch, getState) {
// Exit if there's a quote.
if (getState().compose.get('quoted_status_id')) {
dispatch(showAlert({ message: messages.uploadQuote }));
return;
}
const uploadLimit = getState().getIn(['server', 'server', 'configuration', 'statuses', 'max_media_attachments']);
const media = getState().getIn(['compose', 'media_attachments']);
const pending = getState().getIn(['compose', 'pending_media_attachments']);

View File

@@ -1,9 +1,41 @@
import { defineMessages } from 'react-intl';
import { createAction } from '@reduxjs/toolkit';
import type { List as ImmutableList, Map as ImmutableMap } from 'immutable';
import { apiUpdateMedia } from 'flavours/glitch/api/compose';
import type { ApiMediaAttachmentJSON } from 'flavours/glitch/api_types/media_attachments';
import type { MediaAttachment } from 'flavours/glitch/models/media_attachment';
import { createDataLoadingThunk } from 'flavours/glitch/store/typed_functions';
import {
createDataLoadingThunk,
createAppThunk,
} from 'flavours/glitch/store/typed_functions';
import type { ApiQuotePolicy } from '../api_types/quotes';
import type { Status } from '../models/status';
import { showAlert } from './alerts';
import { focusCompose } from './compose';
import { openModal } from './modal';
const messages = defineMessages({
quoteErrorUpload: {
id: 'quote_error.upload',
defaultMessage: 'Quoting is not allowed with media attachments.',
},
quoteErrorPoll: {
id: 'quote_error.poll',
defaultMessage: 'Quoting is not allowed with polls.',
},
quoteErrorQuote: {
id: 'quote_error.quote',
defaultMessage: 'Only one quote at a time is allowed.',
},
quoteErrorUnauthorized: {
id: 'quote_error.unauthorized',
defaultMessage: 'You are not authorized to quote this post.',
},
});
type SimulatedMediaAttachmentJSON = ApiMediaAttachmentJSON & {
unattached?: boolean;
@@ -68,3 +100,73 @@ export const changeUploadCompose = createDataLoadingThunk(
useLoadingBar: false,
},
);
export const quoteCompose = createAppThunk(
'compose/quoteComposeStatus',
(status: Status, { dispatch }) => {
dispatch(focusCompose());
return status;
},
);
export const quoteComposeByStatus = createAppThunk(
(status: Status, { dispatch, getState }) => {
const state = getState();
const composeState = state.compose;
const mediaAttachments = composeState.get('media_attachments');
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const wasQuietPostHintModalDismissed: boolean =
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
state.settings.getIn(
['dismissed_banners', 'quote/quiet_post_hint'],
false,
);
if (composeState.get('poll')) {
dispatch(showAlert({ message: messages.quoteErrorPoll }));
} else if (
composeState.get('is_uploading') ||
(mediaAttachments &&
typeof mediaAttachments !== 'string' &&
typeof mediaAttachments !== 'number' &&
typeof mediaAttachments !== 'boolean' &&
mediaAttachments.size !== 0)
) {
dispatch(showAlert({ message: messages.quoteErrorUpload }));
} else if (composeState.get('quoted_status_id')) {
dispatch(showAlert({ message: messages.quoteErrorQuote }));
} else if (
status.getIn(['quote_approval', 'current_user']) !== 'automatic' &&
status.getIn(['quote_approval', 'current_user']) !== 'manual'
) {
dispatch(showAlert({ message: messages.quoteErrorUnauthorized }));
} else if (
status.get('visibility') === 'unlisted' &&
!wasQuietPostHintModalDismissed
) {
dispatch(
openModal({
modalType: 'CONFIRM_QUIET_QUOTE',
modalProps: { status },
}),
);
} else {
dispatch(quoteCompose(status));
}
},
);
export const quoteComposeById = createAppThunk(
(statusId: string, { dispatch, getState }) => {
const status = getState().statuses.get(statusId);
if (status) {
dispatch(quoteComposeByStatus(status));
}
},
);
export const quoteComposeCancel = createAction('compose/quoteComposeCancel');
export const setComposeQuotePolicy = createAction<ApiQuotePolicy>(
'compose/setQuotePolicy',
);

View File

@@ -21,6 +21,15 @@ export function normalizeFilterResult(result) {
return normalResult;
}
function stripQuoteFallback(text) {
const wrapper = document.createElement('div');
wrapper.innerHTML = text;
wrapper.querySelector('.quote-inline')?.remove();
return wrapper.innerHTML;
}
export function normalizeStatus(status, normalOldStatus, settings) {
const normalStatus = { ...status };
@@ -78,6 +87,11 @@ export function normalizeStatus(status, normalOldStatus, settings) {
normalStatus.spoilerHtml = emojify(escapeTextContentForBrowser(spoilerText), emojiMap);
normalStatus.hidden = (spoilerText.length > 0 || normalStatus.sensitive) && autoHideCW(settings, spoilerText);
// Remove quote fallback link from the DOM so it doesn't mess with paragraph margins
if (normalStatus.quote) {
normalStatus.contentHtml = stripQuoteFallback(normalStatus.contentHtml);
}
if (normalStatus.url && !(normalStatus.url.startsWith('http://') || normalStatus.url.startsWith('https://'))) {
normalStatus.url = null;
}
@@ -117,6 +131,11 @@ export function normalizeStatusTranslation(translation, status) {
spoiler_text: translation.spoiler_text,
};
// Remove quote fallback link from the DOM so it doesn't mess with paragraph margins
if (status.get('quote')) {
normalTranslation.contentHtml = stripQuoteFallback(normalTranslation.contentHtml);
}
return normalTranslation;
}

View File

@@ -1,8 +1,13 @@
import { apiReblog, apiUnreblog } from 'flavours/glitch/api/interactions';
import {
apiReblog,
apiUnreblog,
apiRevokeQuote,
apiGetQuotes,
} from 'flavours/glitch/api/interactions';
import type { StatusVisibility } from 'flavours/glitch/models/status';
import { createDataLoadingThunk } from 'flavours/glitch/store/typed_functions';
import { importFetchedStatus } from './importer';
import { importFetchedStatus, importFetchedStatuses } from './importer';
export const reblog = createDataLoadingThunk(
'status/reblog',
@@ -33,3 +38,35 @@ export const unreblog = createDataLoadingThunk(
return discardLoadData;
},
);
export const revokeQuote = createDataLoadingThunk(
'status/revoke_quote',
({
statusId,
quotedStatusId,
}: {
statusId: string;
quotedStatusId: string;
}) => apiRevokeQuote(quotedStatusId, statusId),
(data, { dispatch, discardLoadData }) => {
dispatch(importFetchedStatus(data));
return discardLoadData;
},
);
export const fetchQuotes = createDataLoadingThunk(
'status/fetch_quotes',
async ({ statusId, next }: { statusId: string; next?: string }) => {
const { links, statuses } = await apiGetQuotes(statusId, next);
return {
links,
statuses,
replace: !next,
};
},
(payload, { dispatch }) => {
dispatch(importFetchedStatuses(payload.statuses));
},
);

View File

@@ -30,8 +30,21 @@ import { importFetchedAccounts, importFetchedStatuses } from './importer';
import { NOTIFICATIONS_FILTER_SET } from './notifications';
import { saveSettings } from './settings';
function notificationTypeForFilter(type: NotificationType) {
if (type === 'quoted_update') return 'update';
else return type;
}
function notificationTypeForQuickFilter(type: NotificationType) {
if (type === 'quoted_update') return 'update';
else if (type === 'quote') return 'mention';
else return type;
}
function excludeAllTypesExcept(filter: string) {
return allNotificationTypes.filter((item) => item !== filter);
return allNotificationTypes.filter(
(item) => notificationTypeForQuickFilter(item) !== filter,
);
}
function getExcludedTypes(state: RootState) {
@@ -155,13 +168,17 @@ export const processNewNotificationForGroups = createAppAsyncThunk(
const showInColumn =
activeFilter === 'all'
? notificationShows[notification.type] !== false
: activeFilter === notification.type;
? notificationShows[notificationTypeForFilter(notification.type)] !==
false
: activeFilter === notificationTypeForQuickFilter(notification.type);
if (!showInColumn) return;
if (
(notification.type === 'mention' || notification.type === 'update') &&
(notification.type === 'mention' ||
notification.type === 'quote' ||
notification.type === 'update' ||
notification.type === 'quoted_update') &&
notification.status?.filtered
) {
const filters = notification.status.filtered.filter((result) =>

View File

@@ -31,7 +31,7 @@ export function updateNotifications(notification, intlMessages, intlLocale) {
let filtered = false;
if (['mention', 'status'].includes(notification.type) && notification.status.filtered) {
if (['mention', 'quote', 'status'].includes(notification.type) && notification.status.filtered) {
const filters = notification.status.filtered.filter(result => result.filter.context.includes('notifications'));
if (filters.some(result => result.filter.filter_action === 'hide')) {

View File

@@ -1,9 +1,12 @@
import { defineMessages } from 'react-intl';
import { browserHistory } from 'flavours/glitch/components/router';
import api from '../api';
import { showAlert } from './alerts';
import { ensureComposeIsVisible, setComposeToStatus } from './compose';
import { importFetchedStatus, importFetchedStatuses, importFetchedAccount } from './importer';
import { importFetchedStatus, importFetchedAccount } from './importer';
import { fetchContext } from './statuses_typed';
import { deleteFromTimelines } from './timelines';
@@ -40,6 +43,10 @@ export const STATUS_TRANSLATE_SUCCESS = 'STATUS_TRANSLATE_SUCCESS';
export const STATUS_TRANSLATE_FAIL = 'STATUS_TRANSLATE_FAIL';
export const STATUS_TRANSLATE_UNDO = 'STATUS_TRANSLATE_UNDO';
const messages = defineMessages({
deleteSuccess: { id: 'status.delete.success', defaultMessage: 'Post deleted' },
});
export function fetchStatusRequest(id, skipLoading) {
return {
type: STATUS_FETCH_REQUEST,
@@ -48,7 +55,18 @@ export function fetchStatusRequest(id, skipLoading) {
};
}
export function fetchStatus(id, forceFetch = false, alsoFetchContext = true) {
/**
* @param {string} id
* @param {Object} [options]
* @param {boolean} [options.forceFetch]
* @param {boolean} [options.alsoFetchContext]
* @param {string | null | undefined} [options.parentQuotePostId]
*/
export function fetchStatus(id, {
forceFetch = false,
alsoFetchContext = true,
parentQuotePostId,
} = {}) {
return (dispatch, getState) => {
const skipLoading = !forceFetch && getState().getIn(['statuses', id], null) !== null;
@@ -66,7 +84,7 @@ export function fetchStatus(id, forceFetch = false, alsoFetchContext = true) {
dispatch(importFetchedStatus(response.data));
dispatch(fetchStatusSuccess(skipLoading));
}).catch(error => {
dispatch(fetchStatusFail(id, error, skipLoading));
dispatch(fetchStatusFail(id, error, skipLoading, parentQuotePostId));
});
};
}
@@ -78,22 +96,28 @@ export function fetchStatusSuccess(skipLoading) {
};
}
export function fetchStatusFail(id, error, skipLoading) {
export function fetchStatusFail(id, error, skipLoading, parentQuotePostId) {
return {
type: STATUS_FETCH_FAIL,
id,
error,
parentQuotePostId,
skipLoading,
skipAlert: true,
};
}
export function redraft(status, raw_text, content_type) {
return {
type: REDRAFT,
status,
raw_text,
content_type,
return (dispatch, getState) => {
const maxOptions = getState().server.getIn(['server', 'configuration', 'polls', 'max_options']);
dispatch({
type: REDRAFT,
status,
raw_text,
content_type,
maxOptions,
});
};
}
@@ -138,7 +162,7 @@ export function deleteStatus(id, withRedraft = false) {
dispatch(deleteStatusRequest(id));
api().delete(`/api/v1/statuses/${id}`, { params: { delete_media: !withRedraft } }).then(response => {
return api().delete(`/api/v1/statuses/${id}`, { params: { delete_media: !withRedraft } }).then(response => {
dispatch(deleteStatusSuccess(id));
dispatch(deleteFromTimelines(id));
dispatch(importFetchedAccount(response.data.account));
@@ -146,9 +170,14 @@ export function deleteStatus(id, withRedraft = false) {
if (withRedraft) {
dispatch(redraft(status, response.data.text, response.data.content_type));
ensureComposeIsVisible(getState);
} else {
dispatch(showAlert({ message: messages.deleteSuccess }));
}
return response;
}).catch(error => {
dispatch(deleteStatusFail(id, error));
throw error;
});
};
}

View File

@@ -1,18 +1,34 @@
import { apiGetContext } from 'flavours/glitch/api/statuses';
import { createAction } from '@reduxjs/toolkit';
import { apiGetContext, apiSetQuotePolicy } from 'flavours/glitch/api/statuses';
import { createDataLoadingThunk } from 'flavours/glitch/store/typed_functions';
import type { ApiQuotePolicy } from '../api_types/quotes';
import { importFetchedStatuses } from './importer';
export const fetchContext = createDataLoadingThunk(
'status/context',
({ statusId }: { statusId: string }) => apiGetContext(statusId),
(context, { dispatch }) => {
({ context, refresh }, { dispatch }) => {
const statuses = context.ancestors.concat(context.descendants);
dispatch(importFetchedStatuses(statuses));
return {
context,
refresh,
};
},
);
export const completeContextRefresh = createAction<{ statusId: string }>(
'status/context/complete',
);
export const setStatusQuotePolicy = createDataLoadingThunk(
'status/setQuotePolicy',
({ statusId, policy }: { statusId: string; policy: ApiQuotePolicy }) => {
return apiSetQuotePolicy(statusId, policy);
},
);

View File

@@ -15,6 +15,50 @@ export const getLinks = (response: AxiosResponse) => {
return LinkHeader.parse(value);
};
export interface AsyncRefreshHeader {
id: string;
retry: number;
}
const isAsyncRefreshHeader = (obj: object): obj is AsyncRefreshHeader =>
'id' in obj && 'retry' in obj;
export const getAsyncRefreshHeader = (
response: AxiosResponse,
): AsyncRefreshHeader | null => {
const value = response.headers['mastodon-async-refresh'] as
| string
| undefined;
if (!value) {
return null;
}
const asyncRefreshHeader: Record<string, unknown> = {};
value.split(/,\s*/).forEach((pair) => {
const [key, val] = pair.split('=', 2);
let typedValue: string | number;
if (key && ['id', 'retry'].includes(key) && val) {
if (val.startsWith('"')) {
typedValue = val.slice(1, -1);
} else {
typedValue = parseInt(val);
}
asyncRefreshHeader[key] = typedValue;
}
});
if (isAsyncRefreshHeader(asyncRefreshHeader)) {
return asyncRefreshHeader;
}
return null;
};
const csrfHeader: RawAxiosRequestHeaders = {};
const setCSRFHeader = () => {
@@ -62,7 +106,7 @@ export default function api(withAuthorization = true) {
});
}
type ApiUrl = `v${1 | 2}/${string}`;
type ApiUrl = `v${1 | '1_alpha' | 2}/${string}`;
type RequestParamsOrData = Record<string, unknown>;
export async function apiRequest<ApiResponse = unknown>(

View File

@@ -0,0 +1,5 @@
import { apiRequestGet } from 'flavours/glitch/api';
import type { ApiAsyncRefreshJSON } from 'flavours/glitch/api_types/async_refreshes';
export const apiGetAsyncRefresh = (id: string) =>
apiRequestGet<ApiAsyncRefreshJSON>(`v1_alpha/async_refreshes/${id}`);

View File

@@ -1,10 +1,28 @@
import { apiRequestPost } from 'flavours/glitch/api';
import type { Status, StatusVisibility } from 'flavours/glitch/models/status';
import api, { apiRequestPost, getLinks } from 'flavours/glitch/api';
import type { ApiStatusJSON } from 'flavours/glitch/api_types/statuses';
import type { StatusVisibility } from 'flavours/glitch/models/status';
export const apiReblog = (statusId: string, visibility: StatusVisibility) =>
apiRequestPost<{ reblog: Status }>(`v1/statuses/${statusId}/reblog`, {
apiRequestPost<{ reblog: ApiStatusJSON }>(`v1/statuses/${statusId}/reblog`, {
visibility,
});
export const apiUnreblog = (statusId: string) =>
apiRequestPost<Status>(`v1/statuses/${statusId}/unreblog`);
apiRequestPost<ApiStatusJSON>(`v1/statuses/${statusId}/unreblog`);
export const apiRevokeQuote = (quotedStatusId: string, statusId: string) =>
apiRequestPost<ApiStatusJSON>(
`v1/statuses/${quotedStatusId}/quotes/${statusId}/revoke`,
);
export const apiGetQuotes = async (statusId: string, url?: string) => {
const response = await api().request<ApiStatusJSON[]>({
method: 'GET',
url: url ?? `/api/v1/statuses/${statusId}/quotes`,
});
return {
statuses: response.data,
links: getLinks(response),
};
};

View File

@@ -1,5 +1,31 @@
import { apiRequestGet } from 'flavours/glitch/api';
import type { ApiContextJSON } from 'flavours/glitch/api_types/statuses';
import api, { apiRequestPut, getAsyncRefreshHeader } from 'flavours/glitch/api';
import type {
ApiContextJSON,
ApiStatusJSON,
} from 'flavours/glitch/api_types/statuses';
export const apiGetContext = (statusId: string) =>
apiRequestGet<ApiContextJSON>(`v1/statuses/${statusId}/context`);
import type { ApiQuotePolicy } from '../api_types/quotes';
export const apiGetContext = async (statusId: string) => {
const response = await api().request<ApiContextJSON>({
method: 'GET',
url: `/api/v1/statuses/${statusId}/context`,
});
return {
context: response.data,
refresh: getAsyncRefreshHeader(response),
};
};
export const apiSetQuotePolicy = async (
statusId: string,
policy: ApiQuotePolicy,
) => {
return apiRequestPut<ApiStatusJSON>(
`v1/statuses/${statusId}/interaction_policy`,
{
quote_approval_policy: policy,
},
);
};

View File

@@ -37,7 +37,7 @@ export interface BaseApiAccountJSON {
roles?: ApiAccountJSON[];
statuses_count: number;
uri: string;
url: string;
url?: string;
username: string;
moved?: ApiAccountJSON;
suspended?: boolean;

View File

@@ -0,0 +1,7 @@
export interface ApiAsyncRefreshJSON {
async_refresh: {
id: string;
status: 'running' | 'finished';
result_count: number;
};
}

View File

@@ -7,12 +7,13 @@ import type { ApiReportJSON } from './reports';
import type { ApiStatusJSON } from './statuses';
// See app/model/notification.rb
export const allNotificationTypes = [
export const allNotificationTypes: NotificationType[] = [
'follow',
'follow_request',
'favourite',
'reblog',
'mention',
'quote',
'poll',
'status',
'update',
@@ -28,8 +29,10 @@ export type NotificationWithStatusType =
| 'reblog'
| 'status'
| 'mention'
| 'quote'
| 'poll'
| 'update';
| 'update'
| 'quoted_update';
export type NotificationType =
| NotificationWithStatusType

View File

@@ -0,0 +1,39 @@
import type { ApiStatusJSON } from './statuses';
export type ApiQuoteState = 'accepted' | 'pending' | 'revoked' | 'unauthorized';
export type ApiQuotePolicy =
| 'public'
| 'followers'
| 'following'
| 'nobody'
| 'unsupported_policy';
export type ApiUserQuotePolicy = 'automatic' | 'manual' | 'denied' | 'unknown';
interface ApiQuoteEmptyJSON {
state: Exclude<ApiQuoteState, 'accepted'>;
quoted_status: null;
}
interface ApiNestedQuoteJSON {
state: 'accepted';
quoted_status_id: string;
}
interface ApiQuoteAcceptedJSON {
state: 'accepted';
quoted_status: Omit<ApiStatusJSON, 'quote'> & {
quote: ApiNestedQuoteJSON | ApiQuoteEmptyJSON;
};
}
export type ApiQuoteJSON = ApiQuoteAcceptedJSON | ApiQuoteEmptyJSON;
export interface ApiQuotePolicyJSON {
automatic: ApiQuotePolicy[];
manual: ApiQuotePolicy[];
current_user: ApiUserQuotePolicy;
}
export function isQuotePolicy(policy: string): policy is ApiQuotePolicy {
return ['public', 'followers', 'nobody'].includes(policy);
}

View File

@@ -4,6 +4,7 @@ import type { ApiAccountJSON } from './accounts';
import type { ApiCustomEmojiJSON } from './custom_emoji';
import type { ApiMediaAttachmentJSON } from './media_attachments';
import type { ApiPollJSON } from './polls';
import type { ApiQuoteJSON, ApiQuotePolicyJSON } from './quotes';
// See app/modals/status.rb
export type StatusVisibility =
@@ -95,6 +96,7 @@ export interface ApiStatusJSON {
replies_count: number;
reblogs_count: number;
favorites_count: number;
quotes_count: number;
edited_at?: string;
favorited?: boolean;
@@ -118,6 +120,8 @@ export interface ApiStatusJSON {
card?: ApiPreviewCardJSON;
poll?: ApiPollJSON;
quote?: ApiQuoteJSON;
quote_approval?: ApiQuotePolicyJSON;
// glitch-soc additions
local_only?: boolean;
@@ -128,3 +132,15 @@ export interface ApiContextJSON {
ancestors: ApiStatusJSON[];
descendants: ApiStatusJSON[];
}
export interface ApiStatusSourceJSON {
id: string;
text: string;
spoiler_text: string;
}
export function isStatusVisibility(
visibility: string,
): visibility is StatusVisibility {
return ['public', 'unlisted', 'private', 'direct'].includes(visibility);
}

View File

@@ -1,20 +1,76 @@
import { useCallback } from 'react';
import { useLinks } from 'flavours/glitch/hooks/useLinks';
export const AccountBio: React.FC<{
note: string;
className: string;
}> = ({ note, className }) => {
const handleClick = useLinks();
import { EmojiHTML } from '../features/emoji/emoji_html';
import { useAppSelector } from '../store';
import { isModernEmojiEnabled } from '../utils/environment';
if (note.length === 0 || note === '<p></p>') {
interface AccountBioProps {
className: string;
accountId: string;
showDropdown?: boolean;
}
export const AccountBio: React.FC<AccountBioProps> = ({
className,
accountId,
showDropdown = false,
}) => {
const handleClick = useLinks(showDropdown);
const handleNodeChange = useCallback(
(node: HTMLDivElement | null) => {
if (!showDropdown || !node || node.childNodes.length === 0) {
return;
}
addDropdownToHashtags(node, accountId);
},
[showDropdown, accountId],
);
const note = useAppSelector((state) => {
const account = state.accounts.get(accountId);
if (!account) {
return '';
}
return isModernEmojiEnabled() ? account.note : account.note_emojified;
});
const extraEmojis = useAppSelector((state) => {
const account = state.accounts.get(accountId);
return account?.emojis;
});
if (note.length === 0) {
return null;
}
return (
<div
className={`${className} translate`}
dangerouslySetInnerHTML={{ __html: note }}
onClickCapture={handleClick}
/>
ref={handleNodeChange}
>
<EmojiHTML htmlString={note} extraEmojis={extraEmojis} />
</div>
);
};
function addDropdownToHashtags(node: HTMLElement | null, accountId: string) {
if (!node) {
return;
}
for (const childNode of node.childNodes) {
if (!(childNode instanceof HTMLElement)) {
continue;
}
if (
childNode instanceof HTMLAnchorElement &&
(childNode.classList.contains('hashtag') ||
childNode.innerText.startsWith('#')) &&
!childNode.dataset.menuHashtag
) {
childNode.dataset.menuHashtag = accountId;
} else if (childNode.childNodes.length > 0) {
addDropdownToHashtags(childNode, accountId);
}
}
}

View File

@@ -0,0 +1,110 @@
import type { Meta, StoryObj } from '@storybook/react-vite';
import { fn, expect } from 'storybook/test';
import { Alert } from '.';
const meta = {
title: 'Components/Alert',
component: Alert,
args: {
isActive: true,
animateFrom: 'side',
title: '',
message: '',
action: '',
onActionClick: fn(),
},
argTypes: {
isActive: {
control: 'boolean',
type: 'boolean',
description: 'Animate to the active (displayed) state of the alert',
},
animateFrom: {
control: 'radio',
type: 'string',
options: ['side', 'below'],
description:
'Direction that the alert animates in from when activated. `side` is dependent on reading direction, defaulting to left in ltr languages.',
},
title: {
control: 'text',
type: 'string',
description: '(Optional) title of the alert',
},
message: {
control: 'text',
type: 'string',
description: 'Main alert text',
},
action: {
control: 'text',
type: 'string',
description:
'Label of the alert action (requires `onActionClick` handler)',
},
},
tags: ['test'],
} satisfies Meta<typeof Alert>;
export default meta;
type Story = StoryObj<typeof meta>;
export const Simple: Story = {
args: {
message: 'Post published.',
},
render: (args) => (
<div style={{ overflow: 'clip', padding: '1rem' }}>
<Alert {...args} />
</div>
),
};
export const WithAction: Story = {
args: {
...Simple.args,
action: 'Open',
},
render: Simple.render,
play: async ({ args, canvas, userEvent }) => {
const button = await canvas.findByRole('button', { name: 'Open' });
await userEvent.click(button);
await expect(args.onActionClick).toHaveBeenCalled();
},
};
export const WithTitle: Story = {
args: {
title: 'Warning:',
message: 'This is an alert',
},
render: Simple.render,
};
export const WithDismissButton: Story = {
args: {
message: 'More replies found',
action: 'Show',
onDismiss: fn(),
},
render: Simple.render,
};
export const InSizedContainer: Story = {
args: WithDismissButton.args,
render: (args) => (
<div
style={{
overflow: 'clip',
padding: '1rem',
width: '380px',
maxWidth: '100%',
boxSizing: 'border-box',
}}
>
<Alert {...args} />
</div>
),
};

View File

@@ -0,0 +1,68 @@
import { useIntl } from 'react-intl';
import classNames from 'classnames';
import CloseIcon from '@/material-icons/400-24px/close.svg?react';
import { IconButton } from '../icon_button';
/**
* Snackbar/Toast-style notification component.
*/
export const Alert: React.FC<{
isActive?: boolean;
animateFrom?: 'side' | 'below';
title?: string;
message: string;
action?: string;
onActionClick?: () => void;
onDismiss?: () => void;
}> = ({
isActive,
animateFrom = 'side',
title,
message,
action,
onActionClick,
onDismiss,
}) => {
const intl = useIntl();
const hasAction = Boolean(action && onActionClick);
return (
<div
className={classNames('notification-bar', {
'notification-bar--active': isActive,
'from-side': animateFrom === 'side',
'from-below': animateFrom === 'below',
})}
>
<span className='notification-bar__content'>
{Boolean(title) && (
<span className='notification-bar__title'>{title}</span>
)}
{message}
</span>
{hasAction && (
<button className='notification-bar__action' onClick={onActionClick}>
{action}
</button>
)}
{onDismiss && (
<IconButton
title={intl.formatMessage({
id: 'dismissable_banner.dismiss',
defaultMessage: 'Dismiss',
})}
icon='times'
iconComponent={CloseIcon}
className='notification-bar__dismiss-button'
onClick={onDismiss}
/>
)}
</div>
);
};

View File

@@ -3,16 +3,16 @@ import { useState, useEffect } from 'react';
import { useIntl } from 'react-intl';
import type { IntlShape } from 'react-intl';
import classNames from 'classnames';
import { dismissAlert } from 'flavours/glitch/actions/alerts';
import type {
Alert,
Alert as AlertType,
TranslatableString,
TranslatableValues,
} from 'flavours/glitch/models/alert';
import { useAppSelector, useAppDispatch } from 'flavours/glitch/store';
import { Alert } from './alert';
const formatIfNeeded = (
intl: IntlShape,
message: TranslatableString,
@@ -25,8 +25,8 @@ const formatIfNeeded = (
return message;
};
const Alert: React.FC<{
alert: Alert;
const TimedAlert: React.FC<{
alert: AlertType;
dismissAfter: number;
}> = ({
alert: { key, title, message, values, action, onClick },
@@ -62,29 +62,13 @@ const Alert: React.FC<{
}, [dispatch, setActive, key, dismissAfter]);
return (
<div
className={classNames('notification-bar', {
'notification-bar-active': active,
})}
>
<div className='notification-bar-wrapper'>
{title && (
<span className='notification-bar-title'>
{formatIfNeeded(intl, title, values)}
</span>
)}
<span className='notification-bar-message'>
{formatIfNeeded(intl, message, values)}
</span>
{action && (
<button className='notification-bar-action' onClick={onClick}>
{formatIfNeeded(intl, action, values)}
</button>
)}
</div>
</div>
<Alert
isActive={active}
title={title ? formatIfNeeded(intl, title, values) : undefined}
message={formatIfNeeded(intl, message, values)}
action={action ? formatIfNeeded(intl, action, values) : undefined}
onActionClick={onClick}
/>
);
};
@@ -98,7 +82,11 @@ export const AlertsController: React.FC = () => {
return (
<div className='notification-list'>
{alerts.map((alert, idx) => (
<Alert key={alert.key} alert={alert} dismissAfter={5000 + idx * 1000} />
<TimedAlert
key={alert.key}
alert={alert}
dismissAfter={5000 + idx * 1000}
/>
))}
</div>
);

View File

@@ -13,9 +13,9 @@ import { useSelectableClick } from 'flavours/glitch/hooks/useSelectableClick';
const offset = [0, 4] as OffsetValue;
const popperConfig = { strategy: 'fixed' } as UsePopperOptions;
export const AltTextBadge: React.FC<{
description: string;
}> = ({ description }) => {
export const AltTextBadge: React.FC<{ description: string }> = ({
description,
}) => {
const accessibilityId = useId();
const anchorRef = useRef<HTMLButtonElement>(null);
const [open, setOpen] = useState(false);
@@ -56,7 +56,7 @@ export const AltTextBadge: React.FC<{
{({ props }) => (
<div {...props} className='hover-card-controller'>
<div // eslint-disable-line jsx-a11y/no-noninteractive-element-interactions
className='media-gallery__alt__popover dropdown-animation'
className='info-tooltip dropdown-animation'
role='region'
id={accessibilityId}
onMouseDown={handleMouseDown}

View File

@@ -53,6 +53,7 @@ const AutosuggestTextarea = forwardRef(({
onFocus,
autoFocus = true,
lang,
className,
}, textareaRef) => {
const [suggestionsHidden, setSuggestionsHidden] = useState(true);
@@ -192,7 +193,7 @@ const AutosuggestTextarea = forwardRef(({
};
return (
<div className='autosuggest-textarea'>
<div className={classNames('autosuggest-textarea', className)}>
<Textarea
ref={textareaRef}
className='autosuggest-textarea__textarea'

View File

@@ -9,6 +9,7 @@ interface BaseProps
extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'children'> {
block?: boolean;
secondary?: boolean;
plain?: boolean;
compact?: boolean;
dangerous?: boolean;
loading?: boolean;
@@ -35,6 +36,7 @@ export const Button: React.FC<Props> = ({
disabled,
block,
secondary,
plain,
compact,
dangerous,
loading,
@@ -62,6 +64,7 @@ export const Button: React.FC<Props> = ({
<button
className={classNames('button', className, {
'button-secondary': secondary,
'button--plain': plain,
'button--compact': compact,
'button--block': block,
'button--dangerous': dangerous,

View File

@@ -1,8 +1,3 @@
/* eslint-disable @typescript-eslint/no-unsafe-call,
@typescript-eslint/no-unsafe-return,
@typescript-eslint/no-unsafe-assignment,
@typescript-eslint/no-unsafe-member-access
-- the settings store is not yet typed */
import type { PropsWithChildren } from 'react';
import { useCallback, useState, useEffect } from 'react';
@@ -23,31 +18,48 @@ interface Props {
id: string;
}
export const DismissableBanner: React.FC<PropsWithChildren<Props>> = ({
id,
children,
}) => {
const dismissed = useAppSelector((state) =>
export function useDismissableBannerState({ id }: Props) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const dismissed: boolean = useAppSelector((state) =>
/* eslint-disable-next-line */
state.settings.getIn(['dismissed_banners', id], false),
);
const [isVisible, setIsVisible] = useState(
!bannerSettings.get(id) && !dismissed,
);
const dispatch = useAppDispatch();
const [visible, setVisible] = useState(!bannerSettings.get(id) && !dismissed);
const intl = useIntl();
const handleDismiss = useCallback(() => {
setVisible(false);
const dismiss = useCallback(() => {
setIsVisible(false);
bannerSettings.set(id, true);
dispatch(changeSetting(['dismissed_banners', id], true));
}, [id, dispatch]);
useEffect(() => {
if (!visible && !dismissed) {
// Store legacy localStorage setting on server
if (!isVisible && !dismissed) {
dispatch(changeSetting(['dismissed_banners', id], true));
}
}, [id, dispatch, visible, dismissed]);
}, [id, dispatch, isVisible, dismissed]);
if (!visible) {
return {
wasDismissed: !isVisible,
dismiss,
};
}
export const DismissableBanner: React.FC<PropsWithChildren<Props>> = ({
id,
children,
}) => {
const intl = useIntl();
const { wasDismissed, dismiss } = useDismissableBannerState({
id,
});
if (wasDismissed) {
return null;
}
@@ -58,7 +70,7 @@ export const DismissableBanner: React.FC<PropsWithChildren<Props>> = ({
icon='times'
iconComponent={CloseIcon}
title={intl.formatMessage(messages.dismiss)}
onClick={handleDismiss}
onClick={dismiss}
/>
</div>

View File

@@ -1,122 +0,0 @@
import React from 'react';
import type { List } from 'immutable';
import type { Account } from 'flavours/glitch/models/account';
import { autoPlayGif } from '../initial_state';
import { Skeleton } from './skeleton';
interface Props {
account?: Account;
others?: List<Account>;
localDomain?: string;
}
export class DisplayName extends React.PureComponent<Props> {
handleMouseEnter: React.ReactEventHandler<HTMLSpanElement> = ({
currentTarget,
}) => {
if (autoPlayGif) {
return;
}
const emojis =
currentTarget.querySelectorAll<HTMLImageElement>('img.custom-emoji');
emojis.forEach((emoji) => {
const originalSrc = emoji.getAttribute('data-original');
if (originalSrc != null) emoji.src = originalSrc;
});
};
handleMouseLeave: React.ReactEventHandler<HTMLSpanElement> = ({
currentTarget,
}) => {
if (autoPlayGif) {
return;
}
const emojis =
currentTarget.querySelectorAll<HTMLImageElement>('img.custom-emoji');
emojis.forEach((emoji) => {
const staticSrc = emoji.getAttribute('data-static');
if (staticSrc != null) emoji.src = staticSrc;
});
};
render() {
const { others, localDomain } = this.props;
let displayName: React.ReactNode,
suffix: React.ReactNode,
account: Account | undefined;
if (others && others.size > 0) {
account = others.first();
} else if (this.props.account) {
account = this.props.account;
}
if (others && others.size > 1) {
displayName = others
.take(2)
.map((a) => (
<bdi key={a.get('id')}>
<strong
className='display-name__html'
dangerouslySetInnerHTML={{ __html: a.get('display_name_html') }}
/>
</bdi>
))
.reduce((prev, cur) => [prev, ', ', cur]);
if (others.size - 2 > 0) {
suffix = `+${others.size - 2}`;
}
} else if (account) {
let acct = account.get('acct');
if (!acct.includes('@') && localDomain) {
acct = `${acct}@${localDomain}`;
}
displayName = (
<bdi>
<strong
className='display-name__html'
dangerouslySetInnerHTML={{
__html: account.get('display_name_html'),
}}
/>
</bdi>
);
suffix = <span className='display-name__account'>@{acct}</span>;
} else {
displayName = (
<bdi>
<strong className='display-name__html'>
<Skeleton width='10ch' />
</strong>
</bdi>
);
suffix = (
<span className='display-name__account'>
<Skeleton width='7ch' />
</span>
);
}
return (
<span
className='display-name'
onMouseEnter={this.handleMouseEnter}
onMouseLeave={this.handleMouseLeave}
>
{displayName} {suffix}
</span>
);
}
}

View File

@@ -0,0 +1,36 @@
import { useMemo } from 'react';
import type { ComponentPropsWithoutRef, FC } from 'react';
import { Skeleton } from '../skeleton';
import type { DisplayNameProps } from './index';
import { DisplayNameWithoutDomain } from './no-domain';
export const DisplayNameDefault: FC<
Omit<DisplayNameProps, 'variant'> & ComponentPropsWithoutRef<'span'>
> = ({ account, localDomain, className, ...props }) => {
const username = useMemo(() => {
if (!account) {
return null;
}
let acct = account.get('acct');
if (!acct.includes('@') && localDomain) {
acct = `${acct}@${localDomain}`;
}
return `@${acct}`;
}, [account, localDomain]);
return (
<DisplayNameWithoutDomain
account={account}
className={className}
{...props}
>
{' '}
<span className='display-name__account'>
{username ?? <Skeleton width='7ch' />}
</span>
</DisplayNameWithoutDomain>
);
};

View File

@@ -0,0 +1,52 @@
import type { ComponentPropsWithoutRef, FC } from 'react';
import type { LinkProps } from 'react-router-dom';
import type { Account } from '@/flavours/glitch/models/account';
import { Permalink } from 'flavours/glitch/components/permalink';
import { DisplayNameDefault } from './default';
import { DisplayNameWithoutDomain } from './no-domain';
import { DisplayNameSimple } from './simple';
export interface DisplayNameProps {
account?: Account;
localDomain?: string;
variant?: 'default' | 'simple' | 'noDomain';
}
export const DisplayName: FC<
DisplayNameProps & ComponentPropsWithoutRef<'span'>
> = ({ variant = 'default', ...props }) => {
if (variant === 'simple') {
return <DisplayNameSimple {...props} />;
} else if (variant === 'noDomain') {
return <DisplayNameWithoutDomain {...props} />;
}
return <DisplayNameDefault {...props} />;
};
export const LinkedDisplayName: FC<
Omit<LinkProps, 'to'> & {
displayProps: DisplayNameProps & ComponentPropsWithoutRef<'span'>;
}
> = ({ displayProps, children, ...linkProps }) => {
const { account } = displayProps;
if (!account) {
return <DisplayName {...displayProps} />;
}
return (
<Permalink
href={account.url}
to={`/@${account.acct}`}
title={`@${account.acct}`}
data-id={account.id}
data-hover-card-account={account.id}
{...linkProps}
>
{children}
<DisplayName {...displayProps} />
</Permalink>
);
};

View File

@@ -0,0 +1,39 @@
import type { ComponentPropsWithoutRef, FC } from 'react';
import classNames from 'classnames';
import { EmojiHTML } from '@/flavours/glitch/features/emoji/emoji_html';
import { isModernEmojiEnabled } from '@/flavours/glitch/utils/environment';
import { Skeleton } from '../skeleton';
import type { DisplayNameProps } from './index';
export const DisplayNameWithoutDomain: FC<
Omit<DisplayNameProps, 'variant' | 'localDomain'> &
ComponentPropsWithoutRef<'span'>
> = ({ account, className, children, ...props }) => {
return (
<span {...props} className={classNames('display-name', className)}>
<bdi>
{account ? (
<EmojiHTML
className='display-name__html'
htmlString={
isModernEmojiEnabled()
? account.get('display_name')
: account.get('display_name_html')
}
shallow
as='strong'
/>
) : (
<strong className='display-name__html'>
<Skeleton width='10ch' />
</strong>
)}
</bdi>
{children}
</span>
);
};

View File

@@ -0,0 +1,23 @@
import type { ComponentPropsWithoutRef, FC } from 'react';
import { EmojiHTML } from '@/flavours/glitch/features/emoji/emoji_html';
import { isModernEmojiEnabled } from '@/flavours/glitch/utils/environment';
import type { DisplayNameProps } from './index';
export const DisplayNameSimple: FC<
Omit<DisplayNameProps, 'variant' | 'localDomain'> &
ComponentPropsWithoutRef<'span'>
> = ({ account, ...props }) => {
if (!account) {
return null;
}
const accountName = isModernEmojiEnabled()
? account.get('display_name')
: account.get('display_name_html');
return (
<bdi>
<EmojiHTML {...props} htmlString={accountName} shallow as='span' />
</bdi>
);
};

View File

@@ -0,0 +1,141 @@
import { useCallback, useId, useMemo, useRef, useState } from 'react';
import type { ComponentPropsWithoutRef, FC } from 'react';
import { useIntl } from 'react-intl';
import type { MessageDescriptor } from 'react-intl';
import classNames from 'classnames';
import Overlay from 'react-overlays/Overlay';
import UnfoldMoreIcon from '@/material-icons/400-24px/unfold_more.svg?react';
import type { SelectItem } from '../dropdown_selector';
import { DropdownSelector } from '../dropdown_selector';
import { Icon } from '../icon';
import { matchWidth } from './utils';
interface DropdownProps {
disabled?: boolean;
items: SelectItem[];
onChange: (value: string) => void;
current: string;
labelId: string;
descriptionId?: string;
emptyText?: MessageDescriptor;
classPrefix: string;
}
export const Dropdown: FC<
DropdownProps & Omit<ComponentPropsWithoutRef<'button'>, keyof DropdownProps>
> = ({
disabled,
items,
current,
onChange,
labelId,
descriptionId,
classPrefix,
className,
id,
...buttonProps
}) => {
const intl = useIntl();
const buttonRef = useRef<HTMLButtonElement>(null);
const uniqueId = useId();
const buttonId = id ?? `${uniqueId}-button`;
const listboxId = `${uniqueId}-listbox`;
const [open, setOpen] = useState(false);
const handleToggle = useCallback(() => {
if (!disabled) {
setOpen((prevOpen) => {
buttonRef.current?.focus();
return !prevOpen;
});
}
}, [disabled]);
const handleClose = useCallback(() => {
setOpen(false);
buttonRef.current?.focus();
}, []);
const currentText = useMemo(
() =>
items.find((i) => i.value === current)?.text ??
intl.formatMessage({
id: 'dropdown.empty',
defaultMessage: 'Select an option',
}),
[current, intl, items],
);
return (
<>
<button
type='button'
{...buttonProps}
id={buttonId}
aria-labelledby={`${labelId} ${buttonId}`}
aria-describedby={descriptionId}
aria-expanded={open}
aria-controls={listboxId}
onClick={handleToggle}
disabled={disabled}
className={classNames(
`${classPrefix}__button`,
{
active: open,
disabled,
},
className,
)}
ref={buttonRef}
>
{currentText}
<Icon
id='unfold-icon'
icon={UnfoldMoreIcon}
className={`${classPrefix}__icon`}
/>
</button>
<Overlay
show={open}
offset={[0, 0]}
placement='bottom-start'
onHide={handleClose}
flip
target={buttonRef.current}
popperConfig={{
strategy: 'fixed',
modifiers: [matchWidth],
}}
>
{({ props, placement }) => (
<div {...props} className={`${classPrefix}__overlay`}>
<div
className={classNames(
'dropdown-animation',
`${classPrefix}__dropdown`,
placement,
)}
id={listboxId}
>
<DropdownSelector
items={items}
value={current}
onClose={handleClose}
onChange={onChange}
classNamePrefix={classPrefix}
/>
</div>
</div>
)}
</Overlay>
</>
);
};

Some files were not shown because too many files have changed in this diff Show More