Compare commits

...

419 commits

Author SHA1 Message Date
Essem
4f37b4873f
Merge remote-tracking branch 'upstream/main' 2024-05-14 21:20:27 -05:00
Claire
5ed6622a00
Merge pull request #2706 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 1959365c2f
2024-05-12 21:35:25 +02:00
Chee Aun
f65a6d50f1 [Glitch] Fix typo
Port c36a8786c1 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-11 22:44:41 +02:00
Claire
f35ba6963d Merge commit '1959365c2f410aa82874c5c05ab92c4eca4c4055' into glitch-soc/merge-upstream 2024-05-11 22:10:56 +02:00
Claire
1959365c2f
Add missing on_delete: :cascade on notification_policies (#30251) 2024-05-10 20:00:25 +00:00
renovate[bot]
346530732c
Update dependency utf-8-validate to v6.0.4 (#30248)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-10 19:19:47 +00:00
renovate[bot]
9920f41c0f
Update opentelemetry-ruby (non-major) (#30249)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-10 19:18:53 +00:00
Renaud Chaput
d09b02efb6
Group Ruby OTEL packages in Renovate PRs (#30242) 2024-05-10 16:33:10 +00:00
renovate[bot]
482d1087c5
Update dependency opentelemetry-instrumentation-faraday to v0.24.3 (#30237)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-10 14:19:41 +00:00
renovate[bot]
af71f236a2
Update dependency opentelemetry-instrumentation-excon to v0.22.2 (#30236)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-10 13:16:05 +00:00
renovate[bot]
d933e6b6ae
Update dependency opentelemetry-instrumentation-concurrent_ruby to v0.21.3 (#30235)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-10 13:16:02 +00:00
renovate[bot]
ded11eca4f
Update dependency pundit to v2.3.2 (#30222)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-10 13:15:54 +00:00
Renaud Chaput
68b9fe824d
Add OpenTelemetry instrumentation (#30130)
Co-authored-by: Juliano Costa <juliano.costa@datadoghq.com>
Co-authored-by: Robb Kidd <robbkidd@honeycomb.io>
2024-05-10 12:40:20 +00:00
Matt Jankowski
0d397db5dd
Consolidate system specs into single directory, use rspec tags for configuration (#30206) 2024-05-10 12:36:09 +00:00
Joshua Young
164b09bfcc
Update README.md setup steps (#30063) 2024-05-10 12:34:32 +00:00
Matt Jankowski
e20f2e7300
Update i18n to version 1.14.5 (#30198) 2024-05-10 12:34:20 +00:00
renovate[bot]
f3f63107f2
Update dependency @reduxjs/toolkit to v2.2.4 (#30223)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-10 09:59:15 +00:00
Matt Jankowski
fa43a6c835
Use more accurate redirect_uri in oauth spec (#30212) 2024-05-10 09:43:59 +00:00
Matt Jankowski
040aaf3a48
Use default: ... assignment for Devise config, fixes Style/ClassVars cop (#30214) 2024-05-10 09:42:01 +00:00
github-actions[bot]
c9557bdd3b
New Crowdin Translations (automated) (#30215)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-05-10 09:34:48 +00:00
renovate[bot]
3a5a1b2e58
Update dependency node to 20.13 (#30211)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-10 09:25:07 +00:00
renovate[bot]
1aa3976f28
Update dependency pino-http to v10.1.0 (#30199)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-10 09:23:45 +00:00
renovate[bot]
0a4a93038f
Update Yarn to v4.2.2 (#30220)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-10 09:22:47 +00:00
Chee Aun
c36a8786c1
Fix typo (#30224) 2024-05-10 09:19:27 +00:00
renovate[bot]
6ccee2600b
Update dependency rubocop to v1.63.5 (#30225)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-10 09:19:06 +00:00
renovate[bot]
6819bcc4b6
Update dependency glob to v10.3.14 (#30230)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-10 09:18:52 +00:00
Renaud Chaput
5a3062f723
Pass the CodeCov token from the secret to the action (#30219) 2024-05-10 08:00:02 +00:00
Essem
012698f97a
Fix video sizing in edit media modal 2024-05-09 23:35:20 -05:00
Essem
ac041ceefa
Remove custom favicon/app icons
Upstream now includes a way to change them from the admin UI.
2024-05-08 14:12:58 -05:00
Essem
f26fba7473
Merge remote-tracking branch 'upstream/main' 2024-05-08 13:58:54 -05:00
Claire
3286daa807
Merge pull request #2704 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to d8c4284723
2024-05-07 21:10:52 +02:00
Claire
21c904b0f6 Merge commit 'd8c428472356abd70aaf1f514b99114464ee7f61' into glitch-soc/merge-upstream 2024-05-07 20:30:17 +02:00
Claire
d8c4284723
Ensure custom favicon is converted to PNG and ICO (#30208) 2024-05-07 18:15:17 +00:00
renovate[bot]
c9ccba7045
Update dependency sass to v1.77.0 (#30200)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-07 12:43:11 +00:00
Claire
f7dadc9f0b Merge commit '5cd13ee4f19c112ea855063c2495e2874746f23a' into glitch-soc/merge-upstream 2024-05-07 12:13:02 +02:00
renovate[bot]
5cd13ee4f1
Update dependency aws-sdk-s3 to v1.149.1 (#30196)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-07 09:39:20 +00:00
renovate[bot]
8540004f7b
Update dependency dotenv to v3.1.2 (#30197)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-07 09:39:04 +00:00
github-actions[bot]
ed556db395
New Crowdin Translations (automated) (#30201)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-05-07 09:36:16 +00:00
Claire
96fb6e491f
Revert "Migrate paperclip _file_size columns to bigint (#29263)" (#30203) 2024-05-07 08:46:05 +00:00
Claire
996292cd55
Fix db:encryption:init requiring ActiveRecord encryption variables to be set (#30202) 2024-05-07 08:41:53 +00:00
Essem
b636ca2099
Merge remote-tracking branch 'upstream/main' 2024-05-06 22:12:42 -05:00
renovate[bot]
6167894547
Update dependency pino-http to v10 (#30191)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-06 17:14:46 +00:00
Claire
016d194274 Merge commit '2fe1b8d1695d8faa452a69872fde94ccc4611576' into glitch-soc/merge-upstream
Conflicts:
- `app/helpers/application_helper.rb`:
  Not a real conflict, upstream added helpers right next to glitch-soc only
  helpers.
  Added upstream's helpers.
- `spec/models/status_spec.rb`:
  Not a real conflict, upstream added specs right next to glitch-soc only
  specs.
  Added upstream's tests.
2024-05-06 17:53:51 +02:00
Claire
2fe1b8d169
Add API to get multiple accounts and statuses (#27871)
Co-authored-by: noellabo <noel.yoshiba@gmail.com>
2024-05-06 15:19:15 +00:00
Fawaz Farid
bc24c4792d
Allow admins to configure instance favicon and logo (#30040) 2024-05-06 15:06:52 +00:00
Matt Jankowski
b152f936c1
Migrate paperclip _file_size columns to bigint (#29263)
Co-authored-by: Claire <claire.github-309c@sitedethib.com>
2024-05-06 15:05:12 +00:00
Fawaz Farid
05126d106f
Redirect back after site upload deletion (#30141) 2024-05-06 13:31:39 +00:00
Emelia Smith
116f01ec7d
Implement RFC 8414 for OAuth 2.0 server metadata (#29191) 2024-05-06 13:17:56 +00:00
Claire
30ef9fccf0
Fix hashtag matching pattern matching some link anchors (#30190) 2024-05-06 12:47:19 +00:00
Claire
8e4fea77e3
Fix race condition in POST /api/v1/push/subscription (#30166) 2024-05-06 12:41:14 +00:00
Matt Jankowski
dbaa4ed891
Use chewy which relaxes ES version reqs (#30157) 2024-05-06 11:50:45 +00:00
Claire
e5062b7135
Fix post deletion not being deferred when those are part of an account warning (#30163) 2024-05-06 09:52:34 +00:00
renovate[bot]
4f0d18168c
Update DefinitelyTyped types (non-major) (#30184)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-06 08:46:43 +00:00
renovate[bot]
00c34070ae
Update eslint (non-major) (#30186)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-06 08:46:22 +00:00
renovate[bot]
86f17e4b32
Update devDependencies (non-major) (#30185)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-06 08:46:17 +00:00
github-actions[bot]
9be2c02e52
New Crowdin Translations (automated) (#30169)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-05-06 08:36:29 +00:00
renovate[bot]
a96b828023
Update dependency postcss-preset-env to v9.5.11 (#30171)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-06 08:26:33 +00:00
renovate[bot]
d544b83f91
Update formatjs monorepo (#30175)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-06 08:26:28 +00:00
renovate[bot]
e4841ca82b
Update dependency irb to v1.13.1 (#30177)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-06 08:26:12 +00:00
Claire
e9cca1cc09
Merge pull request #2701 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to b7902225d6
2024-05-05 18:32:37 +02:00
Tim Rogers
2f73e486b7
Switched HTMLEntities to the expanded flavor which supports a larger … (#30173) 2024-05-05 02:24:10 +00:00
Renaud Chaput
c59f6ef5b8 [Glitch] Convert entrypoints/two_factor_authentication to Typescript
Port 9e260014c7 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-04 16:30:24 +02:00
mogaminsk
b6ada33ad4 [Glitch] Fix word breaking in filtered notifications badge
Port 616e2f2666 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-04 16:30:05 +02:00
Claire
3789d9f825 Merge commit 'b7902225d698a107df2cf8b4ca221caad38fa464' into glitch-soc/merge-upstream
Conflicts:
- `spec/validators/status_length_validator_spec.rb`:
  Upstream refactored tests to stub `StatusLengthValidator::MAX_CHARS`
  while glitch-soc had custom code to read from `MAX_TOOT_CHARS`.
  Switched to using upstream's implementation of the tests.
2024-05-04 16:28:30 +02:00
Claire
4b82dc84f5 [Glitch] Change width breakpoint for mobile placement behavior
Port 26e10aa203 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-04 16:16:22 +02:00
Claire
6662d604c1 [Glitch] Add loading indicator and empty result message to advanced interface search
Port 7d3fe2b4c3 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-04 16:15:54 +02:00
Renaud Chaput
e62595c966 [Glitch] Remove usage of deprecated defaultTypes on React functional components
Port b9b4db483c to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-04 16:15:16 +02:00
Claire
f09f5b35f2 Merge commit 'd97d31cce664281d868e4c661451687a301c97c8' into glitch-soc/merge-upstream
Conflicts:
- `app/models/account.rb`:
  Upstream refactored this file a bit, moving validation limits to constants.
  We already had a similar change, although with different constant names.
  Updated to match upstream's code.

The following files were also modified accordingly:
- `app/views/settings/profiles/show.html.haml`
- `spec/requests/api/v1/accounts/credentials_spec.rb`
2024-05-04 16:12:51 +02:00
Renaud Chaput
494d28bb56 [Glitch] Convert entrypoints/sign_up to Typescript
Port 4527e012da to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-04 15:51:58 +02:00
Renaud Chaput
fe7db7905f [Glitch] Convert easy entrypoints files to Typescript
Port 36909065b5 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-04 15:49:30 +02:00
David Beck
defd1e4024 [Glitch] Remove home marker updates
Port 4f4b77920e to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-04 15:42:33 +02:00
Claire
a76980a229 Merge commit 'f0c9cbaf3b079700b8179222d409c644dfd8ff66' into glitch-soc/merge-upstream 2024-05-04 15:40:07 +02:00
Renaud Chaput
552e09d57f [Glitch] Fix marker thunks to not ignore eslint directives for the whole file
Port 65093c619f to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-04 15:30:18 +02:00
Claire
a4ce53df27 [Glitch] Change moderation warning notification icon
Port de4a7bf531 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-04 15:29:51 +02:00
Claire
aac59a34ed [Glitch] Add in-app notifications for moderation actions/warnings
Port 4ef0b48b95 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-04 15:29:29 +02:00
Eugen Rochko
8dbcf8a287 [Glitch] Change design of people tab on explore in web UI
Port 0ec061aa8f to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-04 15:28:17 +02:00
Claire
d6f9c97ae4 Merge commit '7201f99cf83a74331febd1624ca9aaace68af5e6' into glitch-soc/merge-upstream 2024-05-04 15:24:22 +02:00
Eugen Rochko
333905b2d5 [Glitch] Change mute options to be in dropdown on muted users list in web UI
Port 74012831f6 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-04 15:15:00 +02:00
Claire
bac4026d80 Merge commit '85fdbd0ad53837c9209acf3fb45811d5bae41cd9' into glitch-soc/merge-upstream 2024-05-04 15:10:54 +02:00
Claire
bceb45adda Merge commit '3f6887557b23d363e7f8f18518db4447739d64bb' into glitch-soc/merge-upstream
Conflicts:
- `app/javascript/entrypoints/common.js`:
  Upstream moved everything from `app/javascript/packs` to
  `app/javascript/entrypoints` while this file was a glitch-soc
  addition. Moved it like the rest.
- `tsconfig.json`:
  Conflict due to glitch-soc's flavor.
  Updated like upstream.

Also moved and updated the following files accordingly:
- `app/javascript/flavours/vanilla/theme.yml`
- `app/javascript/flavours/glitch/theme.yml`
- everything in `app/javascript/flavours/glitch/packs`
2024-05-04 14:59:00 +02:00
Matt Jankowski
b7902225d6
Use built-in github annotation output for stylelint (#30165) 2024-05-03 14:56:48 +00:00
Claire
33368e3e79
Change ActiveRecordEncryption variable to be more explicit (#30151) 2024-05-03 09:26:24 +00:00
Râu Cao
9aa31be8d3
Fix local account search on LDAP login being case-sensitive (#30113)
Co-authored-by: Claire <claire.github-309c@sitedethib.com>
2024-05-03 09:22:48 +00:00
github-actions[bot]
d5444a2c6c
New Crowdin Translations (automated) (#30160)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-05-03 09:15:06 +00:00
renovate[bot]
9380805fc1
Update dependency rubocop-rspec to v2.29.2 (#30158)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-03 08:48:09 +00:00
Essem
a7b905d573
Merge remote-tracking branch 'upstream/main' 2024-05-02 23:31:54 -05:00
renovate[bot]
4b2054ee57
Update Yarn to v4.2.1 (#30153)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-02 21:22:26 +00:00
Claire
253ead3aa7
Fix not being able to block a subdomain of an already-blocked domain through the API (#30119) 2024-05-02 20:56:21 +00:00
Renaud Chaput
9e260014c7
Convert entrypoints/two_factor_authentication to Typescript (#30105) 2024-05-02 12:02:13 +00:00
Claire
e7b09486ed
Merge pull request #2699 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to a2399046ca
2024-05-02 12:55:04 +02:00
mogaminsk
616e2f2666
Fix word breaking in filtered notifications badge (#30114) 2024-05-02 09:40:18 +00:00
Matt Jankowski
88882fbbee
Move Rails/HABTM cop out of todo (#30118) 2024-05-02 09:40:05 +00:00
Matt Jankowski
1e7d5d2957
Update devise-two-factor to version 5.0.0 (#28325)
Co-authored-by: Claire <claire.github-309c@sitedethib.com>
2024-05-02 09:31:41 +00:00
github-actions[bot]
309f352e6a
New Crowdin Translations (automated) (#30140)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-05-02 08:57:30 +00:00
Matt Jankowski
2447497a4c
Status length validation spec updates (#30132) 2024-05-02 08:31:06 +00:00
renovate[bot]
d97d31cce6
Update dependency irb to v1.13.0 (#30143)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-02 08:28:13 +00:00
renovate[bot]
ac1d830e6c
Update dependency aws-sdk-s3 to v1.149.0 (#30136)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-02 08:27:47 +00:00
renovate[bot]
474e5ffaae
Update dependency dotenv to v3.1.1 (#30133)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-02 08:15:49 +00:00
renovate[bot]
62992ba54a
Update dependency sass to v1.76.0 (#30138)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-02 08:14:45 +00:00
renovate[bot]
a9dd68b90a
Update dependency react-redux to v9.1.2 (#30146)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-02 08:00:43 +00:00
Claire
b039e62194 Merge commit 'a2399046ca600d492b492b8dae88011de687bece' into glitch-soc/merge-upstream 2024-05-01 19:49:59 +02:00
Claire
eeefb7cdbc Merge commit 'a15139bc02d279b9ef85e95990f41e3e88838d20' into glitch-soc/merge-upstream 2024-05-01 19:42:34 +02:00
Claire
6204d13a2e Merge commit 'ec71c02c4b028c3541742f023729aeb295a51559' into glitch-soc/merge-upstream
Conflicts:
- `Gemfile`:
  There was an extra newline in glitch-soc for some reason.
  Removed it.
2024-05-01 19:38:34 +02:00
Claire
360590ecd8 Merge commit 'a3902997440c71f161e392f1ad6c5cdcf6aba95d' into glitch-soc/merge-upstream
Conflicts:
- `app/controllers/accounts_controller.rb`:
  Conflict due to glitch-soc's local-only posting feature.
  Refactored as upstream did but kept local changes.
- `app/lib/account_statuses_filter.rb`:
  Conflict due to glitch-soc's local-only posting feature.
  Refactored as upstream did but kept local changes.
2024-05-01 19:30:41 +02:00
Claire
df933836ca [Glitch] Fix incorrect label for filtered notifications badge
Port 66ee0d4a1f to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-01 19:18:06 +02:00
Claire
62b3f284db [Glitch] Fix unfollow button being out of frame on small screens on old browsers
Port 4117c8f6b8 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-01 19:17:28 +02:00
Claire
946bd2e7e1 Merge commit '0622107449e72d35b22afeeba2f0ba983e914803' into glitch-soc/merge-upstream 2024-05-01 19:16:48 +02:00
renovate[bot]
ac5113d524 [Glitch] Update eslint (non-major)
Port 37d984b8bf to glitch-soc

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Renaud Chaput <renchap@gmail.com>
Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-01 19:04:59 +02:00
Claire
e76ddf79bc [Glitch] Add / keyboard shortcut to focus the search field
Port c386c36866 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-01 18:57:39 +02:00
Claire
6f342a6d4c Merge commit '34e826f373d20f6230d1ef0aa03ad41a3bdf5998' into glitch-soc/merge-upstream
Conflicts:
- `app/helpers/theme_helper.rb`:
  Conflict caused by our different theme systems.
  Ported upstream's changes.
- `app/models/account.rb`:
  Upstream basically made a change we already made.
  Moved constant declaration to match upstream.
2024-05-01 18:56:48 +02:00
Renaud Chaput
2d43547934 [Glitch] Fix webpack warnings due to unhandled extensions (LICENCE and README.md)
Port 730e2127e1 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-01 18:43:37 +02:00
Claire
9ce82a35cb Merge commit '20b1e55f24a87868d661fc7b033bbbbd48b1a918' into glitch-soc/merge-upstream 2024-05-01 18:42:26 +02:00
Claire
555e33a392 Merge commit 'b61ae28f8d4b6f269f50a05c3e65ec7f2c846d32' into glitch-soc/merge-upstream
Conflicts:
- `app/helpers/application_helper.rb`:
  Conflict because of our different theming systems.
  Updated accordingly, along with `app/helpers/theme_helper.rb`
  and `app/helpers/theme_helper_spec.rb`.
2024-05-01 18:38:55 +02:00
Michael Stanclift
3739dda2f6 [Glitch] Add purple border to active compose field search inputs
Port 1c87cb8019 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-01 17:31:39 +02:00
Claire
0fb469e2f3 Merge commit '52ab8a59c6e77b6409a7d4d81b15751732b3af91' into glitch-soc/merge-upstream 2024-05-01 17:30:52 +02:00
nicolas
41c43168fb [Glitch] Makes the star icon rotate around its actual centre axis
Port c6da3ee828 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-01 17:27:59 +02:00
Michael Stanclift
b21322b406 [Glitch] Fix blue border on emoji/language search in Safari & Chrome
Port e284417349 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-01 17:27:29 +02:00
Michael Stanclift
4543bb9384 [Glitch] Fix language and emoji search field background colors on light theme
Port 5d67247061 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-01 17:27:10 +02:00
Claire
3503fe1865 Merge commit '4045c069f8f91200d0e7c64a8097e425aee71041' into glitch-soc/merge-upstream 2024-05-01 17:26:21 +02:00
Claire
46cc9141c9 [Glitch] Fix contrast in notification request badge
Port 0b9d4103cb to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-01 17:23:07 +02:00
Claire
15f6d2d038 Merge commit 'd27eb181f6ab419d1745a1fe9b94094be17a618f' into glitch-soc/merge-upstream
Conflicts:
- `spec/requests/api/v2/instance_spec.rb`:
  Conflict due to glitch-soc having a different default site name.
  Updated the tests as upstream did, keeping glitch-soc's default name.
2024-05-01 17:22:02 +02:00
Renaud Chaput
87b9b23025 [Glitch] Use integers and not numbers in notification policy API counters
Port b4d991adaa to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-01 17:12:57 +02:00
Renaud Chaput
c316852a65 [Glitch] Add API types for status and related objects
Port e47a3d00fe to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-01 17:12:16 +02:00
Renaud Chaput
297c8c37b1 [Glitch] Fix Redux Middleware types
Port 07635228e2 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-01 17:08:44 +02:00
Michael Stanclift
0f756eaed2 [Glitch] Fix search box color on light theme
Port fa9574086d to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-01 17:08:05 +02:00
Claire
2c386d4cfe Merge commit 'c70c39cad03824c64564fa7d241e6bf01acbab76' into glitch-soc/merge-upstream 2024-05-01 17:06:49 +02:00
Claire
d52263e0e3 Merge commit '143d9553fa0187b9950a802cdedaea5c8cd12f75' into glitch-soc/merge-upstream
Conflicts:
- `yarn.lock`:
  Upstream updated dependencies textually close to a glitch-soc-only dependency.
  Updated the dependencies as well.
2024-05-01 17:04:33 +02:00
Michael Stanclift
3b1c8d56b2 [Glitch] Fix light theme header on mobile
Port 90eb4a5d01 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-01 16:49:21 +02:00
Michael Stanclift
1783820acd [Glitch] Fix background tint in single column light theme
Port 430da03160 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-01 16:48:55 +02:00
Renaud Chaput
375bd52d97 [Glitch] Handle createAppAsyncThunk rejected actions in the errors middleware
Port 69e5771881 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-01 16:48:27 +02:00
Claire
7f404fd635 Merge commit '90eb4a5d01f1f1e8a76e7dc814eae992a9c1ee16' into glitch-soc/merge-upstream 2024-05-01 16:47:25 +02:00
Renaud Chaput
b3d5567bd0 [Glitch] Remove global boosts state and convert boosts modal to Typescript
Port 67442f9039 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-01 16:42:20 +02:00
Claire
0f90e624c5 Merge commit '672c9f5f05bde788877ae0dcdb6668366c4c8941' into glitch-soc/merge-upstream
Conflicts:
- `app/helpers/application_helper.rb`:
  Conflict due to our theming system being different.
  Ported upstream's changes.
2024-05-01 16:10:45 +02:00
Claire
bc370938ef [Glitch] Fix logo pushing header buttons out of view on certain conditions in mobile layout
Port 4f068d4fcc to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-01 15:56:38 +02:00
Renaud Chaput
cc720cd38f [Glitch] Fix <RelativeTimestamp> types
Port 961bb84e4c to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-01 15:56:37 +02:00
Renaud Chaput
0ab212f6a9 [Glitch] Fix props for <Button>
Port d088964761 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-01 15:56:37 +02:00
Renaud Chaput
02f9ce9ce3 [Glitch] Fix PropTypes for some record objects
Port f2fd1da23f to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-01 15:56:37 +02:00
Claire
5cb4adbf4e [Glitch] Fix language picker and privacy picker not having a backdrop filter
Port c913e2f3e5 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-01 15:56:37 +02:00
Renaud Chaput
555f45f249 [Glitch] Fix notifications marker fetch
Port b9982ce578 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-01 15:56:37 +02:00
Renaud Chaput
371c5e59eb [Glitch] Rewrite PIP state in Typescript
Port 9fbe8d3a0c to glitch-soc

Co-authored-by: Claire <claire.github-309c@sitedethib.com>
Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-01 15:56:37 +02:00
Renaud Chaput
059e10e546 [Glitch] Rewrite markers reducer in Typescript
Port 27d014a7fa to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-01 14:55:03 +02:00
Claire
3f61981f5d Merge commit '8a498f4e65ecf27cc2c992d02b47f890dafef20b' into glitch-soc/merge-upstream 2024-05-01 14:50:16 +02:00
Claire
03af271d3d [Glitch] Fix column borders disappearing in advanced interface on low width viewports
Port b2d841ce9a to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-01 14:32:29 +02:00
Claire
7b46517c38 Merge commit 'd49343ed11b3c08c4e81ecd70e17e01bd30154a6' into glitch-soc/merge-upstream 2024-05-01 14:31:14 +02:00
Renaud Chaput
d63c0a2879 [Glitch] Support "system" theme setting (light/dark theme depending on user system preference)
Port 02ea161506 to glitch-soc

Co-authored-by: Nishiki Liu <hello@nshki.com>
Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-05-01 14:25:51 +02:00
Claire
a6147a831f Merge commit '02ea16150647ac3baf0bb8a89203ccc7200b4a2f' into glitch-soc/merge-upstream
Conflicts:
- `app/lib/themes.rb`
- `app/views/layouts/application.html.haml`
- `app/views/layouts/embedded.html.haml`
- `app/views/layouts/error.html.haml`
- `config/settings.yml`

All these conflicts are because glitch-soc and upstream have different theming
systems and upstream changed a few things to have dynamic theme selection based
on system settings.

Conflicts were solved to take that into account, and `current_theme` has been
changed in the process to return a tuple of `[flavour, skin]` to be used in
the `theme_style_tags` helper.
2024-05-01 14:25:47 +02:00
Claire
3024212403
Merge pull request #2698 from ClearlyClaire/glitch-soc/refactor/index-application
Rename `app/javascript/flavours/glitch/styles/index.scss` to `application.scss`
2024-05-01 13:09:43 +02:00
Claire
26e10aa203
Change width breakpoint for mobile placement behavior (#30131) 2024-04-30 23:39:28 +00:00
Claire
d6048d3a6c Add compatibility app/javascript/flavours/glitch/styles/index.scss 2024-04-30 21:27:04 +02:00
Claire
8a34c42341 Rename app/javascript/flavours/glitch/styles/index.scss to application.scss
This is just to reduce differences with upstream.
2024-04-30 21:03:04 +02:00
Claire
6f74ede26b
Merge pull request #2697 from ClearlyClaire/glitch-soc/refactor/revamp-theming-system
Simplify glitch-soc's theming system
2024-04-30 20:41:38 +02:00
Matt Jankowski
75470f1256
Use implicit dotenv load (#30121) 2024-04-30 13:00:39 +00:00
renovate[bot]
f3ea90b89e
Update workbox monorepo to v7.1.0 (#30047)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-30 09:12:25 +00:00
github-actions[bot]
56821ed879
New Crowdin Translations (automated) (#30128)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-04-30 09:05:53 +00:00
Shlee
40d7a553d2
Minor phrasing on tootcli statuses remove (#30122) 2024-04-30 08:51:39 +00:00
renovate[bot]
f5376c477d
Update babel monorepo to v7.24.5 (#30124)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-30 08:50:42 +00:00
Emelia Smith
81f0002e76
Fix missing destory audit logs for Domain Allows (#30125) 2024-04-30 08:48:02 +00:00
Shlee
b8f0a50435
docker-compose.yml version is obsolete (#30120) 2024-04-29 17:31:14 +00:00
renovate[bot]
f5d6362e90
Update dependency ws to v8.17.0 (#30097)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-29 15:48:34 +00:00
Matt Jankowski
924af400da
Remove unused memoization in CustomFilter#expires_in method (#30117) 2024-04-29 12:49:31 +00:00
Matt Jankowski
f1a4b4e228
Disable Style/SignalException cop (#30064) 2024-04-29 12:32:06 +00:00
Claire
7d3fe2b4c3
Add loading indicator and empty result message to advanced interface search (#30085) 2024-04-29 09:55:41 +00:00
Matt Jankowski
ac7f4d57bb
Use composable query in Status.without_replies scope (#30086) 2024-04-29 09:55:37 +00:00
Claire
95e9de5777
Prevent accidental serialization of Account and User records (#30079) 2024-04-29 09:45:58 +00:00
Matt Jankowski
e336466894
Use shared form partial for admin/rules views (#30067) 2024-04-29 09:33:27 +00:00
Matt Jankowski
a9816f051d
Use shared form partial for admin/warning_presets views (#30069) 2024-04-29 09:33:06 +00:00
Renaud Chaput
b9b4db483c
Remove usage of deprecated defaultTypes on React functional components (#30099) 2024-04-29 09:29:59 +00:00
Matt Jankowski
2739d8d5a4
Use shorter render call in admin/webhooks view (#30071) 2024-04-29 09:10:23 +00:00
Matt Jankowski
bbf1b603e0
Remove unused Account.popular scope (#30068) 2024-04-29 09:04:35 +00:00
renovate[bot]
6931cf5727
Update dependency aws-sdk-s3 to v1.148.0 (#30076)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-29 09:03:27 +00:00
Matt Jankowski
2123281f7c
Move Account limits to constants (#30087) 2024-04-29 09:02:47 +00:00
Matt Jankowski
f0c9cbaf3b
Use EXPIRATION_DURATIONS constant in CustomFilter class (#30088) 2024-04-29 09:01:46 +00:00
Renaud Chaput
4527e012da
Convert entrypoints/sign_up to Typescript (#30106) 2024-04-29 08:23:05 +00:00
github-actions[bot]
9be7efedf0
New Crowdin Translations (automated) (#30092)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-04-29 08:15:43 +00:00
renovate[bot]
00aec2f33a
Update peter-evans/create-pull-request action to v6.0.5 (#30112)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-29 08:10:20 +00:00
renovate[bot]
0efa9854a1
Update libretranslate/libretranslate Docker tag to v1.5.7 (#30111)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-29 08:10:04 +00:00
renovate[bot]
23223369e0
Update eslint (non-major) (#30110)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-29 08:09:50 +00:00
renovate[bot]
c0584a6f4f
Update devDependencies (non-major) (#30109)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-29 08:09:27 +00:00
renovate[bot]
31f3dd57e0
Update dependency rubocop to v1.63.4 (#30096)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-29 08:08:58 +00:00
renovate[bot]
d8a4cea41b
Update dependency haml_lint to v0.58.0 (#30094)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-29 08:08:43 +00:00
Renaud Chaput
36909065b5
Convert easy entrypoints files to Typescript (#30102) 2024-04-29 08:02:41 +00:00
David Beck
4f4b77920e
Remove home marker updates (#22721) 2024-04-29 07:55:58 +00:00
Matt Jankowski
7201f99cf8
Change default ruby version to 3.3.1 (#28013) 2024-04-29 07:41:59 +00:00
Claire
e0a3662d7b Drop hardcoded reliance on vanilla flavor 2024-04-28 22:38:11 +02:00
Claire
7208edbd37 Replace use_pack, layouts/theme and @theme by new helpers
Packs are now loaded from views, just like upstream, and are
identified by their filenames. The definition of `theme.yml` has
changed as such:
- `pack_directory` is now required
- `pack` is now unused
- `signed_in_preload` has been introduced
2024-04-28 15:45:42 +02:00
Claire
c3e12a4dfa Change how theme style packs are loaded
Load the `common` style pack, and then charge the style pack for the current
skin, independent from any selected JS pack.
2024-04-28 15:45:41 +02:00
Claire
93cdc66e64 Make common inheritence unconditional and simplify theming code 2024-04-28 15:06:48 +02:00
Claire
dee57982f1 Rename “home” pack to “application” 2024-04-28 15:06:41 +02:00
Claire
9a8be8cf49 Remove theme fallback mechanism
Remove the `fallback` property and do not fallback to using another flavour
when a pack is not available in the selected flavour.

Flavours should define all packs, and should they wish to piggy-back on
another one, they can import that other one's pack explicitly instead.
2024-04-28 15:05:16 +02:00
Claire
62bc36416f Get rid of app/javascript/core
Have all flavors implement everything they need instead.
2024-04-28 15:04:52 +02:00
Renaud Chaput
65093c619f
Fix marker thunks to not ignore eslint directives for the whole file (#30089) 2024-04-26 17:11:27 +00:00
Claire
de4a7bf531
Change moderation warning notification icon (#30081) 2024-04-26 15:33:15 +00:00
renovate[bot]
0cf6cf457d
Update dependency selenium-webdriver to v4.20.1 (#30060)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-26 15:32:48 +00:00
renovate[bot]
17e0a31fe3
Update dependency cssnano to v7 (#30061)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-26 15:32:38 +00:00
Michael Stanclift
bb8c6346fb
Reword and rearrange Content Retention page (#27733) 2024-04-26 15:17:41 +00:00
Matt Jankowski
b67b61b963
Ignore dotenv *.local files (#29932) 2024-04-26 14:50:39 +00:00
renovate[bot]
ac82f34f7d
Update dependency pino to v9 (#30057)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-26 14:49:54 +00:00
Claire
91ca90e25b
Fix Idempotency-Key ignored when scheduling a post (#30084) 2024-04-26 13:19:02 +00:00
Claire
e845594878
Fix moderator account being exposed in account moderation notification (#30082) 2024-04-26 12:42:06 +00:00
github-actions[bot]
5201882a23
New Crowdin Translations (automated) (#30077)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-04-26 10:05:18 +00:00
Essem
122be8305f
Merge remote-tracking branch 'upstream/main' 2024-04-25 12:59:20 -05:00
Claire
4ef0b48b95
Add in-app notifications for moderation actions/warnings (#30065) 2024-04-25 17:26:05 +00:00
Eugen Rochko
0ec061aa8f
Change design of people tab on explore in web UI (#30059) 2024-04-25 16:25:33 +00:00
github-actions[bot]
85fdbd0ad5
New Crowdin Translations (automated) (#30062)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-04-25 08:50:54 +00:00
Claire
113c931cda
Fix follow request notifications not being displayed (#2695) 2024-04-24 17:00:48 +02:00
Claire
b79df709a8
Merge pull request #2693 from glitch-soc/i18n/crowdin/translations
New Crowdin Translations (automated)
2024-04-24 17:00:31 +02:00
Matt Jankowski
d9eee9bf9a
Remove column defaults for status_pins timestamp columns (#29261) 2024-04-24 14:56:54 +00:00
Claire
0e071edccc Fix bogus translation files 2024-04-24 12:36:32 +02:00
Tim Rogers
b128474625
Fixed rendering of excess whitespace in status card titles (#30017) 2024-04-24 09:09:21 +00:00
Matt Jankowski
f4a53f3fb4
Extract constants for column size length validation limits (#30045) 2024-04-24 08:56:28 +00:00
github-actions[bot]
ebcf9840f4
New Crowdin Translations (automated) (#30050)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-04-24 08:45:24 +00:00
Eugen Rochko
74012831f6
Change mute options to be in dropdown on muted users list in web UI (#30049) 2024-04-24 08:45:12 +00:00
Matt Jankowski
b903e6909e
Disable Style/HashAsLastArrayItem cop (#30041) 2024-04-24 08:32:18 +00:00
Renaud Chaput
0e585b9a52
Update to Ruby 3.2.4 (#30036) 2024-04-24 08:21:05 +00:00
Matt Jankowski
3f6887557b
Move JS source from packs to entrypoints (#30037) 2024-04-23 16:45:12 +00:00
Matt Jankowski
32ead51e5a
Add material design icons to admin/settings views (#27780)
Co-authored-by: Claire <claire.github-309c@sitedethib.com>
2024-04-23 16:43:49 +00:00
Claire
a2399046ca
Fix string interpolation for software updates admin mailer (#30035) 2024-04-23 12:54:52 +00:00
Emelia Smith
049b159beb
Add read:me OAuth 2.0 scope, allowing more limited access to user data (#29087) 2024-04-23 11:47:00 +00:00
github-actions[bot]
d754b15afb
New Crowdin Translations (automated) (#30034)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-04-23 09:07:05 +00:00
renovate[bot]
91c7406b59
Update dependency postcss-preset-env to v9.5.9 (#30029)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-23 08:41:50 +00:00
renovate[bot]
1471c0d4e0
Update dependency rubocop to v1.63.3 (#30031)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-23 08:41:33 +00:00
renovate[bot]
483fabf48a
Update dependency http to '~> 5.2.0' (#30027)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Claire <claire.github-309c@sitedethib.com>
2024-04-22 14:02:47 +00:00
Claire
2ef098d01c
Revert "Rely on dotenv autoload instead of explicit call (#30007)" (#30028) 2024-04-22 14:02:24 +00:00
Matt Jankowski
33e829763d
Use shared form partial for admin/domain_blocks views (#29609) 2024-04-22 12:22:16 +00:00
Matt Jankowski
ffbbf74c50
Limit http gem version to 5.1.x series (#30010) 2024-04-22 09:01:36 +00:00
Matt Jankowski
56b095edeb
Update Gemfile.lock ruby and bundler versions (#30011) 2024-04-22 09:01:24 +00:00
Tim Rogers
1ca6ff8ca5
Fixed crash when supplying FFMPEG_BINARY environment variable (#30022) 2024-04-22 09:00:24 +00:00
Tim Rogers
75163d9daf
Fixed rendering error on /start when not logged in (#30023) 2024-04-22 08:53:08 +00:00
github-actions[bot]
3655fb6a22
New Crowdin Translations (automated) (#30014)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-04-22 08:42:35 +00:00
Matt Jankowski
18737aad49
Rely on dotenv autoload instead of explicit call (#30007) 2024-04-22 08:31:20 +00:00
Matt Jankowski
a15139bc02
Fix intermittent order based failure in UpdateStatusService spec (#30008) 2024-04-22 08:30:38 +00:00
renovate[bot]
24e67c4394
Update dependency postcss-preset-env to v9.5.8 (#30018)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-22 08:24:08 +00:00
renovate[bot]
3e21af3e4a
Update dependency @types/react to v18.2.79 (#30024)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-22 08:14:09 +00:00
renovate[bot]
88f946890d
Update peter-evans/create-pull-request action to v6.0.4 (#30025)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-22 08:13:28 +00:00
renovate[bot]
223936c2e8
Update eslint (non-major) to v7.7.0 (#30026)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-22 08:13:04 +00:00
Matt Jankowski
2ec9bff36e
Fix Rubocop Rails/UniqueValidationWithoutIndex cop (#27461)
Co-authored-by: Claire <claire.github-309c@sitedethib.com>
2024-04-22 08:04:05 +00:00
GitHub Actions
c61130af33 New Crowdin translations 2024-04-22 04:27:38 +00:00
Matt Jankowski
35b517c207
Remove remnants of capistrano (#30009) 2024-04-19 20:53:01 +00:00
Matt Jankowski
369b2ef0ed
Fix Style/TrailingCommaInHashLiteral cop (#30004) 2024-04-19 20:52:01 +00:00
Matt Jankowski
c7384adc00
Fix Style/TrailingCommaInArguments cop (#30003) 2024-04-19 20:37:18 +00:00
Matt Jankowski
b6f04aed35
Silence warning about requiring rubocop-rspec_rails (#30002) 2024-04-19 20:35:00 +00:00
Matt Jankowski
933189887b
Fix Style/StringLiterals cop (#30005) 2024-04-19 20:33:00 +00:00
Matt Jankowski
8d47ba893a
Fix Style/PercentLiteralDelimiters cop (#30006) 2024-04-19 20:32:26 +00:00
renovate[bot]
d24462c81a
Update dependency test-prof to v1.3.3 (#30000)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-19 19:46:13 +00:00
Matt Jankowski
fa5e154ee3
Indirect deps gem version bumps (#29998) 2024-04-19 19:45:41 +00:00
Matt Jankowski
f5d341382e
Add any_args to have_enqueued_sidekiq_job call (quiets deprecation) (#29999) 2024-04-19 19:44:59 +00:00
Matt Jankowski
f386eb6c63
Replace deprecated dotenv-rails gem with dotenv gem (#29173) 2024-04-19 14:25:14 +00:00
github-actions[bot]
ec71c02c4b
New Crowdin Translations (automated) (#29994)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-04-19 13:57:43 +00:00
Matt Jankowski
4837bfcc6a
Use shared form partial for admin/announcements views (#29608) 2024-04-19 13:57:32 +00:00
renovate[bot]
e5d5bd7ff1
Update dependency postcss-preset-env to v9.5.6 (#29983)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-18 16:24:55 +00:00
Matt Jankowski
75f9c652e2
Fix Bundler/OrderedGems cop (#28400) 2024-04-18 16:24:22 +00:00
github-actions[bot]
443186ff40
New Crowdin Translations (automated) (#29980)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-04-18 11:18:39 +00:00
Matt Jankowski
11e0049b08
Use enum-generated scopes/queries for BulkImport (#29975) 2024-04-18 10:13:35 +00:00
renovate[bot]
630572323f
Update dependency ioredis to v5.4.1 (#29977)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-17 21:52:26 +00:00
renovate[bot]
1ad119941f
Update dependency rspec-sidekiq to v4.2.0 (#29964)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-17 11:14:09 +00:00
Claire
8bece467f8
Change have_enqueued_sidekiq_job usage to always make argument expectations explicit (#29974) 2024-04-17 11:13:52 +00:00
Matt Jankowski
013671f29f
Rename JS testing section in GH Actions config (#29931) 2024-04-17 10:23:07 +00:00
Matt Jankowski
650c548c31
Add not_featured_by scope to Tag (#28815) 2024-04-17 10:05:38 +00:00
Matt Jankowski
1d3ecd3fba
Add API::Pagination concern (#28826) 2024-04-17 09:22:45 +00:00
Matt Jankowski
828299e71c
Enable AR Encryption (#29831) 2024-04-17 09:19:02 +00:00
renovate[bot]
a390299744
Update dependency ioredis to v5.4.0 (#29969)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-17 09:08:19 +00:00
renovate[bot]
ee8f999a7b
Update dependency core-js to v3.37.0 (#29968)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-17 09:08:08 +00:00
github-actions[bot]
c35042b7eb
New Crowdin Translations (automated) (#29972)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-04-17 09:07:13 +00:00
Claire
fc89ecc6ca
Change /api/v1/announcements to return regular Status entities (#26736) 2024-04-17 09:06:23 +00:00
Matt Jankowski
9ae2594726
Add reusable duplicate ID finder methods in maintenance CLI (#28910) 2024-04-17 09:00:08 +00:00
renovate[bot]
03abff3b30
Update dependency aws-sdk-s3 to v1.147.0 (#29967)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-17 08:30:58 +00:00
Matt Jankowski
9ce2db4136
Combine double subject runs and DRY up change check in bulk import service spec (#29402) 2024-04-17 08:23:25 +00:00
Matt Jankowski
6fed108703
Use Rails upsert to generate update_count! query in Counters concern (#28738)
Co-authored-by: Claire <claire.github-309c@sitedethib.com>
2024-04-17 08:16:51 +00:00
Claire
5915bd7f45
Fix development environment admin account not being auto-approved (#29958) 2024-04-16 17:30:32 +00:00
Matt Jankowski
caad1e2628
Add scope Status.distributable_visibility (#29950) 2024-04-16 13:16:54 +00:00
renovate[bot]
0622107449
Update dependency @testing-library/react to v15 (#29893)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-16 09:44:02 +00:00
Matt Jankowski
6b33d3f81b
Add CustomFilter.unexpired scope (#29896) 2024-04-16 09:29:34 +00:00
Claire
66ee0d4a1f
Fix incorrect label for filtered notifications badge (#29922) 2024-04-16 09:25:23 +00:00
Matt Jankowski
3159c0a547
Add scope Status.list_eligible_visibility (#29951) 2024-04-16 09:17:03 +00:00
renovate[bot]
e6927db2fe
Update dependency rubocop to v1.63.2 (#29959)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-16 08:58:04 +00:00
renovate[bot]
6ee1b034b6
Update dependency prom-client to v15.1.2 (#29957)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-16 08:45:20 +00:00
github-actions[bot]
285d4123b5
New Crowdin Translations (automated) (#29955)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-04-16 08:36:21 +00:00
Matt Jankowski
7fed4a9740
Pull out repeated setup to shared setup in statusus/show view spec (#29927) 2024-04-15 15:24:31 +00:00
Claire
4117c8f6b8
Fix unfollow button being out of frame on small screens on old browsers (#29923) 2024-04-15 11:56:48 +00:00
Matt Jankowski
1549e6a9dc
Drop support for Ruby 3.0 (reaching EOL) (#29702) 2024-04-15 10:19:23 +00:00
github-actions[bot]
4e78cb9988
New Crowdin Translations (automated) (#29939)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-04-15 09:29:39 +00:00
Matt Jankowski
0d9ad96d3f
Rename PremailerWebpackStrategy -> PremailerBundledAssetStrategy (#29934) 2024-04-15 09:16:59 +00:00
Matt Jankowski
bf5d948237
Fix Style/SingleArgumentDig cop in webpacker/manifest_extensions (#29929) 2024-04-15 09:15:32 +00:00
Renaud Chaput
67dd1763bb
Fix PostCSS config (#29926) 2024-04-15 09:06:06 +00:00
Renaud Chaput
ee4ea83a87
Remove image_pack_tag usage (#29925) 2024-04-15 09:05:19 +00:00
renovate[bot]
34e826f373
Update dependency typescript to v5.4.5 (#29945)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-15 07:28:29 +00:00
renovate[bot]
1906330d13
Update dependency react-redux to v9.1.1 (#29943)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-15 07:27:56 +00:00
renovate[bot]
80edd7a317
Update DefinitelyTyped types (non-major) (#29944)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-15 07:27:33 +00:00
renovate[bot]
e3dd60cce1
Update peter-evans/create-pull-request action to v6.0.3 (#29946)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-15 07:26:57 +00:00
renovate[bot]
86c53e175d
Update dependency @testing-library/react to v14.3.1 (#29947)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-15 07:26:41 +00:00
renovate[bot]
c4d6e10115
Update dependency rubocop to v1.63.1 (#29878)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-12 10:57:37 +00:00
renovate[bot]
67a37c7279
Update dependency sass to v1.75.0 (#29919)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-12 10:56:49 +00:00
Matt Jankowski
61d108f415
Extract header_tags method in statuses/show view spec (#29907) 2024-04-12 09:50:46 +00:00
renovate[bot]
8986e3b088
Update dependency webpack-bundle-analyzer to v4.10.2 (#29909)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-12 09:48:13 +00:00
Claire
c386c36866
Add / keyboard shortcut to focus the search field (#29921) 2024-04-12 09:42:12 +00:00
renovate[bot]
3f821e0d5e
Update dependency postcss-preset-env to v9.5.5 (#29912)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-12 09:41:44 +00:00
Matt Jankowski
da6b9238f5
Expand coverage for admin/metrics/measure/* classes (#29914) 2024-04-12 09:38:24 +00:00
Matt Jankowski
ec5a0e0f5e
Expand coverage for admin/metrics/dimension/* classes (#29913) 2024-04-12 09:18:35 +00:00
Matt Jankowski
13bbde2246
Use existing DEFAULT_FIELDS_SIZE constant to limit Account#fields (#29911) 2024-04-12 09:04:23 +00:00
github-actions[bot]
5992df0762
New Crowdin Translations (automated) (#29920)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-04-12 08:19:48 +00:00
Matt Jankowski
449f99e168
Fix repeated concat output buffer duplicating layout markup (#29918) 2024-04-11 23:37:07 +00:00
github-actions[bot]
20b1e55f24
New Crowdin Translations (automated) (#29903)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-04-11 10:30:31 +00:00
renovate[bot]
4826c1da8a
Update dependency devise to v4.9.4 (#29890)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-11 09:00:15 +00:00
Matt Jankowski
576554b19b
Use fabrication sequence in domain values (#29895) 2024-04-11 08:59:01 +00:00
renovate[bot]
96bdeeed0e
Update dependency nokogiri to v1.16.4 (#29900)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-11 08:50:34 +00:00
github-actions[bot]
db5a5636d9
New Crowdin Translations (automated) (#29888)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-04-10 13:03:40 +00:00
Matt Jankowski
4565015615
Fix Style/MapIntoArray cop in cli progress helper (#29884) 2024-04-10 12:46:43 +00:00
Matt Jankowski
b57ee5cf5b
Fix Style/MapIntoArray cop in context helper (#29885) 2024-04-10 12:46:39 +00:00
Matt Jankowski
4948a063d2
Use tt extension for form scaffold template (#29676) 2024-04-10 09:20:21 +00:00
renovate[bot]
b8dca8d22a
Update dependency typescript to v5.4.4 (#29875)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-08 14:08:32 +00:00
Matt Jankowski
285f63c02e
Use composable query in User.active scope (#29775) 2024-04-08 13:53:49 +00:00
Claire
babbf6017d
Remove caching in cache_collection (#29862) 2024-04-08 13:46:13 +00:00
Claire
f3430eebbb
Fix hashtag string interpolation in welcome email (#29879) 2024-04-08 13:45:25 +00:00
github-actions[bot]
13faf26315
New Crowdin Translations (automated) (#29859)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-04-08 13:44:54 +00:00
Renaud Chaput
730e2127e1
Fix webpack warnings due to unhandled extensions (LICENCE and README.md) (#29869) 2024-04-08 08:17:51 +00:00
renovate[bot]
a1277a9b2b
Update eslint (non-major) (#29877)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-08 08:17:23 +00:00
renovate[bot]
2441fe6fd4
Update dependency stylelint-config-standard-scss to v13.1.0 (#29876)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-08 08:16:57 +00:00
renovate[bot]
b06510d579
Update DefinitelyTyped types (non-major) (#29874)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-08 08:16:36 +00:00
renovate[bot]
499b184fcd
Update dependency pino to v8.20.0 (#29865)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-08 08:16:20 +00:00
renovate[bot]
79bbb2023d
Update dependency react-intl to v6.6.5 (#29864)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-08 08:15:46 +00:00
Claire
e73cf356d2
Move OAuth flow tests from feature tests to system tests (#29837) 2024-04-05 16:52:05 +00:00
Matt Jankowski
b61ae28f8d
Separate methods for theme style and meta color tags (#29802) 2024-04-05 09:52:43 +00:00
ache
52ab8a59c6
Forward 3035 port (#29710) 2024-04-05 09:19:43 +00:00
Matt Jankowski
c0fe8a9f13
Extract shared callback behaviour to CustomFilterCache concern (#29695) 2024-04-05 09:17:58 +00:00
renovate[bot]
285a87a77f
Update dependency scenic to v1.8.0 (#29794)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-05 09:04:10 +00:00
Matt Jankowski
59da591d13
Improve spec for dimension/languages admin metric (#29842) 2024-04-05 08:54:11 +00:00
Renaud Chaput
6ac90d4c5d
Add tests for our number formatting function (#29852) 2024-04-05 08:06:31 +00:00
Renaud Chaput
906a399634
Fix wrong extension for a test file (#29853) 2024-04-05 07:57:44 +00:00
renovate[bot]
c7378218ba
Update dependency rubocop-rspec to v2.29.1 (#29858)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-05 07:57:20 +00:00
Claire
38b9d31f63
Improve email address validation (#29838) 2024-04-05 07:48:45 +00:00
Claire
1f11aa5f04
Add stub for trending tags in user mailer spec (#29850) 2024-04-05 07:48:07 +00:00
Matt Jankowski
601834d746
Use partial collection render for welcome mailer features (#29843) 2024-04-04 16:13:10 +00:00
Matt Jankowski
191bf5876e
Add coverage for sanitize failure path in api/web/embeds spec (#29851) 2024-04-04 16:07:16 +00:00
Michael Stanclift
1c87cb8019
Add purple border to active compose field search inputs (#29839) 2024-04-04 11:51:06 +00:00
Matt Jankowski
966d7f5bf9
Add missing snowflake range correction (#29841) 2024-04-04 11:33:17 +00:00
Jeong Arm
4045c069f8
Use public_visibility (#29847) 2024-04-04 07:31:30 +00:00
renovate[bot]
91d3b3fb25
Update dependency sass to v1.74.1 (#29846)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-04 07:25:30 +00:00
renovate[bot]
58dfc12af2
Update babel monorepo to v7.24.4 (#29840)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-04 07:23:53 +00:00
nicolas
c6da3ee828
Makes the star icon rotate around its actual centre axis (#29844) 2024-04-03 21:10:02 +00:00
Matt Jankowski
cde3206478
Simplify feature loop in welcome mailer (#29760) 2024-04-03 20:10:59 +00:00
renovate[bot]
37d984b8bf
Update eslint (non-major) (#29820)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Renaud Chaput <renchap@gmail.com>
2024-04-03 18:05:39 +00:00
Michael Stanclift
e284417349
Fix blue border on emoji/language search in Safari & Chrome (#29832) 2024-04-03 15:19:10 +00:00
Michael Stanclift
5d67247061
Fix language and emoji search field background colors on light theme (#29828) 2024-04-03 14:22:50 +00:00
github-actions[bot]
56d13069cd
New Crowdin Translations (automated) (#29836)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-04-03 09:04:29 +00:00
renovate[bot]
4233ee1f59
Update dependency pg to v8.11.5 (#29833)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-02 21:33:43 +00:00
renovate[bot]
54c7d1ad14
Update dependency pg-connection-string to v2.6.4 (#29814)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-02 21:22:22 +00:00
Matt Jankowski
a7b637768e
Regenerate rubocop todo with version 1.62.1 (#29830) 2024-04-02 19:56:54 +00:00
renovate[bot]
88c3664889
Update dependency rubocop-performance to v1.21.0 (#29804)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-02 17:00:07 +00:00
Matt Jankowski
d27eb181f6
Reduce LineLength from 320 to 300 (#29636) 2024-04-02 15:50:57 +00:00
renovate[bot]
f8b03c3925
Update dependency faker to v3.3.1 (#29829)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-02 15:48:27 +00:00
Matt Jankowski
edde54e991
Update stoplight to version 4.1.0 (#28366) 2024-04-02 15:47:40 +00:00
Matt Jankowski
921c4c1273
Match comment style of FeedManager list/tags checks (#29639)
Co-authored-by: Renaud Chaput <renchap@gmail.com>
2024-04-02 14:07:31 +00:00
Claire
0b9d4103cb
Fix contrast in notification request badge (#29826) 2024-04-02 14:05:46 +00:00
Matt Jankowski
f87959ab50
Fix RSpec/LetSetup cop in api/v1/timelines/public spec (#28972) 2024-04-02 14:05:02 +00:00
Claire
54119570e6
Remove dependency on posix-spawn (#18559) 2024-04-02 14:02:07 +00:00
Matt Jankowski
34489591ec
Add max_pinned_statuses to instances serializer and api response (#29441) 2024-04-02 13:54:11 +00:00
Matt Jankowski
f56309f5f0
Add by_latest_used scope, move admin area recent IPs to partial (#29497) 2024-04-02 13:51:34 +00:00
renovate[bot]
c70c39cad0
Update docker/dockerfile Docker tag to v1.7 (#27993)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-02 13:47:15 +00:00
renovate[bot]
b0692d994f
Update dependency letter_opener to v1.10.0 (#29189)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-02 13:31:03 +00:00
renovate[bot]
695dded7ed
Update dependency aws-sdk-s3 to v1.146.1 (#28961)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-02 13:29:46 +00:00
renovate[bot]
f6e24bbd79
Update dependency postcss-preset-env to v9.5.4 (#29825)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-02 12:13:43 +00:00
Renaud Chaput
b4d991adaa
Use integers and not numbers in notification policy API counters (#29810) 2024-04-02 10:06:26 +00:00
renovate[bot]
d05f62391d
Update dependency public_suffix to v5.0.5 (#29824)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-02 10:04:32 +00:00
Renaud Chaput
e47a3d00fe
Add API types for status and related objects (#29792) 2024-04-02 10:03:33 +00:00
Renaud Chaput
07635228e2
Fix Redux Middleware types (#29800) 2024-04-02 09:56:03 +00:00
Matt Jankowski
a3fe82e359
Rename cop RSpec/Rails/HttpStatus to RSpecRails/HttpStatus (#29806) 2024-04-02 09:34:44 +00:00
github-actions[bot]
c717747603
New Crowdin Translations (automated) (#29812)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-04-02 09:26:06 +00:00
Michael Stanclift
fa9574086d
Fix search box color on light theme (#29808) 2024-04-02 09:15:31 +00:00
renovate[bot]
143d9553fa
Update dependency fastimage to v2.3.1 (#29822)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-02 09:15:24 +00:00
renovate[bot]
a4158be4d7
Update devDependencies (non-major) (#29819)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-02 08:59:52 +00:00
renovate[bot]
2f7a2d4df7
Update DefinitelyTyped types (non-major) (#29818)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-02 08:59:26 +00:00
renovate[bot]
b58666e12e
Update dependency @reduxjs/toolkit to v2.2.3 (#29817)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-02 08:59:05 +00:00
renovate[bot]
9611023380
Update dependency postcss-preset-env to v9.5.3 (#29816)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-02 08:58:00 +00:00
renovate[bot]
173adb04e2
Update dependency pg to v8.11.4 (#29813)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-02 08:57:14 +00:00
renovate[bot]
589e34d00c
Update dependency selenium-webdriver to v4.19.0 (#29776)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Claire <claire.github-309c@sitedethib.com>
2024-04-02 08:53:44 +00:00
Michael Stanclift
90eb4a5d01
Fix light theme header on mobile (#29809) 2024-03-29 21:03:30 +00:00
Michael Stanclift
430da03160
Fix background tint in single column light theme (#29803) 2024-03-29 17:16:51 +00:00
Renaud Chaput
69e5771881
Handle createAppAsyncThunk rejected actions in the errors middleware (#29791) 2024-03-29 13:57:39 +00:00
github-actions[bot]
f96648d41c
New Crowdin Translations (automated) (#29796)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-03-29 13:35:50 +00:00
Renaud Chaput
672c9f5f05
Change the theme-color value automatically when using a built-in theme (#29795) 2024-03-29 13:32:07 +00:00
renovate[bot]
671167f6da
Update dependency glob to v10.3.12 (#29790)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-29 13:31:13 +00:00
renovate[bot]
cd9d11dda6
Update dependency debug to v1.9.2 (#29799)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-29 13:30:52 +00:00
Renaud Chaput
67442f9039
Remove global boosts state and convert boosts modal to Typescript (#29774) 2024-03-28 15:33:15 +00:00
github-actions[bot]
8a498f4e65
New Crowdin Translations (automated) (#29785)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-03-28 14:48:09 +00:00
Claire
4f068d4fcc
Fix logo pushing header buttons out of view on certain conditions in mobile layout (#29787) 2024-03-28 14:00:57 +00:00
Matt Jankowski
e85f24174e
Simplify checklist step loop in welcome mailer (#29761) 2024-03-28 10:56:33 +00:00
renovate[bot]
d44e7a8578
Update dependency node to 20.12 (#29765)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-28 10:54:16 +00:00
Renaud Chaput
961bb84e4c
Fix <RelativeTimestamp> types (#29781) 2024-03-28 10:07:01 +00:00
Renaud Chaput
d088964761
Fix props for <Button> (#29780) 2024-03-28 10:06:25 +00:00
Renaud Chaput
f2fd1da23f
Fix PropTypes for some record objects (#29786) 2024-03-28 10:05:16 +00:00
github-actions[bot]
1025fff6b9
New Crowdin Translations (automated) (#29772)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-03-27 21:19:03 +00:00
Claire
c913e2f3e5
Fix language picker and privacy picker not having a backdrop filter (#29779) 2024-03-27 16:32:00 +00:00
Renaud Chaput
b9982ce578
Fix notifications marker fetch (#29777) 2024-03-27 15:49:02 +00:00
Renaud Chaput
9fbe8d3a0c
Rewrite PIP state in Typescript (#27645)
Co-authored-by: Claire <claire.github-309c@sitedethib.com>
2024-03-27 15:19:33 +00:00
Matt Jankowski
b016f03637
Pull out constant from AccountWarning.recent scope (#29767) 2024-03-27 14:08:04 +00:00
Renaud Chaput
27d014a7fa
Rewrite markers reducer in Typescript (#27644) 2024-03-27 12:47:09 +00:00
renovate[bot]
d49343ed11
Update dependency react-intl to v6.6.4 (#29771)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-27 09:59:54 +00:00
renovate[bot]
86f999c1f2
Update dependency json-schema to v4.3.0 (#29769)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-27 09:59:50 +00:00
Matt Jankowski
1d0a43f6a3
Use composable query in Status.not_domain_blocked_by_account scope (#29766) 2024-03-27 09:59:45 +00:00
renovate[bot]
c5692d2f2f
Update dependency prom-client to v15.1.1 (#29764)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-27 09:59:42 +00:00
Claire
b2d841ce9a
Fix column borders disappearing in advanced interface on low width viewports (#29763) 2024-03-26 23:14:11 +00:00
Matt Jankowski
c4feba4347
Use existing MascotHelper#instance_presenter instead of local var in welcome email template (#29759) 2024-03-26 15:58:48 +00:00
Claire
de740dfb9c
Use upsert_all and insert_all to reduce back-and-forth in costly migrations (#29752) 2024-03-26 15:57:08 +00:00
Claire
9c24f2d6b1
Undo notification permissions on individual and domain blocks (#29570) 2024-03-26 14:46:38 +00:00
Claire
7508472d84
Fix admin interface repeating rule title instead of showing hint text (#29758) 2024-03-26 14:46:05 +00:00
Claire
cfea9cc172
Add list of pending releases directly in mail notifications for version updates (#29436) 2024-03-26 14:45:19 +00:00
Matt Jankowski
32938dadd7
Add not_allowed scope for PreviewCardTrend (#29599) 2024-03-26 13:21:20 +00:00
Matt Jankowski
cf76380c91
Add AccountStat.by_recent_status, use in Account (#29704) 2024-03-26 13:12:09 +00:00
renovate[bot]
b34c089591
Update dependency csv to v3.3.0 (#29715)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-26 13:09:35 +00:00
github-actions[bot]
b3d970bdb8
New Crowdin Translations (automated) (#29756)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-03-26 09:49:19 +00:00
Matt Jankowski
c3e3c60069
Remove extraneous Lint/UselessAccessModifier config (#29749) 2024-03-26 09:33:07 +00:00
Matt Jankowski
5e6a600b64
Bundler version update and misc gem version bumps (#29717) 2024-03-26 09:31:24 +00:00
Emelia Smith
eb926b7e60
Ensure case-insensitive fields are converted to lowercase in user imports (#29740) 2024-03-26 09:30:10 +00:00
Emelia Smith
a3e8b78250
Ensure case-insensitive fields are converted to lowercase in Admin Imports (#29739) 2024-03-26 09:30:07 +00:00
renovate[bot]
06fc2b3fde
Update dependency faker to v3.3.0 (#29755)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-26 09:29:38 +00:00
renovate[bot]
572a8ef7f9
Update dependency rubocop-rails to v2.24.1 (#29745)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-26 09:27:41 +00:00
renovate[bot]
3002a1e89b
Update dependency express to v4.19.2 (#29750)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-26 09:27:23 +00:00
renovate[bot]
36bc57de95
Update dependency cssnano to v6.1.2 (#29754)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-26 09:27:05 +00:00
Renaud Chaput
02ea161506
Support "system" theme setting (light/dark theme depending on user system preference) (#29748)
Co-authored-by: Nishiki Liu <hello@nshki.com>
2024-03-26 09:25:49 +00:00
793 changed files with 13219 additions and 6163 deletions

View file

@ -70,7 +70,7 @@ services:
hard: -1 hard: -1
libretranslate: libretranslate:
image: libretranslate/libretranslate:v1.5.6 image: libretranslate/libretranslate:v1.5.7
restart: unless-stopped restart: unless-stopped
volumes: volumes:
- lt-data:/home/libretranslate/.local - lt-data:/home/libretranslate/.local

4
.env.development Normal file
View file

@ -0,0 +1,4 @@
# Required by ActiveRecord encryption feature
ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY=fkSxKD2bF396kdQbrP1EJ7WbU7ZgNokR
ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT=r0hvVmzBVsjxC7AMlwhOzmtc36ZCOS1E
ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY=PhdFyyfy5xJ7WVd2lWBpcPScRQHzRTNr

View file

@ -3,3 +3,8 @@ NODE_ENV=production
# Federation # Federation
LOCAL_DOMAIN=cb6e6126.ngrok.io LOCAL_DOMAIN=cb6e6126.ngrok.io
LOCAL_HTTPS=true LOCAL_HTTPS=true
# Required by ActiveRecord encryption feature
ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY=fkSxKD2bF396kdQbrP1EJ7WbU7ZgNokR
ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT=r0hvVmzBVsjxC7AMlwhOzmtc36ZCOS1E
ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY=PhdFyyfy5xJ7WVd2lWBpcPScRQHzRTNr

View file

@ -380,6 +380,7 @@ module.exports = defineConfig({
"message": "Use typed hooks `useAppDispatch` and `useAppSelector` instead." "message": "Use typed hooks `useAppDispatch` and `useAppSelector` instead."
} }
], ],
"@typescript-eslint/restrict-template-expressions": ['warn', { allowNumber: true }],
'jsdoc/require-jsdoc': 'off', 'jsdoc/require-jsdoc': 'off',
// Those rules set stricter rules for TS files // Those rules set stricter rules for TS files

View file

@ -141,6 +141,13 @@
matchUpdateTypes: ['patch', 'minor'], matchUpdateTypes: ['patch', 'minor'],
groupName: 'RSpec (non-major)', groupName: 'RSpec (non-major)',
}, },
{
// Group all opentelemetry-ruby packages in the same PR
matchManagers: ['bundler'],
matchPackagePrefixes: ['opentelemetry-'],
matchUpdateTypes: ['patch', 'minor'],
groupName: 'opentelemetry-ruby (non-major)',
},
// Add labels depending on package manager // Add labels depending on package manager
{ matchManagers: ['npm', 'nvm'], addLabels: ['javascript'] }, { matchManagers: ['npm', 'nvm'], addLabels: ['javascript'] },
{ matchManagers: ['bundler', 'ruby-version'], addLabels: ['ruby'] }, { matchManagers: ['bundler', 'ruby-version'], addLabels: ['ruby'] },

View file

@ -1,21 +0,0 @@
{
"problemMatcher": [
{
"owner": "stylelint",
"pattern": [
{
"regexp": "^([^\\s].*)$",
"file": 1
},
{
"regexp": "^\\s+((\\d+):(\\d+))?\\s+(✖|×)\\s+(.*)\\s{2,}(.*)$",
"line": 2,
"column": 3,
"message": 5,
"code": 6,
"loop": true
}
]
}
]
}

View file

@ -53,7 +53,7 @@ jobs:
# Create or update the pull request # Create or update the pull request
- name: Create Pull Request - name: Create Pull Request
uses: peter-evans/create-pull-request@v6.0.2 uses: peter-evans/create-pull-request@v6.0.5
with: with:
commit-message: 'New Crowdin translations' commit-message: 'New Crowdin translations'
title: 'New Crowdin Translations (automated)' title: 'New Crowdin Translations (automated)'

View file

@ -38,9 +38,5 @@ jobs:
- name: Set up Javascript environment - name: Set up Javascript environment
uses: ./.github/actions/setup-javascript uses: ./.github/actions/setup-javascript
- uses: xt0rted/stylelint-problem-matcher@v1
- run: echo "::add-matcher::.github/stylelint-matcher.json"
- name: Stylelint - name: Stylelint
run: yarn lint:css run: yarn lint:css -f github

View file

@ -38,5 +38,5 @@ jobs:
- name: Set up Javascript environment - name: Set up Javascript environment
uses: ./.github/actions/setup-javascript uses: ./.github/actions/setup-javascript
- name: Jest testing - name: JavaScript testing
run: yarn jest --reporters github-actions summary run: yarn jest --reporters github-actions summary

View file

@ -28,6 +28,9 @@ jobs:
env: env:
RAILS_ENV: ${{ matrix.mode }} RAILS_ENV: ${{ matrix.mode }}
BUNDLE_WITH: ${{ matrix.mode }} BUNDLE_WITH: ${{ matrix.mode }}
ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY: precompile_placeholder
ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT: precompile_placeholder
ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY: precompile_placeholder
OTP_SECRET: precompile_placeholder OTP_SECRET: precompile_placeholder
SECRET_KEY_BASE: precompile_placeholder SECRET_KEY_BASE: precompile_placeholder
@ -111,10 +114,9 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
ruby-version: ruby-version:
- '3.0'
- '3.1' - '3.1'
- '3.2'
- '.ruby-version' - '.ruby-version'
- '3.3'
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@ -143,6 +145,8 @@ jobs:
uses: codecov/codecov-action@v4 uses: codecov/codecov-action@v4
with: with:
files: coverage/lcov/mastodon.lcov files: coverage/lcov/mastodon.lcov
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
test-e2e: test-e2e:
name: End to End testing name: End to End testing
@ -182,15 +186,16 @@ jobs:
DISABLE_SIMPLECOV: true DISABLE_SIMPLECOV: true
RAILS_ENV: test RAILS_ENV: test
BUNDLE_WITH: test BUNDLE_WITH: test
LOCAL_DOMAIN: localhost:3000
LOCAL_HTTPS: false
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
ruby-version: ruby-version:
- '3.0'
- '3.1' - '3.1'
- '3.2'
- '.ruby-version' - '.ruby-version'
- '3.3'
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@ -212,7 +217,7 @@ jobs:
- name: Load database schema - name: Load database schema
run: './bin/rails db:create db:schema:load db:seed' run: './bin/rails db:create db:schema:load db:seed'
- run: bundle exec rake spec:system - run: bin/rspec spec/system --tag streaming --tag js
- name: Archive logs - name: Archive logs
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
@ -287,10 +292,9 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
ruby-version: ruby-version:
- '3.0'
- '3.1' - '3.1'
- '3.2'
- '.ruby-version' - '.ruby-version'
- '3.3'
search-image: search-image:
- docker.elastic.co/elasticsearch/elasticsearch:7.17.13 - docker.elastic.co/elasticsearch/elasticsearch:7.17.13
include: include:

4
.gitignore vendored
View file

@ -24,7 +24,6 @@
/public/packs-test /public/packs-test
.env .env
.env.production .env.production
.env.development
/node_modules/ /node_modules/
/build/ /build/
@ -69,3 +68,6 @@ yarn-debug.log
# Ignore Docker option files # Ignore Docker option files
docker-compose.override.yml docker-compose.override.yml
# Ignore dotenv .local files
.env*.local

View file

@ -1,6 +1,5 @@
exclude: exclude:
- 'vendor/**/*' - 'vendor/**/*'
- lib/templates/haml/scaffold/_form.html.haml
require: require:
- ./lib/linter/haml_middle_dot.rb - ./lib/linter/haml_middle_dot.rb
@ -11,6 +10,6 @@ linters:
MiddleDot: MiddleDot:
enabled: true enabled: true
LineLength: LineLength:
max: 320 max: 300
ViewLength: ViewLength:
max: 200 # Override default value of 100 inherited from rubocop max: 200 # Override default value of 100 inherited from rubocop

2
.nvmrc
View file

@ -1 +1 @@
20.11 20.13

View file

@ -9,12 +9,13 @@ inherit_mode:
require: require:
- rubocop-rails - rubocop-rails
- rubocop-rspec - rubocop-rspec
- rubocop-rspec_rails
- rubocop-performance - rubocop-performance
- rubocop-capybara - rubocop-capybara
- ./lib/linter/rubocop_middle_dot - ./lib/linter/rubocop_middle_dot
AllCops: AllCops:
TargetRubyVersion: 3.0 # Set to minimum supported version of CI TargetRubyVersion: 3.1 # Set to minimum supported version of CI
DisplayCopNames: true DisplayCopNames: true
DisplayStyleGuide: true DisplayStyleGuide: true
ExtraDetails: true ExtraDetails: true
@ -39,13 +40,7 @@ Layout/FirstHashElementIndentation:
# Reason: Currently disabled in .rubocop_todo.yml # Reason: Currently disabled in .rubocop_todo.yml
# https://docs.rubocop.org/rubocop/cops_layout.html#layoutlinelength # https://docs.rubocop.org/rubocop/cops_layout.html#layoutlinelength
Layout/LineLength: Layout/LineLength:
Max: 320 # Default of 120 causes a duplicate entry in generated todo file Max: 300 # Default of 120 causes a duplicate entry in generated todo file
# Reason:
# https://docs.rubocop.org/rubocop/cops_lint.html#lintuselessaccessmodifier
Lint/UselessAccessModifier:
ContextCreatingMethods:
- class_methods
## Disable most Metrics/*Length cops ## Disable most Metrics/*Length cops
# Reason: those are often triggered and force significant refactors when this happend # Reason: those are often triggered and force significant refactors when this happend
@ -86,6 +81,11 @@ Metrics/CyclomaticComplexity:
Metrics/ParameterLists: Metrics/ParameterLists:
CountKeywordArgs: false CountKeywordArgs: false
# Reason: Prefer seeing a variable name
# https://docs.rubocop.org/rubocop/cops_naming.html#namingblockforwarding
Naming/BlockForwarding:
EnforcedStyle: explicit
# Reason: Prevailing style is argument file paths # Reason: Prevailing style is argument file paths
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsfilepath # https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsfilepath
Rails/FilePath: Rails/FilePath:
@ -148,11 +148,6 @@ RSpec/NamedSubject:
RSpec/NotToNot: RSpec/NotToNot:
EnforcedStyle: to_not EnforcedStyle: to_not
# Reason: Prevailing style uses numeric status codes, matches Rails/HttpStatus
# https://docs.rubocop.org/rubocop-rspec/cops_rspec_rails.html#rspecrailshttpstatus
RSpec/Rails/HttpStatus:
EnforcedStyle: numeric
# Reason: Match overrides from Rspec/FilePath rule above # Reason: Match overrides from Rspec/FilePath rule above
# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecspecfilepathformat # https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecspecfilepathformat
RSpec/SpecFilePathFormat: RSpec/SpecFilePathFormat:
@ -163,6 +158,11 @@ RSpec/SpecFilePathFormat:
OEmbedController: oembed_controller OEmbedController: oembed_controller
OStatus: ostatus OStatus: ostatus
# Reason: Prevailing style uses numeric status codes, matches Rails/HttpStatus
# https://docs.rubocop.org/rubocop-rspec/cops_rspec_rails.html#rspecrailshttpstatus
RSpecRails/HttpStatus:
EnforcedStyle: numeric
# Reason: # Reason:
# https://docs.rubocop.org/rubocop/cops_style.html#styleclassandmodulechildren # https://docs.rubocop.org/rubocop/cops_style.html#styleclassandmodulechildren
Style/ClassAndModuleChildren: Style/ClassAndModuleChildren:
@ -182,10 +182,16 @@ Style/FormatStringToken:
AllowedMethods: AllowedMethods:
- redirect_with_vary - redirect_with_vary
# Reason: Prevailing style choice
# https://docs.rubocop.org/rubocop/cops_style.html#stylehashaslastarrayitem
Style/HashAsLastArrayItem:
Enabled: false
# Reason: Enforce modern Ruby style # Reason: Enforce modern Ruby style
# https://docs.rubocop.org/rubocop/cops_style.html#stylehashsyntax # https://docs.rubocop.org/rubocop/cops_style.html#stylehashsyntax
Style/HashSyntax: Style/HashSyntax:
EnforcedStyle: ruby19_no_mixed_keys EnforcedStyle: ruby19_no_mixed_keys
EnforcedShorthandSyntax: either
# Reason: # Reason:
# https://docs.rubocop.org/rubocop/cops_style.html#stylenumericliterals # https://docs.rubocop.org/rubocop/cops_style.html#stylenumericliterals

View file

@ -1,18 +1,11 @@
# This configuration was generated by # This configuration was generated by
# `rubocop --auto-gen-config --auto-gen-only-exclude --no-exclude-limit --no-offense-counts --no-auto-gen-timestamp` # `rubocop --auto-gen-config --auto-gen-only-exclude --no-exclude-limit --no-offense-counts --no-auto-gen-timestamp`
# using RuboCop version 1.60.2. # using RuboCop version 1.62.1.
# The point is for the user to remove these configuration records # The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base. # one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new # Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again. # versions of RuboCop, may require this file to be generated again.
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: TreatCommentsAsGroupSeparators, ConsiderPunctuation, Include.
# Include: **/*.gemfile, **/Gemfile, **/gems.rb
Bundler/OrderedGems:
Exclude:
- 'Gemfile'
Lint/NonLocalExitFromIterator: Lint/NonLocalExitFromIterator:
Exclude: Exclude:
- 'app/helpers/jsonld_helper.rb' - 'app/helpers/jsonld_helper.rb'
@ -36,7 +29,7 @@ Metrics/PerceivedComplexity:
# Configuration parameters: CountAsOne. # Configuration parameters: CountAsOne.
RSpec/ExampleLength: RSpec/ExampleLength:
Max: 20 # Override default of 5 Max: 18
RSpec/MultipleExpectations: RSpec/MultipleExpectations:
Max: 7 Max: 7
@ -49,27 +42,10 @@ RSpec/MultipleMemoizedHelpers:
RSpec/NestedGroups: RSpec/NestedGroups:
Max: 6 Max: 6
# Configuration parameters: Include.
# Include: app/models/**/*.rb
Rails/HasAndBelongsToMany:
Exclude:
- 'app/models/concerns/account/associations.rb'
- 'app/models/status.rb'
- 'app/models/tag.rb'
Rails/OutputSafety: Rails/OutputSafety:
Exclude: Exclude:
- 'config/initializers/simple_form.rb' - 'config/initializers/simple_form.rb'
# Configuration parameters: Include.
# Include: app/models/**/*.rb
Rails/UniqueValidationWithoutIndex:
Exclude:
- 'app/models/account_alias.rb'
- 'app/models/custom_filter_status.rb'
- 'app/models/identity.rb'
- 'app/models/webauthn_credential.rb'
# This cop supports unsafe autocorrection (--autocorrect-all). # This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: AllowedMethods, AllowedPatterns. # Configuration parameters: AllowedMethods, AllowedPatterns.
# AllowedMethods: ==, equal?, eql? # AllowedMethods: ==, equal?, eql?
@ -78,17 +54,12 @@ Style/ClassEqualityComparison:
- 'app/helpers/jsonld_helper.rb' - 'app/helpers/jsonld_helper.rb'
- 'app/serializers/activitypub/outbox_serializer.rb' - 'app/serializers/activitypub/outbox_serializer.rb'
Style/ClassVars:
Exclude:
- 'config/initializers/devise.rb'
# This cop supports safe autocorrection (--autocorrect). # This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: AllowedVars. # Configuration parameters: AllowedVars.
Style/FetchEnvVar: Style/FetchEnvVar:
Exclude: Exclude:
- 'app/lib/redis_configuration.rb' - 'app/lib/redis_configuration.rb'
- 'app/lib/translation_service.rb' - 'app/lib/translation_service.rb'
- 'config/environments/development.rb'
- 'config/environments/production.rb' - 'config/environments/production.rb'
- 'config/initializers/2_limited_federation_mode.rb' - 'config/initializers/2_limited_federation_mode.rb'
- 'config/initializers/3_omniauth.rb' - 'config/initializers/3_omniauth.rb'
@ -98,9 +69,8 @@ Style/FetchEnvVar:
- 'config/initializers/paperclip.rb' - 'config/initializers/paperclip.rb'
- 'config/initializers/vapid.rb' - 'config/initializers/vapid.rb'
- 'lib/mastodon/redis_config.rb' - 'lib/mastodon/redis_config.rb'
- 'lib/premailer_webpack_strategy.rb'
- 'lib/tasks/repo.rake' - 'lib/tasks/repo.rake'
- 'spec/features/profile_spec.rb' - 'spec/system/profile_spec.rb'
# This cop supports safe autocorrection (--autocorrect). # This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle, MaxUnannotatedPlaceholdersAllowed, AllowedMethods, AllowedPatterns. # Configuration parameters: EnforcedStyle, MaxUnannotatedPlaceholdersAllowed, AllowedMethods, AllowedPatterns.
@ -144,22 +114,8 @@ Style/GuardClause:
- 'lib/mastodon/cli/accounts.rb' - 'lib/mastodon/cli/accounts.rb'
- 'lib/mastodon/cli/maintenance.rb' - 'lib/mastodon/cli/maintenance.rb'
- 'lib/mastodon/cli/media.rb' - 'lib/mastodon/cli/media.rb'
- 'lib/paperclip/attachment_extensions.rb'
- 'lib/tasks/repo.rake' - 'lib/tasks/repo.rake'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle.
# SupportedStyles: braces, no_braces
Style/HashAsLastArrayItem:
Exclude:
- 'app/controllers/admin/statuses_controller.rb'
- 'app/controllers/api/v1/statuses_controller.rb'
- 'app/models/concerns/account/counters.rb'
- 'app/models/concerns/status/threading_concern.rb'
- 'app/models/status.rb'
- 'app/services/batched_remove_status_service.rb'
- 'app/services/notify_service.rb'
# This cop supports unsafe autocorrection (--autocorrect-all). # This cop supports unsafe autocorrection (--autocorrect-all).
Style/HashTransformValues: Style/HashTransformValues:
Exclude: Exclude:
@ -207,13 +163,6 @@ Style/OptionalBooleanParameter:
- 'app/workers/unfollow_follow_worker.rb' - 'app/workers/unfollow_follow_worker.rb'
- 'lib/mastodon/redis_config.rb' - 'lib/mastodon/redis_config.rb'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: PreferredDelimiters.
Style/PercentLiteralDelimiters:
Exclude:
- 'config/deploy.rb'
- 'config/initializers/doorkeeper.rb'
# This cop supports unsafe autocorrection (--autocorrect-all). # This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: EnforcedStyle. # Configuration parameters: EnforcedStyle.
# SupportedStyles: short, verbose # SupportedStyles: short, verbose
@ -244,52 +193,12 @@ Style/SafeNavigation:
Exclude: Exclude:
- 'app/models/concerns/account/finder_concern.rb' - 'app/models/concerns/account/finder_concern.rb'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle.
# SupportedStyles: only_raise, only_fail, semantic
Style/SignalException:
Exclude:
- 'lib/devise/strategies/two_factor_ldap_authenticatable.rb'
- 'lib/devise/strategies/two_factor_pam_authenticatable.rb'
# This cop supports unsafe autocorrection (--autocorrect-all).
Style/SingleArgumentDig:
Exclude:
- 'lib/webpacker/manifest_extensions.rb'
# This cop supports unsafe autocorrection (--autocorrect-all). # This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: Mode. # Configuration parameters: Mode.
Style/StringConcatenation: Style/StringConcatenation:
Exclude: Exclude:
- 'config/initializers/paperclip.rb' - 'config/initializers/paperclip.rb'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline.
# SupportedStyles: single_quotes, double_quotes
Style/StringLiterals:
Exclude:
- 'config/environments/production.rb'
- 'config/initializers/backtrace_silencers.rb'
- 'config/initializers/http_client_proxy.rb'
- 'config/initializers/rack_attack.rb'
- 'config/initializers/webauthn.rb'
- 'config/routes.rb'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyleForMultiline.
# SupportedStylesForMultiline: comma, consistent_comma, no_comma
Style/TrailingCommaInArguments:
Exclude:
- 'config/initializers/paperclip.rb'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyleForMultiline.
# SupportedStylesForMultiline: comma, consistent_comma, no_comma
Style/TrailingCommaInHashLiteral:
Exclude:
- 'config/environments/production.rb'
- 'config/environments/test.rb'
# This cop supports safe autocorrection (--autocorrect). # This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: WordRegex. # Configuration parameters: WordRegex.
# SupportedStyles: percent, brackets # SupportedStyles: percent, brackets

View file

@ -1 +1 @@
3.2.3 3.3.1

View file

@ -1,4 +1,4 @@
# syntax=docker/dockerfile:1.4 # syntax=docker/dockerfile:1.7
# Please see https://docs.docker.com/engine/reference/builder for information about # Please see https://docs.docker.com/engine/reference/builder for information about
# the extended buildx capabilities used in this file. # the extended buildx capabilities used in this file.
@ -7,15 +7,15 @@
ARG TARGETPLATFORM=${TARGETPLATFORM} ARG TARGETPLATFORM=${TARGETPLATFORM}
ARG BUILDPLATFORM=${BUILDPLATFORM} ARG BUILDPLATFORM=${BUILDPLATFORM}
# Ruby image to use for base image, change with [--build-arg RUBY_VERSION="3.2.3"] # Ruby image to use for base image, change with [--build-arg RUBY_VERSION="3.3.1"]
ARG RUBY_VERSION="3.2.3" ARG RUBY_VERSION="3.3.1"
# # Node version to use in base image, change with [--build-arg NODE_MAJOR_VERSION="20"] # # Node version to use in base image, change with [--build-arg NODE_MAJOR_VERSION="20"]
ARG NODE_MAJOR_VERSION="20" ARG NODE_MAJOR_VERSION="20"
# Debian image to use for base image, change with [--build-arg DEBIAN_VERSION="bookworm"] # Debian image to use for base image, change with [--build-arg DEBIAN_VERSION="bookworm"]
ARG DEBIAN_VERSION="bookworm" ARG DEBIAN_VERSION="bookworm"
# Node image to use for base image based on combined variables (ex: 20-bookworm-slim) # Node image to use for base image based on combined variables (ex: 20-bookworm-slim)
FROM docker.io/node:${NODE_MAJOR_VERSION}-${DEBIAN_VERSION}-slim as node FROM docker.io/node:${NODE_MAJOR_VERSION}-${DEBIAN_VERSION}-slim as node
# Ruby image to use for base image based on combined variables (ex: 3.2.3-slim-bookworm) # Ruby image to use for base image based on combined variables (ex: 3.3.1-slim-bookworm)
FROM docker.io/ruby:${RUBY_VERSION}-slim-${DEBIAN_VERSION} as ruby FROM docker.io/ruby:${RUBY_VERSION}-slim-${DEBIAN_VERSION} as ruby
# Resulting version string is vX.X.X-MASTODON_VERSION_PRERELEASE+MASTODON_VERSION_METADATA # Resulting version string is vX.X.X-MASTODON_VERSION_PRERELEASE+MASTODON_VERSION_METADATA
@ -29,7 +29,7 @@ ARG MASTODON_VERSION_METADATA=""
# See: https://docs.joinmastodon.org/admin/config/#rails_serve_static_files # See: https://docs.joinmastodon.org/admin/config/#rails_serve_static_files
ARG RAILS_SERVE_STATIC_FILES="true" ARG RAILS_SERVE_STATIC_FILES="true"
# Allow to use YJIT compiler # Allow to use YJIT compiler
# See: https://github.com/ruby/ruby/blob/v3_2_3/doc/yjit/yjit.md # See: https://github.com/ruby/ruby/blob/v3_2_4/doc/yjit/yjit.md
ARG RUBY_YJIT_ENABLE="1" ARG RUBY_YJIT_ENABLE="1"
# Timezone used by the Docker container and runtime, change with [--build-arg TZ=Europe/Berlin] # Timezone used by the Docker container and runtime, change with [--build-arg TZ=Europe/Berlin]
ARG TZ="Etc/UTC" ARG TZ="Etc/UTC"
@ -205,7 +205,12 @@ ARG TARGETPLATFORM
RUN \ RUN \
# Use Ruby on Rails to create Mastodon assets # Use Ruby on Rails to create Mastodon assets
OTP_SECRET=precompile_placeholder SECRET_KEY_BASE=precompile_placeholder bundle exec rails assets:precompile; \ ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY=precompile_placeholder \
ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT=precompile_placeholder \
ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY=precompile_placeholder \
OTP_SECRET=precompile_placeholder \
SECRET_KEY_BASE=precompile_placeholder \
bundle exec rails assets:precompile; \
# Cleanup temporary files # Cleanup temporary files
rm -fr /opt/mastodon/tmp; rm -fr /opt/mastodon/tmp;
@ -257,4 +262,4 @@ USER mastodon
# Expose default Puma ports # Expose default Puma ports
EXPOSE 3000 EXPOSE 3000
# Set container tini as default entry point # Set container tini as default entry point
ENTRYPOINT ["/usr/bin/tini", "--"] ENTRYPOINT ["/usr/bin/tini", "--"]

62
Gemfile
View file

@ -1,28 +1,28 @@
# frozen_string_literal: true # frozen_string_literal: true
source 'https://rubygems.org' source 'https://rubygems.org'
ruby '>= 3.0.0' ruby '>= 3.1.0'
gem 'puma', '~> 6.3'
gem 'rails', '~> 7.1.1'
gem 'propshaft' gem 'propshaft'
gem 'thor', '~> 1.2' gem 'puma', '~> 6.3'
gem 'rack', '~> 2.2.7' gem 'rack', '~> 2.2.7'
gem 'rails', '~> 7.1.1'
gem 'thor', '~> 1.2'
# For why irb is in the Gemfile, see: https://ruby.social/@st0012/111444685161478182 # For why irb is in the Gemfile, see: https://ruby.social/@st0012/111444685161478182
gem 'irb', '~> 1.8' gem 'irb', '~> 1.8'
gem 'dotenv'
gem 'haml-rails', '~>2.0' gem 'haml-rails', '~>2.0'
gem 'pg', '~> 1.5' gem 'pg', '~> 1.5'
gem 'pghero' gem 'pghero'
gem 'dotenv-rails', '~> 2.8'
gem 'aws-sdk-s3', '~> 1.123', require: false gem 'aws-sdk-s3', '~> 1.123', require: false
gem 'blurhash', '~> 0.1'
gem 'fog-core', '<= 2.4.0' gem 'fog-core', '<= 2.4.0'
gem 'fog-openstack', '~> 1.0', require: false gem 'fog-openstack', '~> 1.0', require: false
gem 'kt-paperclip', '~> 7.2' gem 'kt-paperclip', '~> 7.2'
gem 'md-paperclip-azure', '~> 2.2', require: false gem 'md-paperclip-azure', '~> 2.2', require: false
gem 'blurhash', '~> 0.1'
gem 'active_model_serializers', '~> 0.10' gem 'active_model_serializers', '~> 0.10'
gem 'addressable', '~> 2.8' gem 'addressable', '~> 2.8'
@ -31,7 +31,7 @@ gem 'browser'
gem 'charlock_holmes', '~> 0.7.7' gem 'charlock_holmes', '~> 0.7.7'
gem 'chewy', '~> 7.3' gem 'chewy', '~> 7.3'
gem 'devise', '~> 4.9' gem 'devise', '~> 4.9'
gem 'devise-two-factor', '~> 4.1' gem 'devise-two-factor'
group :pam_authentication, optional: true do group :pam_authentication, optional: true do
gem 'devise_pam_authenticatable2', '~> 9.2' gem 'devise_pam_authenticatable2', '~> 9.2'
@ -39,11 +39,11 @@ end
gem 'net-ldap', '~> 0.18' gem 'net-ldap', '~> 0.18'
gem 'omniauth-cas', '~> 3.0.0.beta.1'
gem 'omniauth-saml', '~> 2.0'
gem 'omniauth_openid_connect', '~> 0.6.1'
gem 'omniauth', '~> 2.0' gem 'omniauth', '~> 2.0'
gem 'omniauth-cas', '~> 3.0.0.beta.1'
gem 'omniauth_openid_connect', '~> 0.6.1'
gem 'omniauth-rails_csrf_protection', '~> 1.0' gem 'omniauth-rails_csrf_protection', '~> 1.0'
gem 'omniauth-saml', '~> 2.0'
gem 'color_diff', '~> 0.1' gem 'color_diff', '~> 0.1'
gem 'csv', '~> 3.2' gem 'csv', '~> 3.2'
@ -53,50 +53,49 @@ gem 'ed25519', '~> 1.3'
gem 'fast_blank', '~> 1.0' gem 'fast_blank', '~> 1.0'
gem 'fastimage' gem 'fastimage'
gem 'hiredis', '~> 0.6' gem 'hiredis', '~> 0.6'
gem 'redis-namespace', '~> 1.10'
gem 'htmlentities', '~> 4.3' gem 'htmlentities', '~> 4.3'
gem 'http', '~> 5.1' gem 'http', '~> 5.2.0'
gem 'http_accept_language', '~> 2.1' gem 'http_accept_language', '~> 2.1'
gem 'httplog', '~> 1.6.2' gem 'httplog', '~> 1.6.2'
gem 'i18n', '1.14.1' # TODO: Remove version when resolved: https://github.com/glebm/i18n-tasks/issues/552 / https://github.com/ruby-i18n/i18n/pull/688 gem 'i18n'
gem 'idn-ruby', require: 'idn' gem 'idn-ruby', require: 'idn'
gem 'inline_svg' gem 'inline_svg'
gem 'kaminari', '~> 1.2' gem 'kaminari', '~> 1.2'
gem 'link_header', '~> 0.0' gem 'link_header', '~> 0.0'
gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock'
gem 'mime-types', '~> 3.5.0', require: 'mime/types/columnar' gem 'mime-types', '~> 3.5.0', require: 'mime/types/columnar'
gem 'nokogiri', '~> 1.15' gem 'nokogiri', '~> 1.15'
gem 'nsa' gem 'nsa'
gem 'oj', '~> 3.14' gem 'oj', '~> 3.14'
gem 'ox', '~> 2.14' gem 'ox', '~> 2.14'
gem 'parslet' gem 'parslet'
gem 'posix-spawn' gem 'premailer-rails'
gem 'public_suffix', '~> 5.0' gem 'public_suffix', '~> 5.0'
gem 'pundit', '~> 2.3' gem 'pundit', '~> 2.3'
gem 'premailer-rails'
gem 'rack-attack', '~> 6.6' gem 'rack-attack', '~> 6.6'
gem 'rack-cors', '~> 2.0', require: 'rack/cors' gem 'rack-cors', '~> 2.0', require: 'rack/cors'
gem 'rails-i18n', '~> 7.0' gem 'rails-i18n', '~> 7.0'
gem 'redcarpet', '~> 3.6' gem 'redcarpet', '~> 3.6'
gem 'redis', '~> 4.5', require: ['redis', 'redis/connection/hiredis'] gem 'redis', '~> 4.5', require: ['redis', 'redis/connection/hiredis']
gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock' gem 'redis-namespace', '~> 1.10'
gem 'rqrcode', '~> 2.2' gem 'rqrcode', '~> 2.2'
gem 'ruby-progressbar', '~> 1.13' gem 'ruby-progressbar', '~> 1.13'
gem 'sanitize', '~> 6.0' gem 'sanitize', '~> 6.0'
gem 'scenic', '~> 1.7' gem 'scenic', '~> 1.7'
gem 'sidekiq', '~> 6.5' gem 'sidekiq', '~> 6.5'
gem 'sidekiq-bulk', '~> 0.2.0'
gem 'sidekiq-scheduler', '~> 5.0' gem 'sidekiq-scheduler', '~> 5.0'
gem 'sidekiq-unique-jobs', '~> 7.1' gem 'sidekiq-unique-jobs', '~> 7.1'
gem 'sidekiq-bulk', '~> 0.2.0'
gem 'simple-navigation', '~> 4.4'
gem 'simple_form', '~> 5.2' gem 'simple_form', '~> 5.2'
gem 'stoplight', '~> 3.0.1' gem 'simple-navigation', '~> 4.4'
gem 'stoplight', '~> 4.1'
gem 'strong_migrations', '1.8.0' gem 'strong_migrations', '1.8.0'
gem 'tty-prompt', '~> 0.23', require: false gem 'tty-prompt', '~> 0.23', require: false
gem 'twitter-text', '~> 3.1.0' gem 'twitter-text', '~> 3.1.0'
gem 'tzinfo-data', '~> 1.2023' gem 'tzinfo-data', '~> 1.2023'
gem 'webauthn', '~> 3.0'
gem 'webpacker', '~> 5.4' gem 'webpacker', '~> 5.4'
gem 'webpush', github: 'ClearlyClaire/webpush', ref: 'f14a4d52e201128b1b00245d11b6de80d6cfdcd9' gem 'webpush', github: 'ClearlyClaire/webpush', ref: 'f14a4d52e201128b1b00245d11b6de80d6cfdcd9'
gem 'webauthn', '~> 3.0'
gem 'json-ld' gem 'json-ld'
gem 'json-ld-preloaded', '~> 3.2' gem 'json-ld-preloaded', '~> 3.2'
@ -104,6 +103,24 @@ gem 'rdf-normalize', '~> 0.5'
gem 'private_address_check', '~> 0.5' gem 'private_address_check', '~> 0.5'
group :opentelemetry do
gem 'opentelemetry-exporter-otlp', '~> 0.26.3', require: false
gem 'opentelemetry-instrumentation-active_job', '~> 0.7.1', require: false
gem 'opentelemetry-instrumentation-active_model_serializers', '~> 0.20.1', require: false
gem 'opentelemetry-instrumentation-concurrent_ruby', '~> 0.21.2', require: false
gem 'opentelemetry-instrumentation-excon', '~> 0.22.0', require: false
gem 'opentelemetry-instrumentation-faraday', '~> 0.24.1', require: false
gem 'opentelemetry-instrumentation-http', '~> 0.23.2', require: false
gem 'opentelemetry-instrumentation-http_client', '~> 0.22.3', require: false
gem 'opentelemetry-instrumentation-net_http', '~> 0.22.4', require: false
gem 'opentelemetry-instrumentation-pg', '~> 0.27.1', require: false
gem 'opentelemetry-instrumentation-rack', '~> 0.24.1', require: false
gem 'opentelemetry-instrumentation-rails', '~> 0.30.0', require: false
gem 'opentelemetry-instrumentation-redis', '~> 0.25.3', require: false
gem 'opentelemetry-instrumentation-sidekiq', '~> 0.25.2', require: false
gem 'opentelemetry-sdk', '~> 1.4', require: false
end
group :test do group :test do
# Adds RSpec Error/Warning annotations to GitHub PRs on the Files tab # Adds RSpec Error/Warning annotations to GitHub PRs on the Files tab
gem 'rspec-github', '~> 2.4', require: false gem 'rspec-github', '~> 2.4', require: false
@ -198,13 +215,14 @@ group :production do
gem 'lograge', '~> 0.12' gem 'lograge', '~> 0.12'
end end
gem 'cocoon', '~> 1.2'
gem 'concurrent-ruby', require: false gem 'concurrent-ruby', require: false
gem 'connection_pool', require: false gem 'connection_pool', require: false
gem 'xorcist', '~> 1.1' gem 'xorcist', '~> 1.1'
gem 'cocoon', '~> 1.2'
gem 'net-http', '~> 0.4.0' gem 'net-http', '~> 0.4.0'
gem 'rubyzip', '~> 2.3' gem 'rubyzip', '~> 2.3'
gem 'hcaptcha', '~> 7.1' gem 'hcaptcha', '~> 7.1'
gem 'mail', '~> 2.8'

View file

@ -97,22 +97,20 @@ GEM
activerecord (>= 3.2, < 8.0) activerecord (>= 3.2, < 8.0)
rake (>= 10.4, < 14.0) rake (>= 10.4, < 14.0)
ast (2.4.2) ast (2.4.2)
attr_encrypted (4.0.0) attr_required (1.0.2)
encryptor (~> 3.0.0)
attr_required (1.0.1)
awrence (1.2.1) awrence (1.2.1)
aws-eventstream (1.3.0) aws-eventstream (1.3.0)
aws-partitions (1.873.0) aws-partitions (1.922.0)
aws-sdk-core (3.190.1) aws-sdk-core (3.194.1)
aws-eventstream (~> 1, >= 1.3.0) aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.651.0) aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.8) aws-sigv4 (~> 1.8)
jmespath (~> 1, >= 1.6.1) jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.75.0) aws-sdk-kms (1.80.0)
aws-sdk-core (~> 3, >= 3.188.0) aws-sdk-core (~> 3, >= 3.193.0)
aws-sigv4 (~> 1.1) aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.142.0) aws-sdk-s3 (1.149.1)
aws-sdk-core (~> 3, >= 3.189.0) aws-sdk-core (~> 3, >= 3.194.0)
aws-sdk-kms (~> 1) aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.8) aws-sigv4 (~> 1.8)
aws-sigv4 (1.8.0) aws-sigv4 (1.8.0)
@ -132,17 +130,10 @@ GEM
erubi (>= 1.0.0) erubi (>= 1.0.0)
rack (>= 0.9.0) rack (>= 0.9.0)
rouge (>= 1.0.0) rouge (>= 1.0.0)
better_html (2.0.2) bigdecimal (3.1.8)
actionview (>= 6.0) bindata (2.5.0)
activesupport (>= 6.0) binding_of_caller (1.0.1)
ast (~> 2.0) debug_inspector (>= 1.2.0)
erubi (~> 1.4)
parser (>= 2.4)
smart_properties
bigdecimal (3.1.7)
bindata (2.4.15)
binding_of_caller (1.0.0)
debug_inspector (>= 0.0.1)
blurhash (0.1.7) blurhash (0.1.7)
bootsnap (1.18.3) bootsnap (1.18.3)
msgpack (~> 1.2) msgpack (~> 1.2)
@ -167,11 +158,11 @@ GEM
xpath (~> 3.2) xpath (~> 3.2)
case_transform (0.2) case_transform (0.2)
activesupport activesupport
cbor (0.5.9.6) cbor (0.5.9.8)
charlock_holmes (0.7.7) charlock_holmes (0.7.7)
chewy (7.5.1) chewy (7.6.0)
activesupport (>= 5.2) activesupport (>= 5.2)
elasticsearch (>= 7.12.0, < 7.14.0) elasticsearch (>= 7.14.0, < 8)
elasticsearch-dsl elasticsearch-dsl
chunky_png (1.4.0) chunky_png (1.4.0)
climate_control (1.2.0) climate_control (1.2.0)
@ -182,31 +173,30 @@ GEM
cose (1.3.0) cose (1.3.0)
cbor (~> 0.5.9) cbor (~> 0.5.9)
openssl-signature_algorithm (~> 1.0) openssl-signature_algorithm (~> 1.0)
crack (0.4.6) crack (1.0.0)
bigdecimal bigdecimal
rexml rexml
crass (1.0.6) crass (1.0.6)
css_parser (1.14.0) css_parser (1.17.1)
addressable addressable
csv (3.2.8) csv (3.3.0)
database_cleaner-active_record (2.1.0) database_cleaner-active_record (2.1.0)
activerecord (>= 5.a) activerecord (>= 5.a)
database_cleaner-core (~> 2.0.0) database_cleaner-core (~> 2.0.0)
database_cleaner-core (2.0.1) database_cleaner-core (2.0.1)
date (3.3.4) date (3.3.4)
debug (1.9.1) debug (1.9.2)
irb (~> 1.10) irb (~> 1.10)
reline (>= 0.3.8) reline (>= 0.3.8)
debug_inspector (1.1.0) debug_inspector (1.2.0)
devise (4.9.3) devise (4.9.4)
bcrypt (~> 3.0) bcrypt (~> 3.0)
orm_adapter (~> 0.1) orm_adapter (~> 0.1)
railties (>= 4.1.0) railties (>= 4.1.0)
responders responders
warden (~> 1.2.3) warden (~> 1.2.3)
devise-two-factor (4.1.1) devise-two-factor (5.0.0)
activesupport (~> 7.0) activesupport (~> 7.0)
attr_encrypted (>= 1.3, < 5, != 2)
devise (~> 4.0) devise (~> 4.0)
railties (~> 7.0) railties (~> 7.0)
rotp (~> 6.0) rotp (~> 6.0)
@ -217,36 +207,31 @@ GEM
discard (1.3.0) discard (1.3.0)
activerecord (>= 4.2, < 8) activerecord (>= 4.2, < 8)
docile (1.4.0) docile (1.4.0)
domain_name (0.5.20190701) domain_name (0.6.20240107)
unf (>= 0.0.5, < 1.0.0)
doorkeeper (5.6.9) doorkeeper (5.6.9)
railties (>= 5) railties (>= 5)
dotenv (2.8.1) dotenv (3.1.2)
dotenv-rails (2.8.1)
dotenv (= 2.8.1)
railties (>= 3.2)
drb (2.2.1) drb (2.2.1)
ed25519 (1.3.0) ed25519 (1.3.0)
elasticsearch (7.13.3) elasticsearch (7.17.10)
elasticsearch-api (= 7.13.3) elasticsearch-api (= 7.17.10)
elasticsearch-transport (= 7.13.3) elasticsearch-transport (= 7.17.10)
elasticsearch-api (7.13.3) elasticsearch-api (7.17.10)
multi_json multi_json
elasticsearch-dsl (0.1.10) elasticsearch-dsl (0.1.10)
elasticsearch-transport (7.13.3) elasticsearch-transport (7.17.10)
faraday (~> 1) faraday (>= 1, < 3)
multi_json multi_json
email_spec (2.2.2) email_spec (2.2.2)
htmlentities (~> 4.3.3) htmlentities (~> 4.3.3)
launchy (~> 2.1) launchy (~> 2.1)
mail (~> 2.7) mail (~> 2.7)
encryptor (3.0.0)
erubi (1.12.0) erubi (1.12.0)
et-orbi (1.2.7) et-orbi (1.2.11)
tzinfo tzinfo
excon (0.109.0) excon (0.110.0)
fabrication (2.31.0) fabrication (2.31.0)
faker (3.2.3) faker (3.3.1)
i18n (>= 1.8.11, < 2) i18n (>= 1.8.11, < 2)
faraday (1.10.3) faraday (1.10.3)
faraday-em_http (~> 1.0) faraday-em_http (~> 1.0)
@ -274,10 +259,10 @@ GEM
faraday_middleware (1.2.0) faraday_middleware (1.2.0)
faraday (~> 1.0) faraday (~> 1.0)
fast_blank (1.0.1) fast_blank (1.0.1)
fastimage (2.3.0) fastimage (2.3.1)
ffi (1.15.5) ffi (1.16.3)
ffi-compiler (1.0.1) ffi-compiler (1.3.2)
ffi (>= 1.0.0) ffi (>= 1.15.5)
rake rake
fog-core (2.4.0) fog-core (2.4.0)
builder builder
@ -291,7 +276,7 @@ GEM
fog-core (~> 2.1) fog-core (~> 2.1)
fog-json (>= 1.0) fog-json (>= 1.0)
formatador (1.1.0) formatador (1.1.0)
fugit (1.8.1) fugit (1.10.1)
et-orbi (~> 1, >= 1.2.7) et-orbi (~> 1, >= 1.2.7)
raabro (~> 1.4) raabro (~> 1.4)
fuubar (2.5.1) fuubar (2.5.1)
@ -299,6 +284,9 @@ GEM
ruby-progressbar (~> 1.4) ruby-progressbar (~> 1.4)
globalid (1.2.1) globalid (1.2.1)
activesupport (>= 6.1) activesupport (>= 6.1)
google-protobuf (3.25.3)
googleapis-common-protos-types (1.14.0)
google-protobuf (~> 3.18)
haml (6.3.0) haml (6.3.0)
temple (>= 0.8.2) temple (>= 0.8.2)
thor thor
@ -308,7 +296,7 @@ GEM
activesupport (>= 5.1) activesupport (>= 5.1)
haml (>= 4.0.6) haml (>= 4.0.6)
railties (>= 5.1) railties (>= 5.1)
haml_lint (0.57.0) haml_lint (0.58.0)
haml (>= 5.0) haml (>= 5.0)
parallel (~> 1.10) parallel (~> 1.10)
rainbow rainbow
@ -318,15 +306,16 @@ GEM
hashie (5.0.0) hashie (5.0.0)
hcaptcha (7.1.0) hcaptcha (7.1.0)
json json
highline (2.1.0) highline (3.0.1)
hiredis (0.6.3) hiredis (0.6.3)
hkdf (0.3.0) hkdf (0.3.0)
htmlentities (4.3.4) htmlentities (4.3.4)
http (5.1.1) http (5.2.0)
addressable (~> 2.8) addressable (~> 2.8)
base64 (~> 0.1)
http-cookie (~> 1.0) http-cookie (~> 1.0)
http-form_data (~> 2.2) http-form_data (~> 2.2)
llhttp-ffi (~> 0.4.0) llhttp-ffi (~> 0.5.0)
http-cookie (1.0.5) http-cookie (1.0.5)
domain_name (~> 0.5) domain_name (~> 0.5)
http-form_data (2.3.0) http-form_data (2.3.0)
@ -335,12 +324,11 @@ GEM
httplog (1.6.3) httplog (1.6.3)
rack (>= 2.0) rack (>= 2.0)
rainbow (>= 2.0.0) rainbow (>= 2.0.0)
i18n (1.14.1) i18n (1.14.5)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
i18n-tasks (1.0.13) i18n-tasks (1.0.14)
activesupport (>= 4.0.2) activesupport (>= 4.0.2)
ast (>= 2.1.0) ast (>= 2.1.0)
better_html (>= 1.0, < 3.0)
erubi erubi
highline (>= 2.0.0) highline (>= 2.0.0)
i18n i18n
@ -353,11 +341,11 @@ GEM
activesupport (>= 3.0) activesupport (>= 3.0)
nokogiri (>= 1.6) nokogiri (>= 1.6)
io-console (0.7.2) io-console (0.7.2)
irb (1.12.0) irb (1.13.1)
rdoc rdoc (>= 4.0.0)
reline (>= 0.4.2) reline (>= 0.4.2)
jmespath (1.6.2) jmespath (1.6.2)
json (2.7.1) json (2.7.2)
json-canonicalization (1.0.0) json-canonicalization (1.0.0)
json-jwt (1.15.3.1) json-jwt (1.15.3.1)
activesupport (>= 4.2) activesupport (>= 4.2)
@ -374,7 +362,7 @@ GEM
json-ld-preloaded (3.3.0) json-ld-preloaded (3.3.0)
json-ld (~> 3.3) json-ld (~> 3.3)
rdf (~> 3.3) rdf (~> 3.3)
json-schema (4.2.0) json-schema (4.3.0)
addressable (>= 2.8) addressable (>= 2.8)
jsonapi-renderer (0.2.2) jsonapi-renderer (0.2.2)
jwt (2.7.1) jwt (2.7.1)
@ -399,15 +387,15 @@ GEM
language_server-protocol (3.17.0.3) language_server-protocol (3.17.0.3)
launchy (2.5.2) launchy (2.5.2)
addressable (~> 2.8) addressable (~> 2.8)
letter_opener (1.8.1) letter_opener (1.10.0)
launchy (>= 2.2, < 3) launchy (>= 2.2, < 4)
letter_opener_web (2.0.0) letter_opener_web (2.0.0)
actionmailer (>= 5.2) actionmailer (>= 5.2)
letter_opener (~> 1.7) letter_opener (~> 1.7)
railties (>= 5.2) railties (>= 5.2)
rexml rexml
link_header (0.0.8) link_header (0.0.8)
llhttp-ffi (0.4.0) llhttp-ffi (0.5.0)
ffi-compiler (~> 1.0) ffi-compiler (~> 1.0)
rake (~> 13.0) rake (~> 13.0)
lograge (0.14.0) lograge (0.14.0)
@ -423,7 +411,7 @@ GEM
net-imap net-imap
net-pop net-pop
net-smtp net-smtp
marcel (1.0.2) marcel (1.0.4)
mario-redis-lock (1.2.1) mario-redis-lock (1.2.1)
redis (>= 3.0.5) redis (>= 3.0.5)
matrix (0.4.2) matrix (0.4.2)
@ -434,13 +422,13 @@ GEM
memory_profiler (1.0.1) memory_profiler (1.0.1)
mime-types (3.5.2) mime-types (3.5.2)
mime-types-data (~> 3.2015) mime-types-data (~> 3.2015)
mime-types-data (3.2023.1205) mime-types-data (3.2024.0305)
mini_mime (1.1.5) mini_mime (1.1.5)
mini_portile2 (2.8.5) mini_portile2 (2.8.6)
minitest (5.22.3) minitest (5.22.3)
msgpack (1.7.2) msgpack (1.7.2)
multi_json (1.15.0) multi_json (1.15.0)
multipart-post (2.3.0) multipart-post (2.4.0)
mutex_m (0.2.0) mutex_m (0.2.0)
net-http (0.4.1) net-http (0.4.1)
uri uri
@ -454,10 +442,10 @@ GEM
net-protocol net-protocol
net-protocol (0.2.2) net-protocol (0.2.2)
timeout timeout
net-smtp (0.4.0.1) net-smtp (0.5.0)
net-protocol net-protocol
nio4r (2.5.9) nio4r (2.7.1)
nokogiri (1.16.3) nokogiri (1.16.4)
mini_portile2 (~> 2.8.2) mini_portile2 (~> 2.8.2)
racc (~> 1.4) racc (~> 1.4)
nsa (0.3.0) nsa (0.3.0)
@ -498,10 +486,100 @@ GEM
openssl (3.2.0) openssl (3.2.0)
openssl-signature_algorithm (1.3.0) openssl-signature_algorithm (1.3.0)
openssl (> 2.0) openssl (> 2.0)
opentelemetry-api (1.2.5)
opentelemetry-common (0.20.1)
opentelemetry-api (~> 1.0)
opentelemetry-exporter-otlp (0.26.3)
google-protobuf (~> 3.14)
googleapis-common-protos-types (~> 1.3)
opentelemetry-api (~> 1.1)
opentelemetry-common (~> 0.20)
opentelemetry-sdk (~> 1.2)
opentelemetry-semantic_conventions
opentelemetry-helpers-sql-obfuscation (0.1.0)
opentelemetry-common (~> 0.20)
opentelemetry-instrumentation-action_pack (0.9.0)
opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-base (~> 0.22.1)
opentelemetry-instrumentation-rack (~> 0.21)
opentelemetry-instrumentation-action_view (0.7.0)
opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-active_support (~> 0.1)
opentelemetry-instrumentation-base (~> 0.22.1)
opentelemetry-instrumentation-active_job (0.7.1)
opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-base (~> 0.22.1)
opentelemetry-instrumentation-active_model_serializers (0.20.1)
opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-base (~> 0.22.1)
opentelemetry-instrumentation-active_record (0.7.2)
opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-base (~> 0.22.1)
opentelemetry-instrumentation-active_support (0.5.1)
opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-base (~> 0.22.1)
opentelemetry-instrumentation-base (0.22.3)
opentelemetry-api (~> 1.0)
opentelemetry-registry (~> 0.1)
opentelemetry-instrumentation-concurrent_ruby (0.21.3)
opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-base (~> 0.22.1)
opentelemetry-instrumentation-excon (0.22.1)
opentelemetry-api (~> 1.0)
opentelemetry-common (~> 0.20.0)
opentelemetry-instrumentation-base (~> 0.22.1)
opentelemetry-instrumentation-faraday (0.24.2)
opentelemetry-api (~> 1.0)
opentelemetry-common (~> 0.20.0)
opentelemetry-instrumentation-base (~> 0.22.1)
opentelemetry-instrumentation-http (0.23.3)
opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-base (~> 0.22.1)
opentelemetry-instrumentation-http_client (0.22.4)
opentelemetry-api (~> 1.0)
opentelemetry-common (~> 0.20.0)
opentelemetry-instrumentation-base (~> 0.22.1)
opentelemetry-instrumentation-net_http (0.22.4)
opentelemetry-api (~> 1.0)
opentelemetry-common (~> 0.20.0)
opentelemetry-instrumentation-base (~> 0.22.1)
opentelemetry-instrumentation-pg (0.27.2)
opentelemetry-api (~> 1.0)
opentelemetry-helpers-sql-obfuscation
opentelemetry-instrumentation-base (~> 0.22.1)
opentelemetry-instrumentation-rack (0.24.3)
opentelemetry-api (~> 1.0)
opentelemetry-common (~> 0.20.0)
opentelemetry-instrumentation-base (~> 0.22.1)
opentelemetry-instrumentation-rails (0.30.1)
opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-action_pack (~> 0.9.0)
opentelemetry-instrumentation-action_view (~> 0.7.0)
opentelemetry-instrumentation-active_job (~> 0.7.0)
opentelemetry-instrumentation-active_record (~> 0.7.0)
opentelemetry-instrumentation-active_support (~> 0.5.0)
opentelemetry-instrumentation-base (~> 0.22.1)
opentelemetry-instrumentation-redis (0.25.4)
opentelemetry-api (~> 1.0)
opentelemetry-common (~> 0.20.0)
opentelemetry-instrumentation-base (~> 0.22.1)
opentelemetry-instrumentation-sidekiq (0.25.3)
opentelemetry-api (~> 1.0)
opentelemetry-common (~> 0.20.0)
opentelemetry-instrumentation-base (~> 0.22.1)
opentelemetry-registry (0.3.1)
opentelemetry-api (~> 1.1)
opentelemetry-sdk (1.4.1)
opentelemetry-api (~> 1.1)
opentelemetry-common (~> 0.20)
opentelemetry-registry (~> 0.2)
opentelemetry-semantic_conventions
opentelemetry-semantic_conventions (1.10.0)
opentelemetry-api (~> 1.0)
orm_adapter (0.5.0) orm_adapter (0.5.0)
ox (2.14.18) ox (2.14.18)
parallel (1.24.0) parallel (1.24.0)
parser (3.3.0.5) parser (3.3.1.0)
ast (~> 2.4.1) ast (~> 2.4.1)
racc racc
parslet (2.0.0) parslet (2.0.0)
@ -510,8 +588,7 @@ GEM
pg (1.5.6) pg (1.5.6)
pghero (3.4.1) pghero (3.4.1)
activerecord (>= 6) activerecord (>= 6)
posix-spawn (0.3.15) premailer (1.23.0)
premailer (1.21.0)
addressable addressable
css_parser (>= 1.12.0) css_parser (>= 1.12.0)
htmlentities (>= 4.0.0) htmlentities (>= 4.0.0)
@ -527,10 +604,10 @@ GEM
railties (>= 7.0.0) railties (>= 7.0.0)
psych (5.1.2) psych (5.1.2)
stringio stringio
public_suffix (5.0.4) public_suffix (5.0.5)
puma (6.4.2) puma (6.4.2)
nio4r (~> 2.0) nio4r (~> 2.0)
pundit (2.3.1) pundit (2.3.2)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
raabro (1.4.0) raabro (1.4.0)
racc (1.7.3) racc (1.7.3)
@ -548,7 +625,7 @@ GEM
rack-protection (3.2.0) rack-protection (3.2.0)
base64 (>= 0.1.0) base64 (>= 0.1.0)
rack (~> 2.2, >= 2.2.4) rack (~> 2.2, >= 2.2.4)
rack-proxy (0.7.6) rack-proxy (0.7.7)
rack rack
rack-session (1.0.2) rack-session (1.0.2)
rack (< 3) rack (< 3)
@ -594,7 +671,7 @@ GEM
thor (~> 1.0, >= 1.2.2) thor (~> 1.0, >= 1.2.2)
zeitwerk (~> 2.6) zeitwerk (~> 2.6)
rainbow (3.1.1) rainbow (3.1.1)
rake (13.1.0) rake (13.2.1)
rdf (3.3.1) rdf (3.3.1)
bcp47_spec (~> 0.2) bcp47_spec (~> 0.2)
link_header (~> 0.0, >= 0.0.8) link_header (~> 0.0, >= 0.0.8)
@ -609,16 +686,16 @@ GEM
redlock (1.3.2) redlock (1.3.2)
redis (>= 3.0.0, < 6.0) redis (>= 3.0.0, < 6.0)
regexp_parser (2.9.0) regexp_parser (2.9.0)
reline (0.4.3) reline (0.5.6)
io-console (~> 0.5) io-console (~> 0.5)
request_store (1.5.1) request_store (1.6.0)
rack (>= 1.4) rack (>= 1.4)
responders (3.1.1) responders (3.1.1)
actionpack (>= 5.2) actionpack (>= 5.2)
railties (>= 5.2) railties (>= 5.2)
rexml (3.2.6) rexml (3.2.6)
rotp (6.3.0) rotp (6.3.0)
rouge (4.1.2) rouge (4.2.1)
rpam2 (4.0.2) rpam2 (4.0.2)
rqrcode (2.2.0) rqrcode (2.2.0)
chunky_png (~> 1.0) chunky_png (~> 1.0)
@ -642,13 +719,13 @@ GEM
rspec-expectations (~> 3.13) rspec-expectations (~> 3.13)
rspec-mocks (~> 3.13) rspec-mocks (~> 3.13)
rspec-support (~> 3.13) rspec-support (~> 3.13)
rspec-sidekiq (4.1.0) rspec-sidekiq (4.2.0)
rspec-core (~> 3.0) rspec-core (~> 3.0)
rspec-expectations (~> 3.0) rspec-expectations (~> 3.0)
rspec-mocks (~> 3.0) rspec-mocks (~> 3.0)
sidekiq (>= 5, < 8) sidekiq (>= 5, < 8)
rspec-support (3.13.1) rspec-support (3.13.1)
rubocop (1.62.1) rubocop (1.63.5)
json (~> 2.3) json (~> 2.3)
language_server-protocol (>= 3.17.0) language_server-protocol (>= 3.17.0)
parallel (~> 1.10) parallel (~> 1.10)
@ -659,27 +736,30 @@ GEM
rubocop-ast (>= 1.31.1, < 2.0) rubocop-ast (>= 1.31.1, < 2.0)
ruby-progressbar (~> 1.7) ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0) unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.31.2) rubocop-ast (1.31.3)
parser (>= 3.3.0.4) parser (>= 3.3.1.0)
rubocop-capybara (2.20.0) rubocop-capybara (2.20.0)
rubocop (~> 1.41) rubocop (~> 1.41)
rubocop-factory_bot (2.25.1) rubocop-factory_bot (2.25.1)
rubocop (~> 1.41) rubocop (~> 1.41)
rubocop-performance (1.20.2) rubocop-performance (1.21.0)
rubocop (>= 1.48.1, < 2.0) rubocop (>= 1.48.1, < 2.0)
rubocop-ast (>= 1.30.0, < 2.0) rubocop-ast (>= 1.31.1, < 2.0)
rubocop-rails (2.24.0) rubocop-rails (2.24.1)
activesupport (>= 4.2.0) activesupport (>= 4.2.0)
rack (>= 1.1) rack (>= 1.1)
rubocop (>= 1.33.0, < 2.0) rubocop (>= 1.33.0, < 2.0)
rubocop-ast (>= 1.31.1, < 2.0) rubocop-ast (>= 1.31.1, < 2.0)
rubocop-rspec (2.27.1) rubocop-rspec (2.29.2)
rubocop (~> 1.40) rubocop (~> 1.40)
rubocop-capybara (~> 2.17) rubocop-capybara (~> 2.17)
rubocop-factory_bot (~> 2.22) rubocop-factory_bot (~> 2.22)
rubocop-rspec_rails (~> 2.28)
rubocop-rspec_rails (2.28.3)
rubocop (~> 1.40)
ruby-prof (1.7.0) ruby-prof (1.7.0)
ruby-progressbar (1.13.0) ruby-progressbar (1.13.0)
ruby-saml (1.15.0) ruby-saml (1.16.0)
nokogiri (>= 1.13.10) nokogiri (>= 1.13.10)
rexml rexml
ruby2_keywords (0.0.5) ruby2_keywords (0.0.5)
@ -691,10 +771,10 @@ GEM
sanitize (6.1.0) sanitize (6.1.0)
crass (~> 1.0.2) crass (~> 1.0.2)
nokogiri (>= 1.12.0) nokogiri (>= 1.12.0)
scenic (1.7.0) scenic (1.8.0)
activerecord (>= 4.0.0) activerecord (>= 4.0.0)
railties (>= 4.0.0) railties (>= 4.0.0)
selenium-webdriver (4.18.1) selenium-webdriver (4.20.1)
base64 (~> 0.2) base64 (~> 0.2)
rexml (~> 3.2, >= 3.2.5) rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 3.0) rubyzip (>= 1.2.2, < 3.0)
@ -728,10 +808,9 @@ GEM
simplecov-html (0.12.3) simplecov-html (0.12.3)
simplecov-lcov (0.8.0) simplecov-lcov (0.8.0)
simplecov_json_formatter (0.1.4) simplecov_json_formatter (0.1.4)
smart_properties (1.17.0)
stackprof (0.2.26) stackprof (0.2.26)
statsd-ruby (1.5.0) statsd-ruby (1.5.0)
stoplight (3.0.2) stoplight (4.1.0)
redlock (~> 1.0) redlock (~> 1.0)
stringio (3.1.0) stringio (3.1.0)
strong_migrations (1.8.0) strong_migrations (1.8.0)
@ -746,7 +825,7 @@ GEM
unicode-display_width (>= 1.1.1, < 3) unicode-display_width (>= 1.1.1, < 3)
terrapin (1.0.1) terrapin (1.0.1)
climate_control climate_control
test-prof (1.3.2) test-prof (1.3.3)
thor (1.3.1) thor (1.3.1)
tilt (2.3.0) tilt (2.3.0)
timeout (0.4.1) timeout (0.4.1)
@ -763,7 +842,7 @@ GEM
tty-cursor (~> 0.7) tty-cursor (~> 0.7)
tty-screen (~> 0.8) tty-screen (~> 0.8)
wisper (~> 2.0) wisper (~> 2.0)
tty-screen (0.8.1) tty-screen (0.8.2)
twitter-text (3.1.0) twitter-text (3.1.0)
idn-ruby idn-ruby
unf (~> 0.1.0) unf (~> 0.1.0)
@ -773,9 +852,9 @@ GEM
tzinfo (>= 1.0.0) tzinfo (>= 1.0.0)
unf (0.1.4) unf (0.1.4)
unf_ext unf_ext
unf_ext (0.0.8.2) unf_ext (0.0.9.1)
unicode-display_width (2.5.0) unicode-display_width (2.5.0)
uri (0.12.2) uri (0.13.0)
validate_email (0.1.6) validate_email (0.1.6)
activemodel (>= 3.0) activemodel (>= 3.0)
mail (>= 2.2.5) mail (>= 2.2.5)
@ -796,7 +875,7 @@ GEM
webfinger (1.2.0) webfinger (1.2.0)
activesupport activesupport
httpclient (>= 2.4) httpclient (>= 2.4)
webmock (3.22.0) webmock (3.23.0)
addressable (>= 2.8.0) addressable (>= 2.8.0)
crack (>= 0.3.2) crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0) hashdiff (>= 0.4.0, < 2.0.0)
@ -843,11 +922,11 @@ DEPENDENCIES
database_cleaner-active_record database_cleaner-active_record
debug (~> 1.8) debug (~> 1.8)
devise (~> 4.9) devise (~> 4.9)
devise-two-factor (~> 4.1) devise-two-factor
devise_pam_authenticatable2 (~> 9.2) devise_pam_authenticatable2 (~> 9.2)
discard (~> 1.2) discard (~> 1.2)
doorkeeper (~> 5.6) doorkeeper (~> 5.6)
dotenv-rails (~> 2.8) dotenv
ed25519 (~> 1.3) ed25519 (~> 1.3)
email_spec email_spec
fabrication (~> 2.30) fabrication (~> 2.30)
@ -862,10 +941,10 @@ DEPENDENCIES
hcaptcha (~> 7.1) hcaptcha (~> 7.1)
hiredis (~> 0.6) hiredis (~> 0.6)
htmlentities (~> 4.3) htmlentities (~> 4.3)
http (~> 5.1) http (~> 5.2.0)
http_accept_language (~> 2.1) http_accept_language (~> 2.1)
httplog (~> 1.6.2) httplog (~> 1.6.2)
i18n (= 1.14.1) i18n
i18n-tasks (~> 1.0) i18n-tasks (~> 1.0)
idn-ruby idn-ruby
inline_svg inline_svg
@ -879,6 +958,7 @@ DEPENDENCIES
letter_opener_web (~> 2.0) letter_opener_web (~> 2.0)
link_header (~> 0.0) link_header (~> 0.0)
lograge (~> 0.12) lograge (~> 0.12)
mail (~> 2.8)
mario-redis-lock (~> 1.2) mario-redis-lock (~> 1.2)
md-paperclip-azure (~> 2.2) md-paperclip-azure (~> 2.2)
memory_profiler memory_profiler
@ -893,11 +973,25 @@ DEPENDENCIES
omniauth-rails_csrf_protection (~> 1.0) omniauth-rails_csrf_protection (~> 1.0)
omniauth-saml (~> 2.0) omniauth-saml (~> 2.0)
omniauth_openid_connect (~> 0.6.1) omniauth_openid_connect (~> 0.6.1)
opentelemetry-exporter-otlp (~> 0.26.3)
opentelemetry-instrumentation-active_job (~> 0.7.1)
opentelemetry-instrumentation-active_model_serializers (~> 0.20.1)
opentelemetry-instrumentation-concurrent_ruby (~> 0.21.2)
opentelemetry-instrumentation-excon (~> 0.22.0)
opentelemetry-instrumentation-faraday (~> 0.24.1)
opentelemetry-instrumentation-http (~> 0.23.2)
opentelemetry-instrumentation-http_client (~> 0.22.3)
opentelemetry-instrumentation-net_http (~> 0.22.4)
opentelemetry-instrumentation-pg (~> 0.27.1)
opentelemetry-instrumentation-rack (~> 0.24.1)
opentelemetry-instrumentation-rails (~> 0.30.0)
opentelemetry-instrumentation-redis (~> 0.25.3)
opentelemetry-instrumentation-sidekiq (~> 0.25.2)
opentelemetry-sdk (~> 1.4)
ox (~> 2.14) ox (~> 2.14)
parslet parslet
pg (~> 1.5) pg (~> 1.5)
pghero pghero
posix-spawn
premailer-rails premailer-rails
private_address_check (~> 0.5) private_address_check (~> 0.5)
propshaft propshaft
@ -939,7 +1033,7 @@ DEPENDENCIES
simplecov (~> 0.22) simplecov (~> 0.22)
simplecov-lcov (~> 0.8) simplecov-lcov (~> 0.8)
stackprof stackprof
stoplight (~> 3.0.1) stoplight (~> 4.1)
strong_migrations (= 1.8.0) strong_migrations (= 1.8.0)
test-prof test-prof
thor (~> 1.2) thor (~> 1.2)
@ -953,7 +1047,7 @@ DEPENDENCIES
xorcist (~> 1.1) xorcist (~> 1.1)
RUBY VERSION RUBY VERSION
ruby 3.2.2p53 ruby 3.3.1p55
BUNDLED WITH BUNDLED WITH
2.5.4 2.5.9

View file

@ -1,4 +1,4 @@
# <img src="https://github.com/TheEssem/mastodon/raw/main/app/javascript/icons/android-chrome-256x256.png" width="128"> Chuckya # <img src="https://github.com/TheEssem/mastodon/raw/main/public/chuckya.png" width="128"> Chuckya
Chuckya is a close-to-upstream soft fork of Mastodon Glitch Edition (more commonly known as glitch-soc) that aims to introduce more experimental features/fixes with the goal of making the overall experience more enjoyable. Although it's mainly developed for and used on the [wetdry.world](https://wetdry.world) instance, it can be deployed by any server admin as a drop-in, backwards-compatible replacement for Mastodon. Chuckya is a close-to-upstream soft fork of Mastodon Glitch Edition (more commonly known as glitch-soc) that aims to introduce more experimental features/fixes with the goal of making the overall experience more enjoyable. Although it's mainly developed for and used on the [wetdry.world](https://wetdry.world) instance, it can be deployed by any server admin as a drop-in, backwards-compatible replacement for Mastodon.
@ -15,7 +15,6 @@ Here are some of the changes compared to glitch-soc:
- Allows dashes in custom emote names - Allows dashes in custom emote names
- Emojis can be put side-by-side - Emojis can be put side-by-side
- Minor media attachment tweaks - Minor media attachment tweaks
- Custom favicon
Changes previously in Chuckya that made their way into vanilla Mastodon: Changes previously in Chuckya that made their way into vanilla Mastodon:
@ -112,8 +111,8 @@ Mastodon acts as an OAuth2 provider, so 3rd party apps can use the REST and Stre
- **PostgreSQL** 12+ - **PostgreSQL** 12+
- **Redis** 4+ - **Redis** 4+
- **Ruby** 3.0+ - **Ruby** 3.1+
- **Node.js** 16+ - **Node.js** 18+
The repository includes deployment configurations for **Docker and docker-compose** as well as specific platforms like **Heroku**, **Scalingo**, and **Nanobox**. For Helm charts, reference the [mastodon/chart repository](https://github.com/mastodon/chart). The [**standalone** installation guide](https://docs.joinmastodon.org/admin/install/) is available in the documentation. The repository includes deployment configurations for **Docker and docker-compose** as well as specific platforms like **Heroku**, **Scalingo**, and **Nanobox**. For Helm charts, reference the [mastodon/chart repository](https://github.com/mastodon/chart). The [**standalone** installation guide](https://docs.joinmastodon.org/admin/install/) is available in the documentation.
@ -134,10 +133,12 @@ A **Vagrant** configuration is included for development purposes. To use it, com
To set up **MacOS** for native development, complete the following steps: To set up **MacOS** for native development, complete the following steps:
- Use a Ruby version manager to install the specified version from `.ruby-version` - Use a Ruby version manager to install the specified version from `.ruby-version`
- Run `bundle` to install required gems
- Run `brew install postgresql@14 redis imagemagick libidn` to install required dependencies - Run `brew install postgresql@14 redis imagemagick libidn` to install required dependencies
- Navigate to Mastodon's root directory and run `brew install nvm` then `nvm use` to use the version from `.nvmrc` - Navigate to Mastodon's root directory and run `brew install nvm` then `nvm use` to use the version from `.nvmrc`
- Run `yarn` to install required packages
- Run `corepack enable && corepack prepare` - Run `corepack enable && corepack prepare`
- Run `bundle exec rails db:setup` (optionally prepend `RAILS_ENV=development` to target the dev environment) - Run `RAILS_ENV=development bundle exec rails db:setup`
- Finally, run `bin/dev` which will launch the local services via `overmind` (if installed) or `foreman` - Finally, run `bin/dev` which will launch the local services via `overmind` (if installed) or `foreman`
### Docker ### Docker

1
Vagrantfile vendored
View file

@ -173,6 +173,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
# Otherwise, you can access the site at http://localhost:3000 and http://localhost:4000 , http://localhost:8080 # Otherwise, you can access the site at http://localhost:3000 and http://localhost:4000 , http://localhost:8080
config.vm.network :forwarded_port, guest: 3000, host: 3000 config.vm.network :forwarded_port, guest: 3000, host: 3000
config.vm.network :forwarded_port, guest: 3035, host: 3035
config.vm.network :forwarded_port, guest: 4000, host: 4000 config.vm.network :forwarded_port, guest: 4000, host: 4000
config.vm.network :forwarded_port, guest: 8080, host: 8080 config.vm.network :forwarded_port, guest: 8080, host: 8080
config.vm.network :forwarded_port, guest: 9200, host: 9200 config.vm.network :forwarded_port, guest: 9200, host: 9200

View file

@ -46,7 +46,7 @@ class AccountsController < ApplicationController
end end
def default_statuses def default_statuses
@account.statuses.not_local_only.where(visibility: [:public, :unlisted]) @account.statuses.not_local_only.distributable_visibility
end end
def only_media_scope def only_media_scope

View file

@ -31,7 +31,7 @@ class ActivityPub::RepliesController < ActivityPub::BaseController
def set_replies def set_replies
@replies = only_other_accounts? ? Status.where.not(account_id: @account.id).joins(:account).merge(Account.without_suspended) : @account.statuses @replies = only_other_accounts? ? Status.where.not(account_id: @account.id).joins(:account).merge(Account.without_suspended) : @account.statuses
@replies = @replies.where(in_reply_to_id: @status.id, visibility: [:public, :unlisted]) @replies = @replies.distributable_visibility.where(in_reply_to_id: @status.id)
@replies = @replies.paginate_by_min_id(DESCENDANTS_LIMIT, params[:min_id]) @replies = @replies.paginate_by_min_id(DESCENDANTS_LIMIT, params[:min_id])
end end

View file

@ -7,7 +7,6 @@ module Admin
layout 'admin' layout 'admin'
before_action :set_pack
before_action :set_body_classes before_action :set_body_classes
before_action :set_cache_headers before_action :set_cache_headers
@ -19,10 +18,6 @@ module Admin
@body_classes = 'admin' @body_classes = 'admin'
end end
def set_pack
use_pack 'admin'
end
def set_cache_headers def set_cache_headers
response.cache_control.replace(private: true, no_store: true) response.cache_control.replace(private: true, no_store: true)
end end

View file

@ -25,6 +25,8 @@ class Admin::DomainAllowsController < Admin::BaseController
def destroy def destroy
authorize @domain_allow, :destroy? authorize @domain_allow, :destroy?
UnallowDomainService.new.call(@domain_allow) UnallowDomainService.new.call(@domain_allow)
log_action :destroy, @domain_allow
redirect_to admin_instances_path, notice: I18n.t('admin.domain_allows.destroyed_msg') redirect_to admin_instances_path, notice: I18n.t('admin.domain_allows.destroyed_msg')
end end

View file

@ -9,7 +9,7 @@ module Admin
@site_upload.destroy! @site_upload.destroy!
redirect_to admin_settings_path, notice: I18n.t('admin.site_uploads.destroyed_msg') redirect_back fallback_location: admin_settings_path, notice: I18n.t('admin.site_uploads.destroyed_msg')
end end
private private

View file

@ -9,6 +9,7 @@ class Api::BaseController < ApplicationController
include Api::CachingConcern include Api::CachingConcern
include Api::ContentSecurityPolicy include Api::ContentSecurityPolicy
include Api::ErrorHandling include Api::ErrorHandling
include Api::Pagination
skip_before_action :require_functional!, unless: :limited_federation_mode? skip_before_action :require_functional!, unless: :limited_federation_mode?
@ -29,21 +30,6 @@ class Api::BaseController < ApplicationController
protected protected
def pagination_max_id
pagination_collection.last.id
end
def pagination_since_id
pagination_collection.first.id
end
def set_pagination_headers(next_path = nil, prev_path = nil)
links = []
links << [next_path, [%w(rel next)]] if next_path
links << [prev_path, [%w(rel prev)]] if prev_path
response.headers['Link'] = LinkHeader.new(links) unless links.empty?
end
def limit_param(default_limit) def limit_param(default_limit)
return default_limit unless params[:limit] return default_limit unless params[:limit]
@ -72,10 +58,6 @@ class Api::BaseController < ApplicationController
render json: { error: 'Your login is currently disabled' }, status: 403 if current_user&.account&.unavailable? render json: { error: 'Your login is currently disabled' }, status: 403 if current_user&.account&.unavailable?
end end
def require_valid_pagination_options!
render json: { error: 'Pagination values for `offset` and `limit` must be positive' }, status: 400 if pagination_options_invalid?
end
def require_user! def require_user!
if !current_user if !current_user
render json: { error: 'This method requires an authenticated user' }, status: 422 render json: { error: 'This method requires an authenticated user' }, status: 422
@ -104,14 +86,6 @@ class Api::BaseController < ApplicationController
private private
def insert_pagination_headers
set_pagination_headers(next_path, prev_path)
end
def pagination_options_invalid?
params.slice(:limit, :offset).values.map(&:to_i).any?(&:negative?)
end
def respond_with_error(code) def respond_with_error(code)
render json: { error: Rack::Utils::HTTP_STATUS_CODES[code] }, status: code render json: { error: Rack::Utils::HTTP_STATUS_CODES[code] }, status: code
end end

View file

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
class Api::V1::Accounts::CredentialsController < Api::BaseController class Api::V1::Accounts::CredentialsController < Api::BaseController
before_action -> { doorkeeper_authorize! :read, :'read:accounts' }, except: [:update] before_action -> { doorkeeper_authorize! :read, :'read:accounts', :'read:me' }, except: [:update]
before_action -> { doorkeeper_authorize! :write, :'write:accounts' }, only: [:update] before_action -> { doorkeeper_authorize! :write, :'write:accounts' }, only: [:update]
before_action :require_user! before_action :require_user!

View file

@ -9,16 +9,22 @@ class Api::V1::AccountsController < Api::BaseController
before_action -> { doorkeeper_authorize! :follow, :write, :'write:blocks' }, only: [:block, :unblock] before_action -> { doorkeeper_authorize! :follow, :write, :'write:blocks' }, only: [:block, :unblock]
before_action -> { doorkeeper_authorize! :write, :'write:accounts' }, only: [:create] before_action -> { doorkeeper_authorize! :write, :'write:accounts' }, only: [:create]
before_action :require_user!, except: [:show, :create] before_action :require_user!, except: [:index, :show, :create]
before_action :set_account, except: [:create] before_action :set_account, except: [:index, :create]
before_action :check_account_approval, except: [:create] before_action :set_accounts, only: [:index]
before_action :check_account_confirmation, except: [:create] before_action :check_account_approval, except: [:index, :create]
before_action :check_account_confirmation, except: [:index, :create]
before_action :check_enabled_registrations, only: [:create] before_action :check_enabled_registrations, only: [:create]
before_action :check_accounts_limit, only: [:index]
skip_before_action :require_authenticated_user!, only: :create skip_before_action :require_authenticated_user!, only: :create
override_rate_limit_headers :follow, family: :follows override_rate_limit_headers :follow, family: :follows
def index
render json: @accounts, each_serializer: REST::AccountSerializer
end
def show def show
cache_if_unauthenticated! cache_if_unauthenticated!
render json: @account, serializer: REST::AccountSerializer render json: @account, serializer: REST::AccountSerializer
@ -79,6 +85,10 @@ class Api::V1::AccountsController < Api::BaseController
@account = Account.find(params[:id]) @account = Account.find(params[:id])
end end
def set_accounts
@accounts = Account.where(id: account_ids).without_unapproved
end
def check_account_approval def check_account_approval
raise(ActiveRecord::RecordNotFound) if @account.local? && @account.user_pending? raise(ActiveRecord::RecordNotFound) if @account.local? && @account.user_pending?
end end
@ -87,10 +97,22 @@ class Api::V1::AccountsController < Api::BaseController
raise(ActiveRecord::RecordNotFound) if @account.local? && !@account.user_confirmed? raise(ActiveRecord::RecordNotFound) if @account.local? && !@account.user_confirmed?
end end
def check_accounts_limit
raise(Mastodon::ValidationError) if account_ids.size > DEFAULT_ACCOUNTS_LIMIT
end
def relationships(**options) def relationships(**options)
AccountRelationshipsPresenter.new([@account], current_user.account_id, **options) AccountRelationshipsPresenter.new([@account], current_user.account_id, **options)
end end
def account_ids
Array(accounts_params[:ids]).uniq.map(&:to_i)
end
def accounts_params
params.permit(ids: [])
end
def account_params def account_params
params.permit(:username, :email, :password, :agreement, :locale, :reason, :time_zone, :invite_code) params.permit(:username, :email, :password, :agreement, :locale, :reason, :time_zone, :invite_code)
end end

View file

@ -29,10 +29,11 @@ class Api::V1::Admin::DomainBlocksController < Api::BaseController
def create def create
authorize :domain_block, :create? authorize :domain_block, :create?
@domain_block = DomainBlock.new(resource_params)
existing_domain_block = resource_params[:domain].present? ? DomainBlock.rule_for(resource_params[:domain]) : nil existing_domain_block = resource_params[:domain].present? ? DomainBlock.rule_for(resource_params[:domain]) : nil
return render json: existing_domain_block, serializer: REST::Admin::ExistingDomainBlockErrorSerializer, status: 422 if existing_domain_block.present? return render json: existing_domain_block, serializer: REST::Admin::ExistingDomainBlockErrorSerializer, status: 422 if conflicts_with_existing_block?(@domain_block, existing_domain_block)
@domain_block = DomainBlock.create!(resource_params) @domain_block.save!
DomainBlockWorker.perform_async(@domain_block.id) DomainBlockWorker.perform_async(@domain_block.id)
log_action :create, @domain_block log_action :create, @domain_block
render json: @domain_block, serializer: REST::Admin::DomainBlockSerializer render json: @domain_block, serializer: REST::Admin::DomainBlockSerializer
@ -55,6 +56,10 @@ class Api::V1::Admin::DomainBlocksController < Api::BaseController
private private
def conflicts_with_existing_block?(domain_block, existing_domain_block)
existing_domain_block.present? && (existing_domain_block.domain == TagManager.instance.normalize_domain(domain_block.domain) || !domain_block.stricter_than?(existing_domain_block))
end
def set_domain_blocks def set_domain_blocks
@domain_blocks = filtered_domain_blocks.order(id: :desc).to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id)) @domain_blocks = filtered_domain_blocks.order(id: :desc).to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
end end

View file

@ -12,10 +12,6 @@ class Api::V1::FeaturedTags::SuggestionsController < Api::BaseController
private private
def set_recently_used_tags def set_recently_used_tags
@recently_used_tags = Tag.recently_used(current_account).where.not(id: featured_tag_ids).limit(10) @recently_used_tags = Tag.suggestions_for_account(current_account).limit(10)
end
def featured_tag_ids
current_account.featured_tags.pluck(:tag_id)
end end
end end

View file

@ -1,9 +1,12 @@
# frozen_string_literal: true # frozen_string_literal: true
class Api::V1::Push::SubscriptionsController < Api::BaseController class Api::V1::Push::SubscriptionsController < Api::BaseController
include Redisable
include Lockable
before_action -> { doorkeeper_authorize! :push } before_action -> { doorkeeper_authorize! :push }
before_action :require_user! before_action :require_user!
before_action :set_push_subscription before_action :set_push_subscription, only: [:show, :update]
before_action :check_push_subscription, only: [:show, :update] before_action :check_push_subscription, only: [:show, :update]
def show def show
@ -11,16 +14,18 @@ class Api::V1::Push::SubscriptionsController < Api::BaseController
end end
def create def create
@push_subscription&.destroy! with_redis_lock("push_subscription:#{current_user.id}") do
destroy_web_push_subscriptions!
@push_subscription = Web::PushSubscription.create!( @push_subscription = Web::PushSubscription.create!(
endpoint: subscription_params[:endpoint], endpoint: subscription_params[:endpoint],
key_p256dh: subscription_params[:keys][:p256dh], key_p256dh: subscription_params[:keys][:p256dh],
key_auth: subscription_params[:keys][:auth], key_auth: subscription_params[:keys][:auth],
data: data_params, data: data_params,
user_id: current_user.id, user_id: current_user.id,
access_token_id: doorkeeper_token.id access_token_id: doorkeeper_token.id
) )
end
render json: @push_subscription, serializer: REST::WebPushSubscriptionSerializer render json: @push_subscription, serializer: REST::WebPushSubscriptionSerializer
end end
@ -31,14 +36,18 @@ class Api::V1::Push::SubscriptionsController < Api::BaseController
end end
def destroy def destroy
@push_subscription&.destroy! destroy_web_push_subscriptions!
render_empty render_empty
end end
private private
def destroy_web_push_subscriptions!
doorkeeper_token.web_push_subscriptions.destroy_all
end
def set_push_subscription def set_push_subscription
@push_subscription = Web::PushSubscription.find_by(access_token_id: doorkeeper_token.id) @push_subscription = doorkeeper_token.web_push_subscriptions.first
end end
def check_push_subscription def check_push_subscription

View file

@ -23,7 +23,7 @@ class Api::V1::Statuses::RebloggedByAccountsController < Api::V1::Statuses::Base
end end
def paginated_statuses def paginated_statuses
Status.where(reblog_of_id: @status.id).where(visibility: [:public, :unlisted]).paginate_by_max_id( Status.where(reblog_of_id: @status.id).distributable_visibility.paginate_by_max_id(
limit_param(DEFAULT_ACCOUNTS_LIMIT), limit_param(DEFAULT_ACCOUNTS_LIMIT),
params[:max_id], params[:max_id],
params[:since_id] params[:since_id]

View file

@ -5,9 +5,11 @@ class Api::V1::StatusesController < Api::BaseController
before_action -> { authorize_if_got_token! :read, :'read:statuses' }, except: [:create, :update, :destroy] before_action -> { authorize_if_got_token! :read, :'read:statuses' }, except: [:create, :update, :destroy]
before_action -> { doorkeeper_authorize! :write, :'write:statuses' }, only: [:create, :update, :destroy] before_action -> { doorkeeper_authorize! :write, :'write:statuses' }, only: [:create, :update, :destroy]
before_action :require_user!, except: [:show, :context] before_action :require_user!, except: [:index, :show, :context]
before_action :set_status, only: [:show, :context] before_action :set_statuses, only: [:index]
before_action :set_thread, only: [:create] before_action :set_status, only: [:show, :context]
before_action :set_thread, only: [:create]
before_action :check_statuses_limit, only: [:index]
override_rate_limit_headers :create, family: :statuses override_rate_limit_headers :create, family: :statuses
override_rate_limit_headers :update, family: :statuses override_rate_limit_headers :update, family: :statuses
@ -23,6 +25,11 @@ class Api::V1::StatusesController < Api::BaseController
DESCENDANTS_LIMIT = 60 DESCENDANTS_LIMIT = 60
DESCENDANTS_DEPTH_LIMIT = 20 DESCENDANTS_DEPTH_LIMIT = 20
def index
@statuses = cache_collection(@statuses, Status)
render json: @statuses, each_serializer: REST::StatusSerializer
end
def show def show
cache_if_unauthenticated! cache_if_unauthenticated!
@status = cache_collection([@status], Status).first @status = cache_collection([@status], Status).first
@ -113,6 +120,10 @@ class Api::V1::StatusesController < Api::BaseController
private private
def set_statuses
@statuses = Status.permitted_statuses_from_ids(status_ids, current_account)
end
def set_status def set_status
@status = Status.find(params[:id]) @status = Status.find(params[:id])
authorize @status, :show? authorize @status, :show?
@ -127,6 +138,18 @@ class Api::V1::StatusesController < Api::BaseController
render json: { error: I18n.t('statuses.errors.in_reply_not_found') }, status: 404 render json: { error: I18n.t('statuses.errors.in_reply_not_found') }, status: 404
end end
def check_statuses_limit
raise(Mastodon::ValidationError) if status_ids.size > DEFAULT_STATUSES_LIMIT
end
def status_ids
Array(statuses_params[:ids]).uniq.map(&:to_i)
end
def statuses_params
params.permit(ids: [])
end
def status_params def status_params
params.permit( params.permit(
:status, :status,

View file

@ -19,6 +19,7 @@ class ApplicationController < ActionController::Base
helper_method :current_session helper_method :current_session
helper_method :current_flavour helper_method :current_flavour
helper_method :current_skin helper_method :current_skin
helper_method :current_theme
helper_method :single_user_mode? helper_method :single_user_mode?
helper_method :use_seamless_external_login? helper_method :use_seamless_external_login?
helper_method :omniauth_only? helper_method :omniauth_only?
@ -164,10 +165,7 @@ class ApplicationController < ActionController::Base
def respond_with_error(code) def respond_with_error(code)
respond_to do |format| respond_to do |format|
format.any do format.any { render "errors/#{code}", layout: 'error', status: code, formats: [:html] }
use_pack 'error'
render "errors/#{code}", layout: 'error', status: code, formats: [:html]
end
format.json { render json: { error: Rack::Utils::HTTP_STATUS_CODES[code] }, status: code } format.json { render json: { error: Rack::Utils::HTTP_STATUS_CODES[code] }, status: code }
end end
end end
@ -176,10 +174,7 @@ class ApplicationController < ActionController::Base
return unless self_destruct? return unless self_destruct?
respond_to do |format| respond_to do |format|
format.any do format.any { render 'errors/self_destruct', layout: 'auth', status: 410, formats: [:html] }
use_pack 'error'
render 'errors/self_destruct', layout: 'auth', status: 410, formats: [:html]
end
format.json { render json: { error: Rack::Utils::HTTP_STATUS_CODES[410] }, status: 410 } format.json { render json: { error: Rack::Utils::HTTP_STATUS_CODES[410] }, status: 410 }
end end
end end

View file

@ -5,7 +5,6 @@ class Auth::ChallengesController < ApplicationController
layout 'auth' layout 'auth'
before_action :set_pack
before_action :authenticate_user! before_action :authenticate_user!
skip_before_action :check_self_destruct! skip_before_action :check_self_destruct!
@ -21,10 +20,4 @@ class Auth::ChallengesController < ApplicationController
render_challenge render_challenge
end end
end end
private
def set_pack
use_pack 'auth'
end
end end

View file

@ -6,7 +6,6 @@ class Auth::ConfirmationsController < Devise::ConfirmationsController
layout 'auth' layout 'auth'
before_action :set_body_classes before_action :set_body_classes
before_action :set_pack
before_action :set_confirmation_user!, only: [:show, :confirm_captcha] before_action :set_confirmation_user!, only: [:show, :confirm_captcha]
before_action :redirect_confirmed_user, if: :signed_in_confirmed_user? before_action :redirect_confirmed_user, if: :signed_in_confirmed_user?
@ -66,10 +65,6 @@ class Auth::ConfirmationsController < Devise::ConfirmationsController
@confirmation_user.nil? || @confirmation_user.confirmed? @confirmation_user.nil? || @confirmation_user.confirmed?
end end
def set_pack
use_pack 'auth'
end
def redirect_confirmed_user def redirect_confirmed_user
redirect_to(current_user.approved? ? root_path : edit_user_registration_path) redirect_to(current_user.approved? ? root_path : edit_user_registration_path)
end end

View file

@ -3,7 +3,6 @@
class Auth::PasswordsController < Devise::PasswordsController class Auth::PasswordsController < Devise::PasswordsController
skip_before_action :check_self_destruct! skip_before_action :check_self_destruct!
before_action :redirect_invalid_reset_token, only: :edit, unless: :reset_password_token_is_valid? before_action :redirect_invalid_reset_token, only: :edit, unless: :reset_password_token_is_valid?
before_action :set_pack
before_action :set_body_classes before_action :set_body_classes
layout 'auth' layout 'auth'
@ -32,8 +31,4 @@ class Auth::PasswordsController < Devise::PasswordsController
def reset_password_token_is_valid? def reset_password_token_is_valid?
resource_class.with_reset_password_token(params[:reset_password_token]).present? resource_class.with_reset_password_token(params[:reset_password_token]).present?
end end
def set_pack
use_pack 'auth'
end
end end

View file

@ -9,7 +9,6 @@ class Auth::RegistrationsController < Devise::RegistrationsController
before_action :set_invite, only: [:new, :create] before_action :set_invite, only: [:new, :create]
before_action :check_enabled_registrations, only: [:new, :create] before_action :check_enabled_registrations, only: [:new, :create]
before_action :configure_sign_up_params, only: [:create] before_action :configure_sign_up_params, only: [:create]
before_action :set_pack
before_action :set_sessions, only: [:edit, :update] before_action :set_sessions, only: [:edit, :update]
before_action :set_strikes, only: [:edit, :update] before_action :set_strikes, only: [:edit, :update]
before_action :set_body_classes, only: [:new, :create, :edit, :update] before_action :set_body_classes, only: [:new, :create, :edit, :update]
@ -97,10 +96,6 @@ class Auth::RegistrationsController < Devise::RegistrationsController
private private
def set_pack
use_pack %w(edit update).include?(action_name) ? 'admin' : 'auth'
end
def set_body_classes def set_body_classes
@body_classes = %w(edit update).include?(action_name) ? 'admin' : 'lighter' @body_classes = %w(edit update).include?(action_name) ? 'admin' : 'lighter'
end end

View file

@ -12,7 +12,6 @@ class Auth::SessionsController < Devise::SessionsController
skip_before_action :require_functional! skip_before_action :require_functional!
skip_before_action :update_user_sign_in skip_before_action :update_user_sign_in
prepend_before_action :set_pack
prepend_before_action :check_suspicious!, only: [:create] prepend_before_action :check_suspicious!, only: [:create]
include Auth::TwoFactorAuthenticationConcern include Auth::TwoFactorAuthenticationConcern
@ -104,10 +103,6 @@ class Auth::SessionsController < Devise::SessionsController
private private
def set_pack
use_pack 'auth'
end
def set_body_classes def set_body_classes
@body_classes = 'lighter' @body_classes = 'lighter'
end end

View file

@ -3,7 +3,6 @@
class Auth::SetupController < ApplicationController class Auth::SetupController < ApplicationController
layout 'auth' layout 'auth'
before_action :set_pack
before_action :authenticate_user! before_action :authenticate_user!
before_action :require_unconfirmed_or_pending! before_action :require_unconfirmed_or_pending!
before_action :set_body_classes before_action :set_body_classes
@ -43,8 +42,4 @@ class Auth::SetupController < ApplicationController
def user_params def user_params
params.require(:user).permit(:email) params.require(:user).permit(:email)
end end
def set_pack
use_pack 'sign_up'
end
end end

View file

@ -0,0 +1,36 @@
# frozen_string_literal: true
module Api::Pagination
extend ActiveSupport::Concern
protected
def pagination_max_id
pagination_collection.last.id
end
def pagination_since_id
pagination_collection.first.id
end
def set_pagination_headers(next_path = nil, prev_path = nil)
links = []
links << [next_path, [%w(rel next)]] if next_path
links << [prev_path, [%w(rel prev)]] if prev_path
response.headers['Link'] = LinkHeader.new(links) unless links.empty?
end
def require_valid_pagination_options!
render json: { error: 'Pagination values for `offset` and `limit` must be positive' }, status: 400 if pagination_options_invalid?
end
private
def insert_pagination_headers
set_pagination_headers(next_path, prev_path)
end
def pagination_options_invalid?
params.slice(:limit, :offset).values.map(&:to_i).any?(&:negative?)
end
end

View file

@ -83,8 +83,6 @@ module Auth::TwoFactorAuthenticationConcern
def prompt_for_two_factor(user) def prompt_for_two_factor(user)
register_attempt_in_session(user) register_attempt_in_session(user)
use_pack 'auth'
@body_classes = 'lighter' @body_classes = 'lighter'
@webauthn_enabled = user.webauthn_enabled? @webauthn_enabled = user.webauthn_enabled?
@scheme_type = if user.webauthn_enabled? && user_params[:otp_attempt].blank? @scheme_type = if user.webauthn_enabled? && user_params[:otp_attempt].blank?

View file

@ -46,27 +46,19 @@ module CacheConcern
end end
end end
# TODO: Rename this method, as it does not perform any caching anymore.
def cache_collection(raw, klass) def cache_collection(raw, klass)
return raw unless klass.respond_to?(:with_includes) return raw unless klass.respond_to?(:preload_cacheable_associations)
raw = raw.cache_ids.to_a if raw.is_a?(ActiveRecord::Relation) records = raw.to_a
return [] if raw.empty?
cached_keys_with_value = Rails.cache.read_multi(*raw).transform_keys(&:id) klass.preload_cacheable_associations(records)
uncached_ids = raw.map(&:id) - cached_keys_with_value.keys records
klass.reload_stale_associations!(cached_keys_with_value.values) if klass.respond_to?(:reload_stale_associations!)
unless uncached_ids.empty?
uncached = klass.where(id: uncached_ids).with_includes.index_by(&:id)
Rails.cache.write_multi(uncached.values.to_h { |i| [i, i] })
end
raw.filter_map { |item| cached_keys_with_value[item.id] || uncached[item.id] }
end end
# TODO: Rename this method, as it does not perform any caching anymore.
def cache_collection_paginated_by_id(raw, klass, limit, options) def cache_collection_paginated_by_id(raw, klass, limit, options)
cache_collection raw.cache_ids.to_a_paginated_by_id(limit, options), klass cache_collection raw.to_a_paginated_by_id(limit, options), klass
end end
end end

View file

@ -66,7 +66,7 @@ module SignatureVerification
compare_signed_string = build_signed_string(include_query_string: false) compare_signed_string = build_signed_string(include_query_string: false)
return actor unless verify_signature(actor, signature, compare_signed_string).nil? return actor unless verify_signature(actor, signature, compare_signed_string).nil?
actor = stoplight_wrap_request { actor_refresh_key!(actor) } actor = stoplight_wrapper.run { actor_refresh_key!(actor) }
raise SignatureVerificationError, "Could not refresh public key #{signature_params['keyId']}" if actor.nil? raise SignatureVerificationError, "Could not refresh public key #{signature_params['keyId']}" if actor.nil?
@ -226,10 +226,10 @@ module SignatureVerification
end end
if key_id.start_with?('acct:') if key_id.start_with?('acct:')
stoplight_wrap_request { ResolveAccountService.new.call(key_id.delete_prefix('acct:'), suppress_errors: false) } stoplight_wrapper.run { ResolveAccountService.new.call(key_id.delete_prefix('acct:'), suppress_errors: false) }
elsif !ActivityPub::TagManager.instance.local_uri?(key_id) elsif !ActivityPub::TagManager.instance.local_uri?(key_id)
account = ActivityPub::TagManager.instance.uri_to_actor(key_id) account = ActivityPub::TagManager.instance.uri_to_actor(key_id)
account ||= stoplight_wrap_request { ActivityPub::FetchRemoteKeyService.new.call(key_id, suppress_errors: false) } account ||= stoplight_wrapper.run { ActivityPub::FetchRemoteKeyService.new.call(key_id, suppress_errors: false) }
account account
end end
rescue Mastodon::PrivateNetworkAddressError => e rescue Mastodon::PrivateNetworkAddressError => e
@ -238,12 +238,11 @@ module SignatureVerification
raise SignatureVerificationError, e.message raise SignatureVerificationError, e.message
end end
def stoplight_wrap_request(&block) def stoplight_wrapper
Stoplight("source:#{request.remote_ip}", &block) Stoplight("source:#{request.remote_ip}")
.with_threshold(1) .with_threshold(1)
.with_cool_off_time(5.minutes.seconds) .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) } .with_error_handler { |error, handle| error.is_a?(HTTP::Error) || error.is_a?(OpenSSL::SSL::SSLError) ? handle.call(error) : raise(error) }
.run
end end
def actor_refresh_key!(actor) def actor_refresh_key!(actor)

View file

@ -3,87 +3,22 @@
module ThemingConcern module ThemingConcern
extend ActiveSupport::Concern extend ActiveSupport::Concern
def use_pack(pack_name)
@core = resolve_pack_with_common(Themes.instance.core, pack_name)
@theme = resolve_pack_with_common(Themes.instance.flavour(current_flavour), pack_name, current_skin)
end
private private
def current_flavour def current_flavour
[current_user&.setting_flavour, Setting.flavour, 'glitch', 'vanilla'].find { |flavour| Themes.instance.flavours.include?(flavour) } @current_flavour ||= [current_user&.setting_flavour, Setting.flavour, 'glitch', 'vanilla'].find { |flavour| Themes.instance.flavours.include?(flavour) }
end end
def current_skin def current_skin
skins = Themes.instance.skins_for(current_flavour) @current_skin ||= begin
[current_user&.setting_skin, Setting.skin, 'default'].find { |skin| skins.include?(skin) } skins = Themes.instance.skins_for(current_flavour)
end [current_user&.setting_skin, Setting.skin, 'system', 'default'].find { |skin| skins.include?(skin) }
def valid_pack_data?(data, pack_name)
data['pack'].is_a?(Hash) && data['pack'][pack_name].present?
end
def nil_pack(data)
{
use_common: true,
flavour: data['name'],
pack: nil,
preload: nil,
skin: nil,
supported_locales: data['locales'],
}
end
def pack(data, pack_name, skin)
pack_data = {
use_common: true,
flavour: data['name'],
pack: pack_name,
preload: nil,
skin: nil,
supported_locales: data['locales'],
}
return pack_data unless data['pack'][pack_name].is_a?(Hash)
pack_data[:use_common] = false if data['pack'][pack_name]['use_common'] == false
pack_data[:pack] = nil unless data['pack'][pack_name]['filename']
preloads = data['pack'][pack_name]['preload']
pack_data[:preload] = [preloads] if preloads.is_a?(String)
pack_data[:preload] = preloads if preloads.is_a?(Array)
if skin != 'default' && data['skin'][skin]
pack_data[:skin] = skin if data['skin'][skin].include?(pack_name)
elsif data['pack'][pack_name]['stylesheet']
pack_data[:skin] = 'default'
end end
pack_data
end end
def resolve_pack(data, pack_name, skin) def current_theme
return pack(data, pack_name, skin) if valid_pack_data?(data, pack_name) # NOTE: this is slightly different from upstream, as it's a derived value used
return if data['name'].blank? # for the sole purpose of pointing to the appropriate stylesheet pack
[current_flavour, current_skin]
fallbacks = []
if data.key?('fallback')
fallbacks = data['fallback'] if data['fallback'].is_a?(Array)
fallbacks = [data['fallback']] if data['fallback'].is_a?(String)
elsif data['name'] != Setting.default_settings['flavour']
fallbacks = [Setting.default_settings['flavour']]
end
fallbacks.each do |fallback|
return resolve_pack(Themes.instance.flavour(fallback), pack_name, skin) if Themes.instance.flavour(fallback)
end
nil
end
def resolve_pack_with_common(data, pack_name, skin = 'default')
result = resolve_pack(data, pack_name, skin) || nil_pack(data)
result[:common] = resolve_pack(data, 'common', skin) if result.delete(:use_common)
result
end end
end end

View file

@ -7,7 +7,6 @@ module WebAppControllerConcern
vary_by 'Accept, Accept-Language, Cookie' vary_by 'Accept, Accept-Language, Cookie'
before_action :redirect_unauthenticated_to_permalinks! before_action :redirect_unauthenticated_to_permalinks!
before_action :set_pack
before_action :set_app_body_class before_action :set_app_body_class
end end
@ -37,8 +36,4 @@ module WebAppControllerConcern
end end
end end
end end
def set_pack
use_pack 'home'
end
end end

View file

@ -9,15 +9,10 @@ class Disputes::BaseController < ApplicationController
before_action :set_body_classes before_action :set_body_classes
before_action :authenticate_user! before_action :authenticate_user!
before_action :set_pack
before_action :set_cache_headers before_action :set_cache_headers
private private
def set_pack
use_pack 'admin'
end
def set_body_classes def set_body_classes
@body_classes = 'admin' @body_classes = 'admin'
end end

View file

@ -6,7 +6,6 @@ class Filters::StatusesController < ApplicationController
before_action :authenticate_user! before_action :authenticate_user!
before_action :set_filter before_action :set_filter
before_action :set_status_filters before_action :set_status_filters
before_action :set_pack
before_action :set_body_classes before_action :set_body_classes
before_action :set_cache_headers before_action :set_cache_headers
@ -27,10 +26,6 @@ class Filters::StatusesController < ApplicationController
private private
def set_pack
use_pack 'admin'
end
def set_filter def set_filter
@filter = current_account.custom_filters.find(params[:filter_id]) @filter = current_account.custom_filters.find(params[:filter_id])
end end

View file

@ -5,7 +5,6 @@ class FiltersController < ApplicationController
before_action :authenticate_user! before_action :authenticate_user!
before_action :set_filter, only: [:edit, :update, :destroy] before_action :set_filter, only: [:edit, :update, :destroy]
before_action :set_pack
before_action :set_body_classes before_action :set_body_classes
before_action :set_cache_headers before_action :set_cache_headers
@ -45,10 +44,6 @@ class FiltersController < ApplicationController
private private
def set_pack
use_pack 'settings'
end
def set_filter def set_filter
@filter = current_account.custom_filters.find(params[:id]) @filter = current_account.custom_filters.find(params[:id])
end end

View file

@ -6,7 +6,6 @@ class InvitesController < ApplicationController
layout 'admin' layout 'admin'
before_action :authenticate_user! before_action :authenticate_user!
before_action :set_pack
before_action :set_body_classes before_action :set_body_classes
before_action :set_cache_headers before_action :set_cache_headers
@ -40,10 +39,6 @@ class InvitesController < ApplicationController
private private
def set_pack
use_pack 'settings'
end
def invites def invites
current_user.invites.order(id: :desc) current_user.invites.order(id: :desc)
end end

View file

@ -10,7 +10,6 @@ class MediaController < ApplicationController
before_action :verify_permitted_status! before_action :verify_permitted_status!
before_action :check_playable, only: :player before_action :check_playable, only: :player
before_action :allow_iframing, only: :player before_action :allow_iframing, only: :player
before_action :set_pack, only: :player
content_security_policy only: :player do |policy| content_security_policy only: :player do |policy|
policy.frame_ancestors(false) policy.frame_ancestors(false)
@ -48,8 +47,4 @@ class MediaController < ApplicationController
def allow_iframing def allow_iframing
response.headers.delete('X-Frame-Options') response.headers.delete('X-Frame-Options')
end end
def set_pack
use_pack 'public'
end
end end

View file

@ -5,7 +5,6 @@ class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController
before_action :store_current_location before_action :store_current_location
before_action :authenticate_resource_owner! before_action :authenticate_resource_owner!
before_action :set_pack
before_action :set_cache_headers before_action :set_cache_headers
content_security_policy do |p| content_security_policy do |p|
@ -20,10 +19,6 @@ class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController
store_location_for(:user, request.url) store_location_for(:user, request.url)
end end
def set_pack
use_pack 'auth'
end
def render_success def render_success
if skip_authorization? || (matching_token? && !truthy_param?('force_login')) if skip_authorization? || (matching_token? && !truthy_param?('force_login'))
redirect_or_render authorize_response redirect_or_render authorize_response

View file

@ -5,7 +5,6 @@ class Oauth::AuthorizedApplicationsController < Doorkeeper::AuthorizedApplicatio
before_action :store_current_location before_action :store_current_location
before_action :authenticate_resource_owner! before_action :authenticate_resource_owner!
before_action :set_pack
before_action :require_not_suspended!, only: :destroy before_action :require_not_suspended!, only: :destroy
before_action :set_body_classes before_action :set_body_classes
before_action :set_cache_headers before_action :set_cache_headers
@ -31,10 +30,6 @@ class Oauth::AuthorizedApplicationsController < Doorkeeper::AuthorizedApplicatio
store_location_for(:user, request.url) store_location_for(:user, request.url)
end end
def set_pack
use_pack 'settings'
end
def require_not_suspended! def require_not_suspended!
forbidden if current_account.unavailable? forbidden if current_account.unavailable?
end end

View file

@ -3,7 +3,6 @@
class Redirect::BaseController < ApplicationController class Redirect::BaseController < ApplicationController
vary_by 'Accept-Language' vary_by 'Accept-Language'
before_action :set_pack
before_action :set_resource before_action :set_resource
before_action :set_app_body_class before_action :set_app_body_class
@ -22,8 +21,4 @@ class Redirect::BaseController < ApplicationController
def set_resource def set_resource
raise NotImplementedError raise NotImplementedError
end end
def set_pack
use_pack 'public'
end
end end

View file

@ -5,7 +5,6 @@ class RelationshipsController < ApplicationController
before_action :authenticate_user! before_action :authenticate_user!
before_action :set_accounts, only: :show before_action :set_accounts, only: :show
before_action :set_pack
before_action :set_relationships, only: :show before_action :set_relationships, only: :show
before_action :set_body_classes before_action :set_body_classes
before_action :set_cache_headers before_action :set_cache_headers
@ -73,10 +72,6 @@ class RelationshipsController < ApplicationController
@body_classes = 'admin' @body_classes = 'admin'
end end
def set_pack
use_pack 'admin'
end
def set_cache_headers def set_cache_headers
response.cache_control.replace(private: true, no_store: true) response.cache_control.replace(private: true, no_store: true)
end end

View file

@ -1,7 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
class Settings::BaseController < ApplicationController class Settings::BaseController < ApplicationController
before_action :set_pack
layout 'admin' layout 'admin'
before_action :authenticate_user! before_action :authenticate_user!
@ -10,10 +9,6 @@ class Settings::BaseController < ApplicationController
private private
def set_pack
use_pack 'settings'
end
def set_body_classes def set_body_classes
@body_classes = 'admin' @body_classes = 'admin'
end end

View file

@ -38,7 +38,7 @@ class Settings::FeaturedTagsController < Settings::BaseController
end end
def set_recently_used_tags def set_recently_used_tags
@recently_used_tags = Tag.recently_used(current_account).where.not(id: @featured_tags.map(&:id)).limit(10) @recently_used_tags = Tag.suggestions_for_account(current_account).limit(10)
end end
def featured_tag_params def featured_tag_params

View file

@ -31,7 +31,7 @@ class Settings::ImportsController < Settings::BaseController
def show; end def show; end
def failures def failures
@bulk_import = current_account.bulk_imports.where(state: :finished).find(params[:id]) @bulk_import = current_account.bulk_imports.state_finished.find(params[:id])
respond_to do |format| respond_to do |format|
format.csv do format.csv do
@ -92,7 +92,7 @@ class Settings::ImportsController < Settings::BaseController
end end
def set_bulk_import def set_bulk_import
@bulk_import = current_account.bulk_imports.where(state: :unconfirmed).find(params[:id]) @bulk_import = current_account.bulk_imports.state_unconfirmed.find(params[:id])
end end
def set_recent_imports def set_recent_imports

View file

@ -7,10 +7,4 @@ class Settings::LoginActivitiesController < Settings::BaseController
def index def index
@login_activities = LoginActivity.where(user: current_user).order(id: :desc).page(params[:page]) @login_activities = LoginActivity.where(user: current_user).order(id: :desc).page(params[:page])
end end
private
def set_pack
use_pack 'settings'
end
end end

View file

@ -85,10 +85,6 @@ module Settings
private private
def set_pack
use_pack 'auth'
end
def redirect_invalid_otp def redirect_invalid_otp
flash[:error] = t('webauthn_credentials.otp_required') flash[:error] = t('webauthn_credentials.otp_required')
redirect_to settings_two_factor_authentication_methods_path redirect_to settings_two_factor_authentication_methods_path

View file

@ -4,17 +4,12 @@ class SharesController < ApplicationController
layout 'modal' layout 'modal'
before_action :authenticate_user! before_action :authenticate_user!
before_action :set_pack
before_action :set_body_classes before_action :set_body_classes
def show; end def show; end
private private
def set_pack
use_pack 'share'
end
def set_body_classes def set_body_classes
@body_classes = 'modal-layout compose-standalone' @body_classes = 'modal-layout compose-standalone'
end end

View file

@ -6,7 +6,6 @@ class StatusesCleanupController < ApplicationController
before_action :authenticate_user! before_action :authenticate_user!
before_action :set_policy before_action :set_policy
before_action :set_body_classes before_action :set_body_classes
before_action :set_pack
before_action :set_cache_headers before_action :set_cache_headers
def show; end def show; end
@ -27,10 +26,6 @@ class StatusesCleanupController < ApplicationController
private private
def set_pack
use_pack 'settings'
end
def set_policy def set_policy
@policy = current_account.statuses_cleanup_policy || current_account.build_statuses_cleanup_policy(enabled: false) @policy = current_account.statuses_cleanup_policy || current_account.build_statuses_cleanup_policy(enabled: false)
end end

View file

@ -41,7 +41,6 @@ class StatusesController < ApplicationController
end end
def embed def embed
use_pack 'embed'
return not_found if @status.hidden? || @status.reblog? return not_found if @status.hidden? || @status.reblog?
expires_in 180, public: true expires_in 180, public: true

View file

@ -0,0 +1,23 @@
# frozen_string_literal: true
module WellKnown
class OauthMetadataController < ActionController::Base # rubocop:disable Rails/ApplicationController
include CacheConcern
# Prevent `active_model_serializer`'s `ActionController::Serialization` from calling `current_user`
# and thus re-issuing session cookies
serialization_scope nil
def show
# Due to this document potentially changing between Mastodon versions (as
# new OAuth scopes are added), we don't use expires_in to cache upstream,
# instead just caching in the rails cache:
render_with_cache(
json: ::OauthMetadataPresenter.new,
serializer: ::OauthMetadataSerializer,
content_type: 'application/json',
expires_in: 15.minutes
)
end
end
end

View file

@ -113,6 +113,14 @@ module ApplicationHelper
content_tag(:i, nil, attributes.merge(class: class_names.join(' '))) content_tag(:i, nil, attributes.merge(class: class_names.join(' ')))
end end
def material_symbol(icon, attributes = {})
inline_svg_tag(
"400-24px/#{icon}.svg",
class: %w(icon).concat(attributes[:class].to_s.split),
role: :img
)
end
def check_icon def check_icon
inline_svg_tag 'check.svg' inline_svg_tag 'check.svg'
end end
@ -233,6 +241,32 @@ module ApplicationHelper
EmojiFormatter.new(html, custom_emojis, other_options.merge(animate: prefers_autoplay?)).to_s EmojiFormatter.new(html, custom_emojis, other_options.merge(animate: prefers_autoplay?)).to_s
end end
def site_icon_path(type, size = '48')
icon = SiteUpload.find_by(var: type)
return nil unless icon
icon.file.url(size)
end
# glitch-soc addition to handle the multiple flavors
def preload_locale_pack
supported_locales = Themes.instance.flavour(current_flavour)['locales']
preload_pack_asset "locales/#{current_flavour}/#{I18n.locale}-json.js" if supported_locales.include?(I18n.locale.to_s)
end
def flavoured_javascript_pack_tag(pack_name, **options)
javascript_pack_tag("flavours/#{current_flavour}/#{pack_name}", **options)
end
def flavoured_stylesheet_pack_tag(pack_name, **options)
stylesheet_pack_tag("flavours/#{current_flavour}/#{pack_name}", **options)
end
def preload_signed_in_js_packs
preload_files = Themes.instance.flavour(current_flavour)&.fetch('signed_in_preload', nil) || []
safe_join(preload_files.map { |entry| preload_pack_asset entry })
end
private private
def storage_host_var def storage_host_var

View file

@ -19,6 +19,6 @@ module BrandingHelper
end end
def render_logo def render_logo
image_pack_tag('logo.svg', alt: 'Mastodon', class: 'logo logo--icon') image_tag(frontend_asset_path('images/logo.svg'), alt: 'Mastodon', class: 'logo logo--icon')
end end
end end

View file

@ -49,13 +49,11 @@ module ContextHelper
end end
def serialized_context(named_contexts_map, context_extensions_map) def serialized_context(named_contexts_map, context_extensions_map)
context_array = []
named_contexts = named_contexts_map.keys named_contexts = named_contexts_map.keys
context_extensions = context_extensions_map.keys context_extensions = context_extensions_map.keys
named_contexts.each do |key| context_array = named_contexts.map do |key|
context_array << NAMED_CONTEXT_MAP[key] NAMED_CONTEXT_MAP[key]
end end
extensions = context_extensions.each_with_object({}) do |key, h| extensions = context_extensions.each_with_object({}) do |key, h|

View file

@ -0,0 +1,31 @@
# frozen_string_literal: true
module ThemeHelper
def theme_style_tags(flavour_and_skin)
flavour, theme = flavour_and_skin
if theme == 'system'
stylesheet_pack_tag("skins/#{flavour}/mastodon-light", media: 'not all and (prefers-color-scheme: dark)', crossorigin: 'anonymous') +
stylesheet_pack_tag("skins/#{flavour}/default", media: '(prefers-color-scheme: dark)', crossorigin: 'anonymous')
else
stylesheet_pack_tag "skins/#{flavour}/#{theme}", media: 'all', crossorigin: 'anonymous'
end
end
def theme_color_tags(flavour_and_skin)
_, theme = flavour_and_skin
if theme == 'system'
tag.meta(name: 'theme-color', content: Themes::THEME_COLORS[:dark], media: '(prefers-color-scheme: dark)') +
tag.meta(name: 'theme-color', content: Themes::THEME_COLORS[:light], media: '(prefers-color-scheme: light)')
else
tag.meta name: 'theme-color', content: theme_color_for(theme)
end
end
private
def theme_color_for(theme)
theme == 'mastodon-light' ? Themes::THEME_COLORS[:light] : Themes::THEME_COLORS[:dark]
end
end

View file

@ -1,3 +0,0 @@
import 'packs/public-path';
import './settings';
import './two_factor_authentication';

View file

@ -1,6 +0,0 @@
// This file will be loaded on all pages, regardless of theme.
import 'packs/public-path';
import 'font-awesome/css/font-awesome.css';
require.context('../images/', true);

View file

@ -1,41 +0,0 @@
// This file will be loaded on embed pages, regardless of theme.
import 'packs/public-path';
import ready from '../mastodon/ready';
interface SetHeightMessage {
type: 'setHeight';
id: string;
height: number;
}
function isSetHeightMessage(data: unknown): data is SetHeightMessage {
if (
data &&
typeof data === 'object' &&
'type' in data &&
data.type === 'setHeight'
)
return true;
else return false;
}
window.addEventListener('message', (e) => {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- typings are not correct, it can be null in very rare cases
if (!e.data || !isSetHeightMessage(e.data) || !window.parent) return;
const data = e.data;
ready(() => {
window.parent.postMessage(
{
type: 'setHeight',
id: data.id,
height: document.getElementsByTagName('html')[0].scrollHeight,
},
'*',
);
}).catch((e) => {
console.error('Error in setHeightMessage postMessage', e);
});
});

View file

@ -1,70 +0,0 @@
// This file will be loaded on settings pages, regardless of theme.
import 'packs/public-path';
import Rails from '@rails/ujs';
Rails.delegate(
document,
'#edit_profile input[type=file]',
'change',
({ target }) => {
if (!(target instanceof HTMLInputElement)) return;
const avatar = document.querySelector<HTMLImageElement>(
`img#${target.id}-preview`,
);
if (!avatar) return;
let file: File | undefined;
if (target.files) file = target.files[0];
const url = file ? URL.createObjectURL(file) : avatar.dataset.originalSrc;
if (url) avatar.src = url;
},
);
Rails.delegate(document, '.input-copy input', 'click', ({ target }) => {
if (!(target instanceof HTMLInputElement)) return;
target.focus();
target.select();
target.setSelectionRange(0, target.value.length);
});
Rails.delegate(document, '.input-copy button', 'click', ({ target }) => {
if (!(target instanceof HTMLButtonElement)) return;
const input = target.parentNode?.querySelector<HTMLInputElement>(
'.input-copy__wrapper input',
);
if (!input) return;
const oldReadOnly = input.readOnly;
input.readOnly = false;
input.focus();
input.select();
input.setSelectionRange(0, input.value.length);
try {
if (document.execCommand('copy')) {
input.blur();
const parent = target.parentElement;
if (!parent) return;
parent.classList.add('copied');
setTimeout(() => {
parent.classList.remove('copied');
}, 700);
}
} catch (err) {
console.error(err);
}
input.readOnly = oldReadOnly;
});

View file

@ -1,24 +0,0 @@
# These packs will be loaded on every appropriate page, regardless of
# theme.
pack:
about:
admin: admin.ts
auth: auth.js
common:
filename: common.js
stylesheet: true
embed: embed.ts
error:
home:
inert:
filename: inert.js
stylesheet: true
mailer:
filename: mailer.js
stylesheet: true
modal:
public:
settings: settings.ts
sign_up:
share:
remote_interaction_helper: remote_interaction_helper.ts

View file

@ -1,121 +0,0 @@
import 'packs/public-path';
import * as WebAuthnJSON from '@github/webauthn-json';
import axios from 'axios';
import ready from '../mastodon/ready';
import 'regenerator-runtime/runtime';
function getCSRFToken() {
var CSRFSelector = document.querySelector('meta[name="csrf-token"]');
if (CSRFSelector) {
return CSRFSelector.getAttribute('content');
} else {
return null;
}
}
function hideFlashMessages() {
Array.from(document.getElementsByClassName('flash-message')).forEach(function(flashMessage) {
flashMessage.classList.add('hidden');
});
}
function callback(url, body) {
axios.post(url, JSON.stringify(body), {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'X-CSRF-Token': getCSRFToken(),
},
credentials: 'same-origin',
}).then(function(response) {
window.location.replace(response.data.redirect_path);
}).catch(function(error) {
if (error.response.status === 422) {
const errorMessage = document.getElementById('security-key-error-message');
errorMessage.classList.remove('hidden');
console.error(error.response.data.error);
} else {
console.error(error);
}
});
}
ready(() => {
if (!WebAuthnJSON.supported()) {
const unsupported_browser_message = document.getElementById('unsupported-browser-message');
if (unsupported_browser_message) {
unsupported_browser_message.classList.remove('hidden');
document.querySelector('.btn.js-webauthn').disabled = true;
}
}
const webAuthnCredentialRegistrationForm = document.getElementById('new_webauthn_credential');
if (webAuthnCredentialRegistrationForm) {
webAuthnCredentialRegistrationForm.addEventListener('submit', (event) => {
event.preventDefault();
var nickname = event.target.querySelector('input[name="new_webauthn_credential[nickname]"]');
if (nickname.value) {
axios.get('/settings/security_keys/options')
.then((response) => {
const credentialOptions = response.data;
WebAuthnJSON.create({ 'publicKey': credentialOptions }).then((credential) => {
var params = { 'credential': credential, 'nickname': nickname.value };
callback('/settings/security_keys', params);
}).catch((error) => {
const errorMessage = document.getElementById('security-key-error-message');
errorMessage.classList.remove('hidden');
console.error(error);
});
}).catch((error) => {
console.error(error.response.data.error);
});
} else {
nickname.focus();
}
});
}
const webAuthnCredentialAuthenticationForm = document.getElementById('webauthn-form');
if (webAuthnCredentialAuthenticationForm) {
webAuthnCredentialAuthenticationForm.addEventListener('submit', (event) => {
event.preventDefault();
axios.get('sessions/security_key_options')
.then((response) => {
const credentialOptions = response.data;
WebAuthnJSON.get({ 'publicKey': credentialOptions }).then((credential) => {
var params = { 'user': { 'credential': credential } };
callback('sign_in', params);
}).catch((error) => {
const errorMessage = document.getElementById('security-key-error-message');
errorMessage.classList.remove('hidden');
console.error(error);
});
}).catch((error) => {
console.error(error.response.data.error);
});
});
const otpAuthenticationForm = document.getElementById('otp-authentication-form');
const linkToOtp = document.getElementById('link-to-otp');
linkToOtp.addEventListener('click', () => {
webAuthnCredentialAuthenticationForm.classList.add('hidden');
otpAuthenticationForm.classList.remove('hidden');
hideFlashMessages();
});
const linkToWebAuthn = document.getElementById('link-to-webauthn');
linkToWebAuthn.addEventListener('click', () => {
otpAuthenticationForm.classList.add('hidden');
webAuthnCredentialAuthenticationForm.classList.remove('hidden');
hideFlashMessages();
});
}
});

View file

@ -1,6 +1,5 @@
// This file will be loaded on admin pages, regardless of theme. import './public-path';
import { createRoot } from 'react-dom/client';
import 'packs/public-path';
import Rails from '@rails/ujs'; import Rails from '@rails/ujs';
@ -261,6 +260,31 @@ Rails.delegate(
}, },
); );
async function mountReactComponent(element: Element) {
const componentName = element.getAttribute('data-admin-component');
const stringProps = element.getAttribute('data-props');
if (!stringProps) return;
const componentProps = JSON.parse(stringProps) as object;
const { default: AdminComponent } = await import(
'@/mastodon/containers/admin_component'
);
const { default: Component } = (await import(
`@/mastodon/components/admin/${componentName}`
)) as { default: React.ComponentType };
const root = createRoot(element);
root.render(
<AdminComponent>
<Component {...componentProps} />
</AdminComponent>,
);
}
ready(() => { ready(() => {
const domainBlockSeveritySelect = document.querySelector<HTMLSelectElement>( const domainBlockSeveritySelect = document.querySelector<HTMLSelectElement>(
'select#domain_block_severity', 'select#domain_block_severity',
@ -335,6 +359,10 @@ ready(() => {
if (announcementStartsAt) { if (announcementStartsAt) {
setAnnouncementEndsAttributes(announcementStartsAt); setAnnouncementEndsAttributes(announcementStartsAt);
} }
}).catch((reason) => {
document.querySelectorAll('[data-admin-component]').forEach((element) => {
void mountReactComponent(element);
});
}).catch((reason: unknown) => {
throw reason; throw reason;
}); });

View file

@ -1,5 +1,5 @@
import './public-path'; import './public-path';
import main from "mastodon/main"; import main from 'mastodon/main';
import { start } from '../mastodon/common'; import { start } from '../mastodon/common';
import { loadLocale } from '../mastodon/locales'; import { loadLocale } from '../mastodon/locales';
@ -10,6 +10,6 @@ start();
loadPolyfills() loadPolyfills()
.then(loadLocale) .then(loadLocale)
.then(main) .then(main)
.catch(e => { .catch((e: unknown) => {
console.error(e); console.error(e);
}); });

View file

@ -0,0 +1,5 @@
/* This file is a hack to have something more reliable than the upstream `common` tag
that is implicitly generated as the common chunk through webpack's `splitChunks` config */
import './public-path';
import 'font-awesome/css/font-awesome.css';

View file

@ -2,7 +2,9 @@ import './public-path';
import ready from '../mastodon/ready'; import ready from '../mastodon/ready';
ready(() => { ready(() => {
const image = document.querySelector('img'); const image = document.querySelector<HTMLImageElement>('img');
if (!image) return;
image.addEventListener('mouseenter', () => { image.addEventListener('mouseenter', () => {
image.src = '/oops.gif'; image.src = '/oops.gif';
@ -11,4 +13,6 @@ ready(() => {
image.addEventListener('mouseleave', () => { image.addEventListener('mouseleave', () => {
image.src = '/oops.png'; image.src = '/oops.png';
}); });
}).catch((e: unknown) => {
console.error(e);
}); });

View file

@ -2,7 +2,7 @@
// to share the same assets regardless of instance configuration. // to share the same assets regardless of instance configuration.
// See https://webpack.js.org/guides/public-path/#on-the-fly // See https://webpack.js.org/guides/public-path/#on-the-fly
function removeOuterSlashes(string) { function removeOuterSlashes(string: string) {
return string.replace(/^\/*/, '').replace(/\/*$/, ''); return string.replace(/^\/*/, '').replace(/\/*$/, '');
} }
@ -15,7 +15,9 @@ function formatPublicPath(host = '', path = '') {
return `${formattedHost}/${formattedPath}/`; return `${formattedHost}/${formattedPath}/`;
} }
const cdnHost = document.querySelector('meta[name=cdn-host]'); const cdnHost = document.querySelector<HTMLMetaElement>('meta[name=cdn-host]');
// eslint-disable-next-line no-undef __webpack_public_path__ = formatPublicPath(
__webpack_public_path__ = formatPublicPath(cdnHost ? cdnHost.content : '', process.env.PUBLIC_OUTPUT_PATH); cdnHost ? cdnHost.content : '',
process.env.PUBLIC_OUTPUT_PATH,
);

View file

@ -37,6 +37,43 @@ const messages = defineMessages({
}, },
}); });
interface SetHeightMessage {
type: 'setHeight';
id: string;
height: number;
}
function isSetHeightMessage(data: unknown): data is SetHeightMessage {
if (
data &&
typeof data === 'object' &&
'type' in data &&
data.type === 'setHeight'
)
return true;
else return false;
}
window.addEventListener('message', (e) => {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- typings are not correct, it can be null in very rare cases
if (!e.data || !isSetHeightMessage(e.data) || !window.parent) return;
const data = e.data;
ready(() => {
window.parent.postMessage(
{
type: 'setHeight',
id: data.id,
height: document.getElementsByTagName('html')[0].scrollHeight,
},
'*',
);
}).catch((e: unknown) => {
console.error('Error in setHeightMessage postMessage', e);
});
});
function loaded() { function loaded() {
const { messages: localeData } = getLocale(); const { messages: localeData } = getLocale();
@ -169,7 +206,7 @@ function loaded() {
return true; return true;
}) })
.catch((error) => { .catch((error: unknown) => {
console.error(error); console.error(error);
}); });
} }
@ -288,6 +325,72 @@ function loaded() {
}); });
} }
Rails.delegate(
document,
'#edit_profile input[type=file]',
'change',
({ target }) => {
if (!(target instanceof HTMLInputElement)) return;
const avatar = document.querySelector<HTMLImageElement>(
`img#${target.id}-preview`,
);
if (!avatar) return;
let file: File | undefined;
if (target.files) file = target.files[0];
const url = file ? URL.createObjectURL(file) : avatar.dataset.originalSrc;
if (url) avatar.src = url;
},
);
Rails.delegate(document, '.input-copy input', 'click', ({ target }) => {
if (!(target instanceof HTMLInputElement)) return;
target.focus();
target.select();
target.setSelectionRange(0, target.value.length);
});
Rails.delegate(document, '.input-copy button', 'click', ({ target }) => {
if (!(target instanceof HTMLButtonElement)) return;
const input = target.parentNode?.querySelector<HTMLInputElement>(
'.input-copy__wrapper input',
);
if (!input) return;
const oldReadOnly = input.readOnly;
input.readOnly = false;
input.focus();
input.select();
input.setSelectionRange(0, input.value.length);
try {
if (document.execCommand('copy')) {
input.blur();
const parent = target.parentElement;
if (!parent) return;
parent.classList.add('copied');
setTimeout(() => {
parent.classList.remove('copied');
}, 700);
}
} catch (err) {
console.error(err);
}
input.readOnly = oldReadOnly;
});
const toggleSidebar = () => { const toggleSidebar = () => {
const sidebar = document.querySelector<HTMLUListElement>('.sidebar ul'); const sidebar = document.querySelector<HTMLUListElement>('.sidebar ul');
const toggleButton = document.querySelector<HTMLAnchorElement>( const toggleButton = document.querySelector<HTMLAnchorElement>(
@ -345,7 +448,7 @@ Rails.delegate(document, '#registration_new_user,#new_user', 'submit', () => {
}); });
function main() { function main() {
ready(loaded).catch((error) => { ready(loaded).catch((error: unknown) => {
console.error(error); console.error(error);
}); });
} }
@ -354,6 +457,6 @@ loadPolyfills()
.then(loadLocale) .then(loadLocale)
.then(main) .then(main)
.then(loadKeyboardExtensions) .then(loadKeyboardExtensions)
.catch((error) => { .catch((error: unknown) => {
console.error(error); console.error(error);
}); });

View file

@ -8,7 +8,7 @@ and performs no other task.
*/ */
import 'packs/public-path'; import './public-path';
import axios from 'axios'; import axios from 'axios';

View file

@ -2,7 +2,7 @@ import './public-path';
import { createRoot } from 'react-dom/client'; import { createRoot } from 'react-dom/client';
import { start } from '../mastodon/common'; import { start } from '../mastodon/common';
import ComposeContainer from '../mastodon/containers/compose_container'; import ComposeContainer from '../mastodon/containers/compose_container';
import { loadPolyfills } from '../mastodon/polyfills'; import { loadPolyfills } from '../mastodon/polyfills';
import ready from '../mastodon/ready'; import ready from '../mastodon/ready';
@ -16,7 +16,7 @@ function loaded() {
if (!attr) return; if (!attr) return;
const props = JSON.parse(attr); const props = JSON.parse(attr) as object;
const root = createRoot(mountNode); const root = createRoot(mountNode);
root.render(<ComposeContainer {...props} />); root.render(<ComposeContainer {...props} />);
@ -24,9 +24,13 @@ function loaded() {
} }
function main() { function main() {
ready(loaded); ready(loaded).catch((error: unknown) => {
console.error(error);
});
} }
loadPolyfills().then(main).catch(error => { loadPolyfills()
console.error(error); .then(main)
}); .catch((error: unknown) => {
console.error(error);
});

View file

@ -0,0 +1,48 @@
import './public-path';
import axios from 'axios';
import ready from '../mastodon/ready';
async function checkConfirmation() {
const response = await axios.get('/api/v1/emails/check_confirmation');
if (response.data) {
window.location.href = '/start';
}
}
ready(() => {
setInterval(() => {
void checkConfirmation();
}, 5000);
document
.querySelectorAll<HTMLButtonElement>('button.timer-button')
.forEach((button) => {
let counter = 30;
const container = document.createElement('span');
const updateCounter = () => {
container.innerText = ` (${counter})`;
};
updateCounter();
const countdown = setInterval(() => {
counter--;
if (counter === 0) {
button.disabled = false;
button.removeChild(container);
clearInterval(countdown);
} else {
updateCounter();
}
}, 1000);
button.appendChild(container);
});
}).catch((e: unknown) => {
throw e;
});

View file

@ -0,0 +1,197 @@
import * as WebAuthnJSON from '@github/webauthn-json';
import axios, { AxiosError } from 'axios';
import ready from '../mastodon/ready';
import 'regenerator-runtime/runtime';
type PublicKeyCredentialCreationOptionsJSON =
WebAuthnJSON.CredentialCreationOptionsJSON['publicKey'];
function exceptionHasAxiosError(
error: unknown,
): error is AxiosError<{ error: unknown }> {
return (
error instanceof AxiosError &&
typeof error.response?.data === 'object' &&
'error' in error.response.data
);
}
function logAxiosResponseError(error: unknown) {
if (exceptionHasAxiosError(error)) console.error(error);
}
function getCSRFToken() {
return document
.querySelector<HTMLMetaElement>('meta[name="csrf-token"]')
?.getAttribute('content');
}
function hideFlashMessages() {
document.querySelectorAll('.flash-message').forEach((flashMessage) => {
flashMessage.classList.add('hidden');
});
}
async function callback(
url: string,
body:
| {
credential: WebAuthnJSON.PublicKeyCredentialWithAttestationJSON;
nickname: string;
}
| {
user: { credential: WebAuthnJSON.PublicKeyCredentialWithAssertionJSON };
},
) {
try {
const response = await axios.post<{ redirect_path: string }>(
url,
JSON.stringify(body),
{
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
'X-CSRF-Token': getCSRFToken(),
},
},
);
window.location.replace(response.data.redirect_path);
} catch (error) {
if (error instanceof AxiosError && error.response?.status === 422) {
const errorMessage = document.getElementById(
'security-key-error-message',
);
errorMessage?.classList.remove('hidden');
logAxiosResponseError(error);
} else {
console.error(error);
}
}
}
async function handleWebauthnCredentialRegistration(nickname: string) {
try {
const response = await axios.get<PublicKeyCredentialCreationOptionsJSON>(
'/settings/security_keys/options',
);
const credentialOptions = response.data;
try {
const credential = await WebAuthnJSON.create({
publicKey: credentialOptions,
});
const params = {
credential: credential,
nickname: nickname,
};
await callback('/settings/security_keys', params);
} catch (error) {
const errorMessage = document.getElementById(
'security-key-error-message',
);
errorMessage?.classList.remove('hidden');
console.error(error);
}
} catch (error) {
logAxiosResponseError(error);
}
}
async function handleWebauthnCredentialAuthentication() {
try {
const response = await axios.get<PublicKeyCredentialCreationOptionsJSON>(
'sessions/security_key_options',
);
const credentialOptions = response.data;
try {
const credential = await WebAuthnJSON.get({
publicKey: credentialOptions,
});
const params = { user: { credential: credential } };
void callback('sign_in', params);
} catch (error) {
const errorMessage = document.getElementById(
'security-key-error-message',
);
errorMessage?.classList.remove('hidden');
console.error(error);
}
} catch (error) {
logAxiosResponseError(error);
}
}
ready(() => {
if (!WebAuthnJSON.supported()) {
const unsupported_browser_message = document.getElementById(
'unsupported-browser-message',
);
if (unsupported_browser_message) {
unsupported_browser_message.classList.remove('hidden');
const button = document.querySelector<HTMLButtonElement>(
'button.btn.js-webauthn',
);
if (button) button.disabled = true;
}
}
const webAuthnCredentialRegistrationForm =
document.querySelector<HTMLFormElement>('form#new_webauthn_credential');
if (webAuthnCredentialRegistrationForm) {
webAuthnCredentialRegistrationForm.addEventListener('submit', (event) => {
event.preventDefault();
if (!(event.target instanceof HTMLFormElement)) return;
const nickname = event.target.querySelector<HTMLInputElement>(
'input[name="new_webauthn_credential[nickname]"]',
);
if (nickname?.value) {
void handleWebauthnCredentialRegistration(nickname.value);
} else {
nickname?.focus();
}
});
}
const webAuthnCredentialAuthenticationForm =
document.getElementById('webauthn-form');
if (webAuthnCredentialAuthenticationForm) {
webAuthnCredentialAuthenticationForm.addEventListener('submit', (event) => {
event.preventDefault();
void handleWebauthnCredentialAuthentication();
});
const otpAuthenticationForm = document.getElementById(
'otp-authentication-form',
);
const linkToOtp = document.getElementById('link-to-otp');
linkToOtp?.addEventListener('click', () => {
webAuthnCredentialAuthenticationForm.classList.add('hidden');
otpAuthenticationForm?.classList.remove('hidden');
hideFlashMessages();
});
const linkToWebAuthn = document.getElementById('link-to-webauthn');
linkToWebAuthn?.addEventListener('click', () => {
otpAuthenticationForm?.classList.add('hidden');
webAuthnCredentialAuthenticationForm.classList.remove('hidden');
hideFlashMessages();
});
}
}).catch((e: unknown) => {
throw e;
});

View file

@ -1,32 +0,0 @@
import { openModal } from './modal';
export const BOOSTS_INIT_MODAL = 'BOOSTS_INIT_MODAL';
export const BOOSTS_CHANGE_PRIVACY = 'BOOSTS_CHANGE_PRIVACY';
export function initBoostModal(props) {
return (dispatch, getState) => {
const default_privacy = getState().getIn(['compose', 'default_privacy']);
const privacy = props.status.get('visibility') === 'private' ? 'private' : default_privacy;
dispatch({
type: BOOSTS_INIT_MODAL,
privacy,
});
dispatch(openModal({
modalType: 'BOOST',
modalProps: props,
}));
};
}
export function changeBoostPrivacy(privacy) {
return dispatch => {
dispatch({
type: BOOSTS_CHANGE_PRIVACY,
privacy,
});
};
}

View file

@ -1,152 +0,0 @@
import { List as ImmutableList } from 'immutable';
import { debounce } from 'lodash';
import api from '../api';
import { compareId } from '../compare_id';
export const MARKERS_FETCH_REQUEST = 'MARKERS_FETCH_REQUEST';
export const MARKERS_FETCH_SUCCESS = 'MARKERS_FETCH_SUCCESS';
export const MARKERS_FETCH_FAIL = 'MARKERS_FETCH_FAIL';
export const MARKERS_SUBMIT_SUCCESS = 'MARKERS_SUBMIT_SUCCESS';
export const synchronouslySubmitMarkers = () => (dispatch, getState) => {
const accessToken = getState().getIn(['meta', 'access_token'], '');
const params = _buildParams(getState());
if (Object.keys(params).length === 0 || accessToken === '') {
return;
}
// The Fetch API allows us to perform requests that will be carried out
// after the page closes. But that only works if the `keepalive` attribute
// is supported.
if (window.fetch && 'keepalive' in new Request('')) {
fetch('/api/v1/markers', {
keepalive: true,
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${accessToken}`,
},
body: JSON.stringify(params),
});
return;
} else if (navigator && navigator.sendBeacon) {
// Failing that, we can use sendBeacon, but we have to encode the data as
// FormData for DoorKeeper to recognize the token.
const formData = new FormData();
formData.append('bearer_token', accessToken);
for (const [id, value] of Object.entries(params)) {
formData.append(`${id}[last_read_id]`, value.last_read_id);
}
if (navigator.sendBeacon('/api/v1/markers', formData)) {
return;
}
}
// If neither Fetch nor sendBeacon worked, try to perform a synchronous
// request.
try {
const client = new XMLHttpRequest();
client.open('POST', '/api/v1/markers', false);
client.setRequestHeader('Content-Type', 'application/json');
client.setRequestHeader('Authorization', `Bearer ${accessToken}`);
client.send(JSON.stringify(params));
} catch (e) {
// Do not make the BeforeUnload handler error out
}
};
const _buildParams = (state) => {
const params = {};
const lastHomeId = state.getIn(['timelines', 'home', 'items'], ImmutableList()).find(item => item !== null);
const lastNotificationId = state.getIn(['notifications', 'lastReadId']);
if (lastHomeId && compareId(lastHomeId, state.getIn(['markers', 'home'])) > 0) {
params.home = {
last_read_id: lastHomeId,
};
}
if (lastNotificationId && lastNotificationId !== '0' && compareId(lastNotificationId, state.getIn(['markers', 'notifications'])) > 0) {
params.notifications = {
last_read_id: lastNotificationId,
};
}
return params;
};
const debouncedSubmitMarkers = debounce((dispatch, getState) => {
const accessToken = getState().getIn(['meta', 'access_token'], '');
const params = _buildParams(getState());
if (Object.keys(params).length === 0 || accessToken === '') {
return;
}
api(getState).post('/api/v1/markers', params).then(() => {
dispatch(submitMarkersSuccess(params));
}).catch(() => {});
}, 300000, { leading: true, trailing: true });
export function submitMarkersSuccess({ home, notifications }) {
return {
type: MARKERS_SUBMIT_SUCCESS,
home: (home || {}).last_read_id,
notifications: (notifications || {}).last_read_id,
};
}
export function submitMarkers(params = {}) {
const result = (dispatch, getState) => debouncedSubmitMarkers(dispatch, getState);
if (params.immediate === true) {
debouncedSubmitMarkers.flush();
}
return result;
}
export const fetchMarkers = () => (dispatch, getState) => {
const params = { timeline: ['notifications'] };
dispatch(fetchMarkersRequest());
api(getState).get('/api/v1/markers', { params }).then(response => {
dispatch(fetchMarkersSuccess(response.data));
}).catch(error => {
dispatch(fetchMarkersFail(error));
});
};
export function fetchMarkersRequest() {
return {
type: MARKERS_FETCH_REQUEST,
skipLoading: true,
};
}
export function fetchMarkersSuccess(markers) {
return {
type: MARKERS_FETCH_SUCCESS,
markers,
skipLoading: true,
};
}
export function fetchMarkersFail(error) {
return {
type: MARKERS_FETCH_FAIL,
error,
skipLoading: true,
skipAlert: true,
};
}

View file

@ -0,0 +1,147 @@
import { debounce } from 'lodash';
import type { MarkerJSON } from 'flavours/glitch/api_types/markers';
import type { AppDispatch, RootState } from 'flavours/glitch/store';
import { createAppAsyncThunk } from 'flavours/glitch/store/typed_functions';
import api, { authorizationTokenFromState } from '../api';
import { compareId } from '../compare_id';
export const synchronouslySubmitMarkers = createAppAsyncThunk(
'markers/submit',
async (_args, { getState }) => {
const accessToken = authorizationTokenFromState(getState);
const params = buildPostMarkersParams(getState());
if (Object.keys(params).length === 0 || !accessToken) {
return;
}
// The Fetch API allows us to perform requests that will be carried out
// after the page closes. But that only works if the `keepalive` attribute
// is supported.
if ('fetch' in window && 'keepalive' in new Request('')) {
await fetch('/api/v1/markers', {
keepalive: true,
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${accessToken}`,
},
body: JSON.stringify(params),
});
return;
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
} else if ('navigator' && 'sendBeacon' in navigator) {
// Failing that, we can use sendBeacon, but we have to encode the data as
// FormData for DoorKeeper to recognize the token.
const formData = new FormData();
formData.append('bearer_token', accessToken);
for (const [id, value] of Object.entries(params)) {
if (value.last_read_id)
formData.append(`${id}[last_read_id]`, value.last_read_id);
}
if (navigator.sendBeacon('/api/v1/markers', formData)) {
return;
}
}
// If neither Fetch nor sendBeacon worked, try to perform a synchronous
// request.
try {
const client = new XMLHttpRequest();
client.open('POST', '/api/v1/markers', false);
client.setRequestHeader('Content-Type', 'application/json');
client.setRequestHeader('Authorization', `Bearer ${accessToken}`);
client.send(JSON.stringify(params));
} catch (e) {
// Do not make the BeforeUnload handler error out
}
},
);
interface MarkerParam {
last_read_id?: string;
}
function getLastNotificationId(state: RootState): string | undefined {
// @ts-expect-error state.notifications is not yet typed
// eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call
return state.getIn(['notifications', 'lastReadId']);
}
const buildPostMarkersParams = (state: RootState) => {
const params = {} as { home?: MarkerParam; notifications?: MarkerParam };
const lastNotificationId = getLastNotificationId(state);
if (
lastNotificationId &&
lastNotificationId !== '0' &&
compareId(lastNotificationId, state.markers.notifications) > 0
) {
params.notifications = {
last_read_id: lastNotificationId,
};
}
return params;
};
export const submitMarkersAction = createAppAsyncThunk<{
home: string | undefined;
notifications: string | undefined;
}>('markers/submitAction', async (_args, { getState }) => {
const accessToken = authorizationTokenFromState(getState);
const params = buildPostMarkersParams(getState());
if (Object.keys(params).length === 0 || accessToken === '') {
return { home: undefined, notifications: undefined };
}
await api(getState).post<MarkerJSON>('/api/v1/markers', params);
return {
home: params.home?.last_read_id,
notifications: params.notifications?.last_read_id,
};
});
const debouncedSubmitMarkers = debounce(
(dispatch: AppDispatch) => {
void dispatch(submitMarkersAction());
},
300000,
{
leading: true,
trailing: true,
},
);
export const submitMarkers = createAppAsyncThunk(
'markers/submit',
(params: { immediate?: boolean }, { dispatch }) => {
debouncedSubmitMarkers(dispatch);
if (params.immediate) {
debouncedSubmitMarkers.flush();
}
},
);
export const fetchMarkers = createAppAsyncThunk(
'markers/fetch',
async (_args, { getState }) => {
const response = await api(getState).get<Record<string, MarkerJSON>>(
`/api/v1/markers`,
{ params: { timeline: ['notifications'] } },
);
return { markers: response.data };
},
);

View file

@ -1,46 +0,0 @@
// @ts-check
export const PICTURE_IN_PICTURE_DEPLOY = 'PICTURE_IN_PICTURE_DEPLOY';
export const PICTURE_IN_PICTURE_REMOVE = 'PICTURE_IN_PICTURE_REMOVE';
/**
* @typedef MediaProps
* @property {string} src
* @property {boolean} muted
* @property {number} volume
* @property {number} currentTime
* @property {string} poster
* @property {string} backgroundColor
* @property {string} foregroundColor
* @property {string} accentColor
*/
/**
* @param {string} statusId
* @param {string} accountId
* @param {string} playerType
* @param {MediaProps} props
* @returns {object}
*/
export const deployPictureInPicture = (statusId, accountId, playerType, props) => {
// @ts-expect-error
return (dispatch, getState) => {
// Do not open a player for a toot that does not exist
if (getState().hasIn(['statuses', statusId])) {
dispatch({
type: PICTURE_IN_PICTURE_DEPLOY,
statusId,
accountId,
playerType,
props,
});
}
};
};
/*
* @return {object}
*/
export const removePictureInPicture = () => ({
type: PICTURE_IN_PICTURE_REMOVE,
});

View file

@ -0,0 +1,31 @@
import { createAction } from '@reduxjs/toolkit';
import type { PIPMediaProps } from 'flavours/glitch/reducers/picture_in_picture';
import { createAppAsyncThunk } from 'flavours/glitch/store/typed_functions';
interface DeployParams {
statusId: string;
accountId: string;
playerType: 'audio' | 'video';
props: PIPMediaProps;
}
export const removePictureInPicture = createAction('pip/remove');
export const deployPictureInPictureAction =
createAction<DeployParams>('pip/deploy');
export const deployPictureInPicture = createAppAsyncThunk(
'pip/deploy',
(args: DeployParams, { dispatch, getState }) => {
const { statusId } = args;
// Do not open a player for a toot that does not exist
// @ts-expect-error state.statuses is not yet typed
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
if (getState().hasIn(['statuses', statusId])) {
dispatch(deployPictureInPictureAction(args));
}
},
);

View file

@ -29,9 +29,14 @@ const setCSRFHeader = () => {
void ready(setCSRFHeader); void ready(setCSRFHeader);
export const authorizationTokenFromState = (getState?: GetState) => {
return (
getState && (getState().meta.get('access_token', '') as string | false)
);
};
const authorizationHeaderFromState = (getState?: GetState) => { const authorizationHeaderFromState = (getState?: GetState) => {
const accessToken = const accessToken = authorizationTokenFromState(getState);
getState && (getState().meta.get('access_token', '') as string);
if (!accessToken) { if (!accessToken) {
return {}; return {};

View file

@ -0,0 +1,7 @@
// See app/serializers/rest/account_serializer.rb
export interface MarkerJSON {
last_read_id: string;
version: string;
updated_at: string;
}

View file

@ -0,0 +1,22 @@
// See app/serializers/rest/media_attachment_serializer.rb
export type MediaAttachmentType =
| 'image'
| 'gifv'
| 'video'
| 'unknown'
| 'audio';
export interface ApiMediaAttachmentJSON {
id: string;
type: MediaAttachmentType;
url: string;
preview_url: string;
remoteUrl: string;
preview_remote_url: string;
text_url: string;
// TODO: how to define this?
meta: unknown;
description?: string;
blurhash: string;
}

View file

@ -0,0 +1,23 @@
import type { ApiCustomEmojiJSON } from './custom_emoji';
// See app/serializers/rest/poll_serializer.rb
export interface ApiPollOptionJSON {
title: string;
votes_count: number;
}
export interface ApiPollJSON {
id: string;
expires_at: string;
expired: boolean;
multiple: boolean;
votes_count: number;
voters_count: number;
options: ApiPollOptionJSON[];
emojis: ApiCustomEmojiJSON[];
voted: boolean;
own_votes: number[];
}

View file

@ -0,0 +1,95 @@
// See app/serializers/rest/status_serializer.rb
import type { ApiAccountJSON } from './accounts';
import type { ApiCustomEmojiJSON } from './custom_emoji';
import type { ApiMediaAttachmentJSON } from './media_attachments';
import type { ApiPollJSON } from './polls';
// See app/modals/status.rb
export type StatusVisibility =
| 'public'
| 'unlisted'
| 'private'
// | 'limited' // This is never exposed to the API (they become `private`)
| 'direct';
export interface ApiStatusApplicationJSON {
name: string;
website: string;
}
export interface ApiTagJSON {
name: string;
url: string;
}
export interface ApiMentionJSON {
id: string;
username: string;
url: string;
acct: string;
}
export interface ApiPreviewCardJSON {
url: string;
title: string;
description: string;
language: string;
type: string;
author_name: string;
author_url: string;
provider_name: string;
provider_url: string;
html: string;
width: number;
height: number;
image: string;
image_description: string;
embed_url: string;
blurhash: string;
published_at: string;
}
export interface ApiStatusJSON {
id: string;
created_at: string;
in_reply_to_id?: string;
in_reply_to_account_id?: string;
sensitive: boolean;
spoiler_text?: string;
visibility: StatusVisibility;
language: string;
uri: string;
url: string;
replies_count: number;
reblogs_count: number;
favorites_count: number;
edited_at?: string;
favorited?: boolean;
reblogged?: boolean;
muted?: boolean;
bookmarked?: boolean;
pinned?: boolean;
// filtered: FilterResult[]
filtered: unknown; // TODO
content?: string;
text?: string;
reblog?: ApiStatusJSON;
application?: ApiStatusApplicationJSON;
account: ApiAccountJSON;
media_attachments: ApiMediaAttachmentJSON[];
mentions: ApiMentionJSON[];
tags: ApiTagJSON[];
emojis: ApiCustomEmojiJSON[];
card?: ApiPreviewCardJSON;
poll?: ApiPollJSON;
// glitch-soc additions
local_only?: boolean;
content_type?: string;
}

View file

@ -0,0 +1,12 @@
import Rails from '@rails/ujs';
import 'font-awesome/css/font-awesome.css';
export function start() {
require.context('@/images/', true, /\.(jpg|png|svg)$/);
try {
Rails.start();
} catch (e) {
// If called twice
}
}

View file

@ -1,16 +1,18 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { useCallback } from 'react';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
import classNames from 'classnames'; import classNames from 'classnames';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react';
import { EmptyAccount } from 'flavours/glitch/components/empty_account'; import { EmptyAccount } from 'flavours/glitch/components/empty_account';
import { ShortNumber } from 'flavours/glitch/components/short_number'; import { ShortNumber } from 'flavours/glitch/components/short_number';
import { VerifiedBadge } from 'flavours/glitch/components/verified_badge'; import { VerifiedBadge } from 'flavours/glitch/components/verified_badge';
import DropdownMenuContainer from '../containers/dropdown_menu_container';
import { me } from '../initial_state'; import { me } from '../initial_state';
import { Avatar } from './avatar'; import { Avatar } from './avatar';
@ -30,153 +32,153 @@ const messages = defineMessages({
unmute_notifications: { id: 'account.unmute_notifications_short', defaultMessage: 'Unmute notifications' }, unmute_notifications: { id: 'account.unmute_notifications_short', defaultMessage: 'Unmute notifications' },
mute: { id: 'account.mute_short', defaultMessage: 'Mute' }, mute: { id: 'account.mute_short', defaultMessage: 'Mute' },
block: { id: 'account.block_short', defaultMessage: 'Block' }, block: { id: 'account.block_short', defaultMessage: 'Block' },
more: { id: 'status.more', defaultMessage: 'More' },
}); });
class Account extends ImmutablePureComponent { const Account = ({ size = 46, account, onFollow, onBlock, onMute, onMuteNotifications, hidden, minimal, defaultAction, withBio }) => {
const intl = useIntl();
static propTypes = { const handleFollow = useCallback(() => {
size: PropTypes.number, onFollow(account);
account: ImmutablePropTypes.record, }, [onFollow, account]);
onFollow: PropTypes.func,
onBlock: PropTypes.func,
onMute: PropTypes.func,
onMuteNotifications: PropTypes.func,
intl: PropTypes.object.isRequired,
hidden: PropTypes.bool,
minimal: PropTypes.bool,
defaultAction: PropTypes.string,
withBio: PropTypes.bool,
};
static defaultProps = { const handleBlock = useCallback(() => {
size: 46, onBlock(account);
}; }, [onBlock, account]);
handleFollow = () => { const handleMute = useCallback(() => {
this.props.onFollow(this.props.account); onMute(account);
}; }, [onMute, account]);
handleBlock = () => { const handleMuteNotifications = useCallback(() => {
this.props.onBlock(this.props.account); onMuteNotifications(account, true);
}; }, [onMuteNotifications, account]);
handleMute = () => { const handleUnmuteNotifications = useCallback(() => {
this.props.onMute(this.props.account); onMuteNotifications(account, false);
}; }, [onMuteNotifications, account]);
handleMuteNotifications = () => { if (!account) {
this.props.onMuteNotifications(this.props.account, true); return <EmptyAccount size={size} minimal={minimal} />;
}; }
handleUnmuteNotifications = () => {
this.props.onMuteNotifications(this.props.account, false);
};
render () {
const { account, intl, hidden, withBio, defaultAction, size, minimal } = this.props;
if (!account) {
return <EmptyAccount size={size} minimal={minimal} />;
}
if (hidden) {
return (
<>
{account.get('display_name')}
{account.get('username')}
</>
);
}
let buttons;
if (account.get('id') !== me && account.get('relationship', null) !== null) {
const following = account.getIn(['relationship', 'following']);
const requested = account.getIn(['relationship', 'requested']);
const blocking = account.getIn(['relationship', 'blocking']);
const muting = account.getIn(['relationship', 'muting']);
if (requested) {
buttons = <Button text={intl.formatMessage(messages.cancel_follow_request)} onClick={this.handleFollow} />;
} else if (blocking) {
buttons = <Button text={intl.formatMessage(messages.unblock)} onClick={this.handleBlock} />;
} else if (muting) {
let hidingNotificationsButton;
if (account.getIn(['relationship', 'muting_notifications'])) {
hidingNotificationsButton = <Button text={intl.formatMessage(messages.unmute_notifications)} onClick={this.handleUnmuteNotifications} />;
} else {
hidingNotificationsButton = <Button text={intl.formatMessage(messages.mute_notifications)} onClick={this.handleMuteNotifications} />;
}
buttons = (
<>
<Button text={intl.formatMessage(messages.unmute)} onClick={this.handleMute} />
{hidingNotificationsButton}
</>
);
} else if (defaultAction === 'mute') {
buttons = <Button title={intl.formatMessage(messages.mute)} onClick={this.handleMute} />;
} else if (defaultAction === 'block') {
buttons = <Button text={intl.formatMessage(messages.block)} onClick={this.handleBlock} />;
} else if (!account.get('suspended') && !account.get('moved') || following) {
buttons = <Button text={intl.formatMessage(following ? messages.unfollow : messages.follow)} onClick={this.handleFollow} />;
}
}
let muteTimeRemaining;
if (account.get('mute_expires_at')) {
muteTimeRemaining = <>· <RelativeTimestamp timestamp={account.get('mute_expires_at')} futureDate /></>;
}
let verification;
const firstVerifiedField = account.get('fields').find(item => !!item.get('verified_at'));
if (firstVerifiedField) {
verification = <VerifiedBadge link={firstVerifiedField.get('value')} />;
}
if (hidden) {
return ( return (
<div className={classNames('account', { 'account--minimal': minimal })}> <>
<div className='account__wrapper'> {account.get('display_name')}
<Permalink key={account.get('id')} className='account__display-name' title={account.get('acct')} href={account.get('url')} to={`/@${account.get('acct')}`}> {account.get('username')}
<div className='account__avatar-wrapper'> </>
<Avatar account={account} size={size} />
</div>
<div className='account__contents'>
<DisplayName account={account} />
{!minimal && (
<div className='account__details'>
{account.get('followers_count') !== -1 && (
<ShortNumber value={account.get('followers_count')} renderer={FollowersCounter} />
)} {verification} {muteTimeRemaining}
</div>
)}
</div>
</Permalink>
{!minimal && (
<div className='account__relationship'>
{buttons}
</div>
)}
</div>
{withBio && (account.get('note').length > 0 ? (
<div
className='account__note translate'
dangerouslySetInnerHTML={{ __html: account.get('note_emojified') }}
/>
) : (
<div className='account__note account__note--missing'><FormattedMessage id='account.no_bio' defaultMessage='No description provided.' /></div>
))}
</div>
); );
} }
} let buttons;
export default injectIntl(Account); if (account.get('id') !== me && account.get('relationship', null) !== null) {
const following = account.getIn(['relationship', 'following']);
const requested = account.getIn(['relationship', 'requested']);
const blocking = account.getIn(['relationship', 'blocking']);
const muting = account.getIn(['relationship', 'muting']);
if (requested) {
buttons = <Button text={intl.formatMessage(messages.cancel_follow_request)} onClick={handleFollow} />;
} else if (blocking) {
buttons = <Button text={intl.formatMessage(messages.unblock)} onClick={handleBlock} />;
} else if (muting) {
let menu;
if (account.getIn(['relationship', 'muting_notifications'])) {
menu = [{ text: intl.formatMessage(messages.unmute_notifications), action: handleUnmuteNotifications }];
} else {
menu = [{ text: intl.formatMessage(messages.mute_notifications), action: handleMuteNotifications }];
}
buttons = (
<>
<DropdownMenuContainer
items={menu}
icon='ellipsis-h'
iconComponent={MoreHorizIcon}
direction='right'
title={intl.formatMessage(messages.more)}
/>
<Button text={intl.formatMessage(messages.unmute)} onClick={handleMute} />
</>
);
} else if (defaultAction === 'mute') {
buttons = <Button title={intl.formatMessage(messages.mute)} onClick={handleMute} />;
} else if (defaultAction === 'block') {
buttons = <Button text={intl.formatMessage(messages.block)} onClick={handleBlock} />;
} else if (!account.get('suspended') && !account.get('moved') || following) {
buttons = <Button text={intl.formatMessage(following ? messages.unfollow : messages.follow)} onClick={handleFollow} />;
}
}
let muteTimeRemaining;
if (account.get('mute_expires_at')) {
muteTimeRemaining = <>· <RelativeTimestamp timestamp={account.get('mute_expires_at')} futureDate /></>;
}
let verification;
const firstVerifiedField = account.get('fields').find(item => !!item.get('verified_at'));
if (firstVerifiedField) {
verification = <VerifiedBadge link={firstVerifiedField.get('value')} />;
}
return (
<div className={classNames('account', { 'account--minimal': minimal })}>
<div className='account__wrapper'>
<Permalink key={account.get('id')} className='account__display-name' title={account.get('acct')} href={account.get('url')} to={`/@${account.get('acct')}`}>
<div className='account__avatar-wrapper'>
<Avatar account={account} size={size} />
</div>
<div className='account__contents'>
<DisplayName account={account} />
{!minimal && (
<div className='account__details'>
{account.get('followers_count') !== -1 && (
<ShortNumber value={account.get('followers_count')} renderer={FollowersCounter} />
)} {verification} {muteTimeRemaining}
</div>
)}
</div>
</Permalink>
{!minimal && (
<div className='account__relationship'>
{buttons}
</div>
)}
</div>
{withBio && (account.get('note').length > 0 ? (
<div
className='account__note translate'
dangerouslySetInnerHTML={{ __html: account.get('note_emojified') }}
/>
) : (
<div className='account__note account__note--missing'><FormattedMessage id='account.no_bio' defaultMessage='No description provided.' /></div>
))}
</div>
);
};
Account.propTypes = {
size: PropTypes.number,
account: ImmutablePropTypes.record,
onFollow: PropTypes.func,
onBlock: PropTypes.func,
onMute: PropTypes.func,
onMuteNotifications: PropTypes.func,
intl: PropTypes.object.isRequired,
hidden: PropTypes.bool,
minimal: PropTypes.bool,
defaultAction: PropTypes.string,
withBio: PropTypes.bool,
};
export default Account;

View file

@ -7,7 +7,7 @@ import PersonIcon from '@/material-icons/400-24px/person.svg?react';
import SmartToyIcon from '@/material-icons/400-24px/smart_toy.svg?react'; import SmartToyIcon from '@/material-icons/400-24px/smart_toy.svg?react';
export const Badge = ({ icon, label, domain, roleId }) => ( export const Badge = ({ icon = <PersonIcon />, label, domain, roleId }) => (
<div className='account-role' data-account-role-id={roleId}> <div className='account-role' data-account-role-id={roleId}>
{icon} {icon}
{label} {label}
@ -22,10 +22,6 @@ Badge.propTypes = {
roleId: PropTypes.string roleId: PropTypes.string
}; };
Badge.defaultProps = {
icon: <PersonIcon />,
};
export const GroupBadge = () => ( export const GroupBadge = () => (
<Badge icon={<GroupsIcon />} label={<FormattedMessage id='account.badges.group' defaultMessage='Group' />} /> <Badge icon={<GroupsIcon />} label={<FormattedMessage id='account.badges.group' defaultMessage='Group' />} />
); );

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