Compare commits

...

204 Commits

Author SHA1 Message Date
Claire
efab184980 Change mastodon-streaming nightly builds to be tagged as latest
glitch-soc does not have releases, so it tags nightly container builds as latest; but we were not doing the same thing for the new `mastodon-streaming` container
2023-12-26 10:42:14 +01:00
Claire
ea6c187fca Fix media attachment order of remote posts (#28469) 2023-12-22 18:45:36 +01:00
Claire
72ff0d30d8 Fix submitting post from content warning field not working properly (#2538) 2023-12-22 17:23:15 +01:00
Claire
e676b57831 Merge pull request #2537 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to b7bdcd4f39
2023-12-22 17:22:39 +01:00
Claire
f96e713522 Fix trying to push mastodon-streaming docker images to upstream's ghcr repo (#2541) 2023-12-22 13:01:08 +01:00
Claire
5bd61a3fc5 Don't try to push images to Mastodon's dockerhub (#2540) 2023-12-22 12:13:53 +01:00
Claire
d4c87ff5b8 Disable use of missing native arm64 docker builder for the streaming image (#2539) 2023-12-22 08:45:37 +01:00
Claire
92aa6e2ec9 Merge commit 'b7bdcd4f395aaa1e85930940975439d10b570f40' into glitch-soc/merge-upstream 2023-12-21 19:42:13 +01:00
Claire
30ee7339d3 Merge commit '7d9b209fe84b00eff348ea9d54905cbfffa79788' into glitch-soc/merge-upstream
Conflicts:
- `app/models/form/admin_settings.rb`:
  Upstream changed code style change, including on a line modified by glitch-soc.
  Kept glitch-soc's line but with the code style change applied.
2023-12-21 19:31:12 +01:00
Claire
f2eb5038a6 Fix linting warning in glitch-soc-only migration 2023-12-21 19:25:12 +01:00
Claire
f5b7307890 Merge commit 'f99e05710ea06cf10bbd3fb64ae8c00b095cb455' into glitch-soc/merge-upstream
Conflicts:
- `.rubocop_todo.yml`:
  Took upstream's version of the conflicting lines.
2023-12-21 19:24:10 +01:00
Claire
7a0be26367 [Glitch] Fix empty column explainer getting cropped under certain conditions
Port 3f1ec16377 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2023-12-21 19:08:43 +01:00
Claire
a60b9acf3c Merge commit 'b2f915b31ae884e3893e93a99da4e2b8d7e9ef7b' into glitch-soc/merge-upstream 2023-12-21 19:04:20 +01:00
Claire
dac2b56932 Merge pull request #2535 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 4a7395d989
2023-12-21 19:03:29 +01:00
Claire
6e56f95285 Merge commit '4a7395d989e40c3bd4ef18173aa5ea850c8ddcdd' into glitch-soc/merge-upstream
Conflicts:
- `README.md`:
  Upstream modified its README, we have a completely different one.
  Kept our README file.
2023-12-21 18:17:17 +01:00
Claire
d668b85dcd Merge pull request #2532 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 0b4a3a0437
2023-12-21 18:13:49 +01:00
Claire
9ac13bbc9c Fix glitch-only HAML linting issue 2023-12-20 22:27:29 +01:00
Claire
b2961dad2b Fix lint issue in glitch-soc-only file 2023-12-20 22:25:23 +01:00
Matt Jankowski
01e77a0f34 [Glitch] Enable the eslint react/no-unknown-property rule
Port ee83d5c760 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2023-12-20 22:24:40 +01:00
Claire
077e0c6812 Merge commit '0b4a3a04378ce43f2f314b9446b5053f6b374c6d' into glitch-soc/merge-upstream
Conflicts:
- `Gemfile.lock`:
  Conflict caused by the `json` gem thing once again.
  Updated as upstream did, but keeping the most recent `json` version.
- `spec/helpers/application_helper_spec.rb`:
  Upstream refactored a bunch of specs, including one place that differs
  because of glitch-soc's theming system.
  Refactored as upstream did, adapting it for glitch-soc's theming system.
2023-12-20 22:16:50 +01:00
Claire
75580360cd Merge commit '272592d16d40e804ec325ef3b5e6de9bbad5f2dd' into glitch-soc/merge-upstream
Conflicts:
- `.rubocop_todo.yml`:
  Upstream fixed a bunch lint issues, and changed the `Max` parameter of the
  `Metrics/AbcSize` cop.
  Glitch-soc has different code and slightly higher `AbcSize` complexity,
  modified the `.rubocop_todo.yml` file accordingly.
- `app/policies/status_policy.rb`:
  Upstream changed `account.suspended?` to `account.unavailable?` to prepare
  for delete flags. Glitch-soc has additional local-only conditions.
  Ported upstream's refactor while keeping glitch-soc's additional condition.
- `app/serializers/initial_state_serializer.rb`:
  Upstream refactored a bunch of stuff while glitch-soc has more settings.
  Refactored as upstream did while keeping glitch-soc's settings.
2023-12-20 22:05:31 +01:00
Claire
5de551002d [Glitch] Fix onboarding step descriptions being truncated on narrow screens
Port b20af17a2c to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2023-12-20 21:59:58 +01:00
Claire
8a5f2442cc Merge commit '0530ce5e9575c09464847412f43852f438b0494e' into glitch-soc/merge-upstream 2023-12-20 21:58:18 +01:00
Claire
b41af99673 [Glitch] Change dismissed banners to be stored server-side
Port 7faa27e17d to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2023-12-20 20:40:47 +01:00
Claire
b8209c3b96 Merge commit '85662a5a57531af5402a6777d0b1089e78c56815' into glitch-soc/merge-upstream
Conflicts:
- `config/initializers/content_security_policy.rb`:
  Upstream reworked the CSP, we kept our version for now.
- `spec/requests/content_security_policy_spec.rb`:
  Upstream reworked the CSP, we kept our version for now.
2023-12-20 20:10:45 +01:00
renovate[bot]
b7bdcd4f39 Update dependency @material-symbols/svg-600 to v0.14.3 (#28276)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-19 10:56:23 +00:00
Matt Jankowski
c28976d89e Handle negative offset param in api/v2/search (#28282) 2023-12-19 10:55:39 +00:00
Renaud Chaput
7b1d390734 Fixes dropdown target without a buttonRef (edit history) (#28427) 2023-12-19 10:47:53 +00:00
github-actions[bot]
fa987db738 New Crowdin Translations (automated) (#28423)
Co-authored-by: GitHub Actions <noreply@github.com>
2023-12-19 09:40:37 +00:00
Claire
3598c2e1db Revert "Feature - Prevents multiple audio/video attachments from being played at the same time (#24717)" (#28251) 2023-12-19 05:08:52 +00:00
Renaud Chaput
8b1eeb2f90 Fix the loading bar with the new Redux actions (#28422) 2023-12-18 23:19:27 +00:00
Matt Jankowski
7cfc078198 Fix rails mailer preview not honouring locale (#28418) 2023-12-18 21:49:17 +00:00
Matt Jankowski
476d1237d4 Typo fix in json ld helper spec (#28417) 2023-12-18 16:47:22 +00:00
renovate[bot]
ab1201c9d9 Update dependency regenerator-runtime to v0.14.1 (#28393)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-18 16:21:54 +00:00
Claire
7d9b209fe8 Fix call to inefficient delete_matched cache method in domain blocks (#28374) 2023-12-18 16:14:43 +00:00
Yamagishi Kazutoshi
f4b9c2ba40 Group artifact actions (#28413) 2023-12-18 14:02:19 +00:00
Matt Jankowski
af366f65ee Add spec coverage for models/form/custom_emoji_batch class (#28388) 2023-12-18 12:41:37 +00:00
renovate[bot]
b2ca71f733 Update dependency rubocop-performance to v1.20.0 (#28395)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-18 12:41:22 +00:00
Matt Jankowski
0b42cf2979 Opt out of Rails/NegateInclude cop (#28370) 2023-12-18 12:21:45 +00:00
Matt Jankowski
1820bad646 Fix Performance/StringIdentifierArgument cop (#28399) 2023-12-18 10:26:09 +00:00
Matt Jankowski
2bd8d343cf Fix Style/SoleNestedConditional and Style/IfInsideElse cops, regenerate haml todo (#28384) 2023-12-18 10:06:42 +00:00
Matt Jankowski
8e9e7d57d8 Opt out of Rails/UnusedIgnoredColumns cop (#28385) 2023-12-18 09:58:53 +00:00
Matt Jankowski
0e5b8fc46b Fix Style/RedundantReturn cop (#28391) 2023-12-18 09:50:51 +00:00
Matt Jankowski
89d468ada7 Fix Style/StderrPuts cop (#28389) 2023-12-18 09:36:08 +00:00
Matt Jankowski
e56fb9e489 Fix Style/SymbolProc cop (#28386) 2023-12-18 09:32:02 +00:00
renovate[bot]
fc4eaa779a Update dependency cssnano to v6.0.2 (#28382)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-18 09:31:21 +00:00
renovate[bot]
fad7dca0e4 Update dependency prom-client to v15.1.0 (#28394)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-18 09:29:41 +00:00
renovate[bot]
43f637c130 Update dependency rubocop-rails to v2.23.0 (#28396)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-18 09:28:19 +00:00
renovate[bot]
287384b3bb Update DefinitelyTyped types (non-major) (#28407)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-18 09:28:10 +00:00
renovate[bot]
d099cf67c0 Update eslint (non-major) (#28408)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-18 09:28:06 +00:00
github-actions[bot]
f99e05710e New Crowdin Translations (automated) (#28373)
Co-authored-by: GitHub Actions <noreply@github.com>
2023-12-18 08:25:21 +00:00
Matt Jankowski
b1dec09d20 Fix Style/InverseMethods cop (#28377) 2023-12-15 15:52:00 +00:00
Matt Jankowski
3e336fe706 Opt out of Rails/SkipsModelValidations cop in db/migrate (#28371) 2023-12-15 14:38:12 +00:00
Matt Jankowski
e5717c9bc6 Fix Style/Lambda cop (#28378) 2023-12-15 14:34:24 +00:00
Matt Jankowski
1ee8d1e50e Assign a proc to Rack::Request.ip_filter instead of patching method (#28380) 2023-12-15 14:33:56 +00:00
Matt Jankowski
db897eaa5a Unwind map on single-item array in spec/services/delete_account_service spec (#28358) 2023-12-14 14:07:54 +00:00
Matt Jankowski
e17faedffb Move default meta options from InitialStateSerializer to private method (AbcSize reduction) (#28355) 2023-12-14 14:04:55 +00:00
Matt Jankowski
1c3b5f4a78 Fix reference to non-existent var in CLI maintenance command (#28363) 2023-12-14 14:02:33 +00:00
Matt Jankowski
ef9797a395 Un-nest contexts in settings/2fa/webauthn spec (#28359) 2023-12-14 10:46:43 +00:00
Matt Jankowski
adbfd40a1b Convert api/v1/directories controller spec to request spec (#28356) 2023-12-14 10:38:06 +00:00
Matt Jankowski
cd9ebf5f0f Update stylelint to version 16.0.2 (#28354) 2023-12-14 10:35:54 +00:00
Matt Jankowski
28e1a7a394 Improve spec coverage for models/announcement class (#28350) 2023-12-14 10:29:10 +00:00
renovate[bot]
d791b47058 Update dependency chewy to v7.4.0 (#28349)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-14 10:26:28 +00:00
Matt Jankowski
8a3d8c6c14 Remove the stub_stdout wrapper around CLI specs (#28340) 2023-12-13 10:14:19 +00:00
renovate[bot]
3a59365e40 Update dependency test-prof to v1.3.1 (#28342)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-13 09:52:43 +00:00
renovate[bot]
49150e2f1d Update dependency ws to v8.15.1 (#28343)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-13 09:52:40 +00:00
github-actions[bot]
b2f915b31a New Crowdin Translations (automated) (#28344)
Co-authored-by: GitHub Actions <noreply@github.com>
2023-12-13 09:52:37 +00:00
renovate[bot]
aae4b5644f Update dependency haml_lint to v0.52.0 (#28345)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-13 09:52:33 +00:00
Claire
dcc24db793 Fix N+1s because of association preloaders not actually getting called (#28339) 2023-12-13 07:47:32 +00:00
Claire
3f1ec16377 Fix empty column explainer getting cropped under certain conditions (#28337) 2023-12-12 14:31:37 +00:00
renovate[bot]
db3220ff77 Update dependency rubocop to v1.59.0 (#28320)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-12 14:18:30 +00:00
Claire
f37c93f3d7 Change cookie rotator to use SHA1 digest for new cookies (#27392) 2023-12-12 12:01:08 +00:00
Claire
393e851649 Change Rails' cache format to 7.0 (#27393) 2023-12-12 12:00:23 +00:00
Matt Jankowski
4a7395d989 Add migrator_version method to CLI maintenance script (#28323) 2023-12-12 11:56:39 +00:00
renovate[bot]
ca51e41239 Update dependency stylelint-config-standard-scss to v12 (#28333)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-12 11:45:39 +00:00
github-actions[bot]
14e64bc880 New Crowdin Translations (automated) (#28334)
Co-authored-by: GitHub Actions <noreply@github.com>
2023-12-12 11:45:10 +00:00
renovate[bot]
8078520c76 Update dependency oj to v3.16.3 (#28332)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-12 10:40:54 +00:00
Claire
89a496b42f Fix status edits not always being streamed to mentioned users (#28324) 2023-12-12 10:39:21 +00:00
Claire
a8a5c6514f Fix LinkCrawlWorker error when encountering empty OEmbed response (#28268) 2023-12-12 08:29:46 +00:00
Matt Jankowski
2c6369918c Fix Style/RedundantArgument cop (#28321) 2023-12-11 14:58:29 +00:00
renovate[bot]
9dfa940636 Update babel monorepo to v7.23.6 (#28319)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-11 14:58:10 +00:00
Claire
f3864db409 Fix notification sounds (#28316) 2023-12-11 14:23:30 +00:00
Matt Jankowski
b5a1013ae3 Combine CLI::... spec example subjects (#28285) 2023-12-11 10:23:45 +00:00
renovate[bot]
4ad2e87c48 Update dependency debug to v1.9.0 (#28315)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-11 08:45:30 +00:00
github-actions[bot]
79a81da69c New Crowdin Translations (automated) (#28291)
Co-authored-by: GitHub Actions <noreply@github.com>
2023-12-11 08:22:52 +00:00
Matt Jankowski
0e4233de9d Controller spec to request spec: api/v2/suggestions (#28297) 2023-12-11 08:13:57 +00:00
Matt Jankowski
0c64092500 Controller spec to request spec: api/v1/accounts/search (#28299) 2023-12-11 08:13:28 +00:00
Matt Jankowski
253393f3a8 Only attempt to remove indexes that exist in CLI::Maintenance script (#28286) 2023-12-11 08:04:45 +00:00
renovate[bot]
f5d6143aa1 Update dependency addressable to v2.8.6 (#28296)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-11 08:01:17 +00:00
Matt Jankowski
16ede59d0a Controller spec to request spec: api/v1/featured_tags/suggestions (#28298) 2023-12-11 08:00:41 +00:00
Matt Jankowski
809506bdd4 Controller spec to request spec: api/v1/accounts/pins (#28300) 2023-12-11 07:59:40 +00:00
Matt Jankowski
94cc707ab3 Controller spec to request spec: api/v1/accounts/notes (#28301) 2023-12-11 07:58:48 +00:00
Matt Jankowski
e544b6df42 Controller spec to request spec: api/v1/accounts/lookup (#28302) 2023-12-11 07:57:33 +00:00
Matt Jankowski
a968898dc7 Controller spec to request spec: api/v1/accounts/lists (#28303) 2023-12-11 07:56:47 +00:00
Matt Jankowski
8f94502e7d Controller spec to request spec: api/v1/accounts/identify_proofs (#28304) 2023-12-11 07:56:13 +00:00
Matt Jankowski
78347d2556 Controller spec to request spec: api/v1/accounts/familiar_followers (#28305) 2023-12-11 07:55:45 +00:00
Matt Jankowski
11d2bd9716 Fix intermittent failure from unspecified order in api/v1/accounts/relationships spec (#28306) 2023-12-11 07:55:07 +00:00
renovate[bot]
b82fc8a2ca Update dependency ws to v8.15.0 (#28308)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-11 07:54:22 +00:00
renovate[bot]
a117155728 Update DefinitelyTyped types (non-major) (#28310)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-11 07:54:01 +00:00
renovate[bot]
7ddd937330 Update dependency prettier to v3.1.1 (#28311)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-11 07:53:32 +00:00
renovate[bot]
d0e7999a90 Update dependency typescript to v5.3.3 (#28312)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-11 07:53:13 +00:00
renovate[bot]
bd88883b6e Update eslint (non-major) (#28313)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-11 07:52:53 +00:00
Michael Stanclift
afc8550b63 Change preview card deletes to be done using batch method (#28183) 2023-12-11 07:49:10 +00:00
Matt Jankowski
490e4969a1 Correct section naming in maintenance cli script (#28279) 2023-12-08 13:54:48 +00:00
Matt Jankowski
a3cbb4b2f1 Add spec for CLI::Search#deploy command (#28272) 2023-12-08 13:54:20 +00:00
github-actions[bot]
ca1b7efb06 New Crowdin Translations (automated) (#28275)
Co-authored-by: GitHub Actions <noreply@github.com>
2023-12-08 09:52:32 +00:00
JakePaustian
f37a1535ef Update CONTRIBUTING.md with additional requirements for API additions (#28274)
Co-authored-by: Jake Paustian <jake1500@iastate.edu>
2023-12-08 09:52:28 +00:00
Matt Jankowski
8de86eabbf Add spec for CLI::Domains#crawl command (#28271) 2023-12-08 09:51:57 +00:00
Matt Jankowski
7e514688b3 Convert api/v2/search controller spec to request spec (#28269) 2023-12-08 09:27:33 +00:00
Matt Jankowski
8d8ae05a18 Add spec coverage for CLI::Media#lookup command (#28266) 2023-12-07 15:27:41 +00:00
Matt Jankowski
3918dc68c7 Use composite primary key for PreviewCardsStatus model (#28208) 2023-12-07 14:49:05 +00:00
Michael Stanclift
da3d8aff79 Error handling for attachment batch delete process (#28184)
Co-authored-by: Claire <claire.github-309c@sitedethib.com>
2023-12-07 14:40:44 +00:00
Matt Jankowski
ad34d33bfd Formalize some patterns in cli specs (#28255) 2023-12-07 13:49:14 +00:00
Ken Greeff
5d97a897c8 Add note to install libidn on MacOS (#28259) 2023-12-07 12:45:55 +00:00
Matt Jankowski
0b4a3a0437 Remove remaining without_partial_double_verification usage (#28127) 2023-12-07 12:15:50 +00:00
Matt Jankowski
1d7b8234c9 Remove useless reorder(nil) call in tootctl statuses (#28141) 2023-12-07 09:41:00 +00:00
github-actions[bot]
e0dacf6b4c New Crowdin Translations (automated) (#28264)
Co-authored-by: GitHub Actions <noreply@github.com>
2023-12-07 09:38:44 +00:00
Claire
7593465c23 Fix error when processing link preview with an array as inLanguage (#28252) 2023-12-07 09:05:08 +00:00
renovate[bot]
336d6260ba Update dependency chewy to v7.3.5 (#28253)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-07 08:44:45 +00:00
renovate[bot]
54db2006a9 Update dependency sass-loader to v10.5.0 (#28254)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-07 08:44:16 +00:00
renovate[bot]
5e8a38e254 Update dependency oj to v3.16.2 (#28263)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-07 08:42:47 +00:00
Claire
658ad7a6ca Fix flaky tests related to file creation (#28248) 2023-12-06 22:22:25 +00:00
Matt Jankowski
af66d3d836 Use following and followers scopes in CLI (#28154) 2023-12-06 14:15:54 +00:00
renovate[bot]
23b16aaab0 Update dependency selenium-webdriver to v4.16.0 (#28246)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-06 13:50:59 +00:00
Matt Jankowski
ee83d5c760 Enable the eslint react/no-unknown-property rule (#28217) 2023-12-06 13:42:12 +00:00
Matt Jankowski
42afd30324 Replace Sprockets with Propshaft (#28239) 2023-12-06 10:19:24 +00:00
github-actions[bot]
954169966b New Crowdin Translations (automated) (#28245)
Co-authored-by: GitHub Actions <noreply@github.com>
2023-12-06 08:52:55 +00:00
Matt Jankowski
0e8ba19113 Add spec coverage for CLI::Emoji class (#28182) 2023-12-06 08:52:30 +00:00
Matt Jankowski
ed7b5c091b Remove double subject call in services/delete_account_service spec (#28212) 2023-12-06 08:51:09 +00:00
Matt Jankowski
be6bb1a10d Remove double subject call in services/suspend_account_service spec (#28213) 2023-12-06 08:45:19 +00:00
Matt Jankowski
5517df61de Remove double subject call in services/activitypub/process_account_service spec (#28214) 2023-12-06 08:44:51 +00:00
Matt Jankowski
faffd81976 Remove double subject call in services/unsuspend_account_service spec (#28215) 2023-12-06 08:44:07 +00:00
renovate[bot]
3b710b96cf Update dependency irb to v1.10.1 (#28240)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-06 08:33:27 +00:00
renovate[bot]
996c13a24d Update dependency core-js to v3.34.0 (#28241)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-06 08:33:11 +00:00
github-actions[bot]
4238ec844d New Crowdin Translations (automated) (#28120)
Co-authored-by: GitHub Actions <noreply@github.com>
Co-authored-by: Claire <claire.github-309c@sitedethib.com>
2023-12-05 16:07:53 +00:00
Jonathan de Jong
d0a5ebf914 Fix error when encountering malformed Tag objects from Kbin (#28235) 2023-12-05 13:59:15 +00:00
renovate[bot]
2d2e23c68d Update dependency brakeman to v6.1.0 (#28231)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-05 12:59:31 +00:00
renovate[bot]
f944a767c4 Update dependency json-ld to v3.3.1 (#28229)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-05 12:57:16 +00:00
Matt Jankowski
89a8e6e622 Remove 2x double subject call in models/form/account_batch spec (#28209) 2023-12-04 15:41:43 +00:00
Matt Jankowski
71e5a16eba Remove triple subject call in api/v1/lists spec (#28210) 2023-12-04 15:28:19 +00:00
Matt Jankowski
cca19f5fbb Use the Admin::ActionLog fabricator in admin/action_logs spec (#28194) 2023-12-04 12:56:28 +00:00
Matt Jankowski
b3b009e6aa Add spec coverage for CLI::EmailDomainBlocks commands (#28181) 2023-12-04 09:44:54 +00:00
renovate[bot]
829457212e Update dependency rubocop to v1.58.0 (#28170)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-04 09:38:49 +00:00
Claire
a2bcfeb887 Fix Style/HashEachMethods cop in HAML files (#28178) 2023-12-04 09:09:43 +00:00
Matt Jankowski
9603198982 Add spec coverage for CLI::Domains#purge command (#28179) 2023-12-04 09:09:05 +00:00
Matt Jankowski
1bf2230fd1 Add spec coverage for CLI::Upgrade#storage_schema command (#28180) 2023-12-04 09:08:47 +00:00
Matt Jankowski
19ad51253d Prevent triple-subject run in admin/domain_blocks spec (#28195) 2023-12-04 09:02:40 +00:00
renovate[bot]
154fb95e44 Update dependency postcss to v8.4.32 (#28185)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-04 08:52:53 +00:00
Matt Jankowski
d848d8d87c Add helper methods for domains allow and export blocks files (#28196) 2023-12-04 08:52:21 +00:00
renovate[bot]
3ec263bf15 Update dependency irb to v1.10.0 (#28198)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-04 08:51:08 +00:00
renovate[bot]
b4fef6c26f Update DefinitelyTyped types (non-major) (#28199)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-04 08:50:43 +00:00
renovate[bot]
0ca7a50e96 Update devDependencies (non-major) (#28200)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-04 08:50:28 +00:00
renovate[bot]
456597dae5 Update dependency doorkeeper to v5.6.8 (#28177)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-01 16:22:15 +00:00
Matt Jankowski
469ee2ae36 Fix Style/HashEachMethods cop (#28173) 2023-12-01 16:07:19 +00:00
Matt Jankowski
3bc437b99a Fix Style/RedundantParentheses cop (#28176) 2023-12-01 16:00:44 +00:00
Matt Jankowski
5631f139c1 Fix Lint/SymbolConversion cop (#28175) 2023-12-01 15:53:35 +00:00
Matt Jankowski
aa8563d43d Fix Style/SuperWithArgsParentheses cop (#28174) 2023-12-01 15:53:15 +00:00
Matt Jankowski
d83d01eb1e Fix Lint/RedundantSafeNavigation cop (#28172) 2023-12-01 15:52:56 +00:00
Matt Jankowski
a98fccf84e Fix Style/SelfAssignment cop (#28171) 2023-12-01 15:52:52 +00:00
Matt Jankowski
f70f39dd04 Add explicit dependent: nil to associations (#28169) 2023-12-01 15:52:47 +00:00
Matt Jankowski
1564799952 Add spec coverage for media CLI refresh command (#28166) 2023-12-01 14:18:45 +00:00
Matt Jankowski
7753e5f715 Add shared example for CLI command specs (#28165) 2023-12-01 12:00:34 +00:00
Matt Jankowski
92fa9b109f Add spec coverage for media CLI usage command (#28167) 2023-12-01 11:56:47 +00:00
Michael Stanclift
272592d16d Change startup command for Puma in Docker Compose (#28138) 2023-12-01 11:06:37 +00:00
Matt Jankowski
440b80b2e7 Model concerns organization into module namespaces (#28149) 2023-12-01 11:00:41 +00:00
Matt Jankowski
b751078fcd Eliminate double subject call in admin/ controller specs (#28158) 2023-12-01 10:38:15 +00:00
Michael Stanclift
8710bdb183 Fix mastodon user not being owner of tmp folder in Dockerfile (#28137) 2023-11-30 16:11:21 +00:00
Claire
963354978a Add Account#unavailable? and Account#permanently_unavailable? aliases (#28053) 2023-11-30 15:43:26 +00:00
Matt Jankowski
35deaaf90b Reduce AbcSize complexity in InitialStateSerializer (#27782) 2023-11-30 15:41:26 +00:00
Matt Jankowski
1f1c75bba5 File cleanup/organization in controllers/concerns (#27846) 2023-11-30 14:39:41 +00:00
Matt Jankowski
0530ce5e95 Convert accounts controller spec to request spec (#28126) 2023-11-30 14:28:05 +00:00
Matt Jankowski
e7c340a634 Spec coverage for missing q param and error conditions in api/v2/search controller (#27842) 2023-11-30 13:59:46 +00:00
Matt Jankowski
a8473f582d Add zeitwerk inflector for cli->CLI (#27635) 2023-11-30 13:55:20 +00:00
Claire
b20af17a2c Fix onboarding step descriptions being truncated on narrow screens (#28021) 2023-11-30 13:47:07 +00:00
Claire
85662a5a57 Change img-src and media-src CSP directives to not include https: (#28025) 2023-11-30 13:47:01 +00:00
Matt Jankowski
bb0efe16e6 Remove default_scope from MediaAttachment class (#28043) 2023-11-30 13:30:35 +00:00
renovate[bot]
02a98210e8 fix(deps): update dependency jsdom to v23.0.1 (#28135)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-30 13:22:40 +00:00
renovate[bot]
0212e0cfbf fix(deps): update dependency @babel/runtime to v7.23.5 (#28136)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-30 13:22:25 +00:00
Claire
7faa27e17d Change dismissed banners to be stored server-side (#27055) 2023-11-30 11:45:54 +00:00
Matt Jankowski
ce78a9c9ac Clean up two_factor_authentication/confirmations controller spec (#28128) 2023-11-30 11:44:42 +00:00
Filippo Giunchedi
e6fd9a59e6 Fix FamiliarFollowersController test response comparison (#28121)
Co-authored-by: Filippo Giunchedi <filippo@debian.org>
2023-11-30 10:58:40 +00:00
renovate[bot]
c761cc4738 fix(deps): update babel monorepo to v7.23.5 (#28122)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-30 10:53:49 +00:00
Matt Jankowski
b696ca6b1a Move self destruct CLI command definition code to module (#28131) 2023-11-30 10:48:46 +00:00
Filippo Giunchedi
6e55ff9643 Change Vagrant to install Node 20 (#28100)
Co-authored-by: Filippo Giunchedi <filippo@debian.org>
2023-11-30 10:46:06 +00:00
Matt Jankowski
e48ecd2929 Remove default_scope from Admin::ActionLog (#28026) 2023-11-29 10:39:59 +00:00
Matt Jankowski
291dc04e67 Remove un-needed action and template options to render in controllers (#28022) 2023-11-29 10:38:05 +00:00
Matt Jankowski
a1636fce7f Move lib/devise/* to lib/devise/strategies/* (#27638) 2023-11-29 10:10:21 +00:00
Matt Jankowski
31bef99b9e Move lib/mastodon/premailer_webpack_strategy to lib/ (#27636) 2023-11-29 10:08:55 +00:00
Matt Jankowski
72b7cd349c Extract helper methods for form label in admin/ area views (#27575) 2023-11-29 10:06:19 +00:00
Matt Jankowski
9b47c5d53c Extract helper methods for labels from filters/_filter_fields (#27574) 2023-11-29 10:02:59 +00:00
Matt Jankowski
186895fc88 Refactor, lint fix, and bug fix on admin/roles/form partial (#27558) 2023-11-29 10:00:52 +00:00
renovate[bot]
3e1e41054b chore(deps): update dependency pghero to v3.4.0 (#28117)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-29 09:00:07 +00:00
Emelia Smith
603b245cc6 Add VAPID public key to instance serializer (#28006)
Co-authored-by: Renaud Chaput <renchap@gmail.com>
2023-11-29 08:34:36 +00:00
Michael Stanclift
c40cfc5d09 Fix apt cache not being properly utilized in Dockerfile (#28115) 2023-11-28 22:23:44 +00:00
Michael Stanclift
7a3b41eb54 Fix incorrect apt-get install block in Dockerfile (#28112) 2023-11-28 20:44:04 +00:00
Matt Jankowski
6b46bf9953 Handle scenario when webfinger response subject is missing host value (#28088) 2023-11-28 18:37:54 +00:00
Matt Jankowski
b9492d84a0 Update bcrypt to version 3.1.20 (#28084) 2023-11-28 18:36:21 +00:00
Matt Jankowski
b45fe15c06 Update temple to version 0.10.3 (#28086) 2023-11-28 18:36:16 +00:00
Josh Goldberg ✨
3a7f10c3f1 Converted hashtag.jsx to TypeScript (#27872)
Co-authored-by: Claire <claire.github-309c@sitedethib.com>
Co-authored-by: Renaud Chaput <renchap@gmail.com>
2023-11-28 18:20:10 +00:00
Josh Goldberg ✨
1142f4c79e Converted app/javascript/mastodon/utils/ folder to TypeScript (#27895) 2023-11-28 17:47:55 +00:00
Renaud Chaput
cdc7894243 Fix devcontainer by not forcing NODE_ENV (#28099) 2023-11-28 14:47:32 +00:00
Emelia Smith
a4de0e364b Refactor streaming to simplify for logging change (#28056) 2023-11-28 14:24:41 +00:00
Emelia Smith
4949b6da58 Fix streaming eslint configuration (#28055) 2023-11-28 14:09:21 +00:00
Michael Stanclift
a80530d1df Dockerfile rewrite based on Ruby image with performance optimizations and size reduction, dedicated Streaming image (#26850)
Co-authored-by: “Michael <“mx@vmstan.com>
Co-authored-by: Emelia Smith <ThisIsMissEm@users.noreply.github.com>
2023-11-28 10:04:40 +00:00
439 changed files with 10291 additions and 3915 deletions

View File

@@ -24,4 +24,4 @@ RAILS_ENV=development ./bin/rails db:setup
RAILS_ENV=development ./bin/rails assets:precompile
# Precompile assets for test
RAILS_ENV=test NODE_ENV=tests ./bin/rails assets:precompile
RAILS_ENV=test ./bin/rails assets:precompile

View File

@@ -1,4 +1,7 @@
module.exports = {
// @ts-check
const { defineConfig } = require('eslint-define-config');
module.exports = defineConfig({
root: true,
extends: [
@@ -117,7 +120,6 @@ module.exports = {
'react/jsx-uses-react': 'off', // not needed with new JSX transform
'react/jsx-wrap-multilines': 'error',
'react/no-deprecated': 'off',
'react/no-unknown-property': 'off',
'react/react-in-jsx-scope': 'off', // not needed with new JSX transform
'react/self-closing-comp': 'error',
@@ -193,6 +195,7 @@ module.exports = {
'error',
{
devDependencies: [
'.eslintrc.js',
'config/webpack/**',
'app/javascript/mastodon/performance.js',
'app/javascript/mastodon/test_setup.js',
@@ -297,7 +300,6 @@ module.exports = {
'formatjs/no-id': 'off', // IDs are used for translation keys
'formatjs/no-invalid-icu': 'error',
'formatjs/no-literal-string-in-jsx': 'off', // Should be looked at, but mainly flagging punctuation outside of strings
'formatjs/no-multiple-plurals': 'off', // Only used by hashtag.jsx
'formatjs/no-multiple-whitespaces': 'error',
'formatjs/no-offset': 'error',
'formatjs/no-useless-message': 'error',
@@ -316,6 +318,7 @@ module.exports = {
overrides: [
{
files: [
'.eslintrc.js',
'*.config.js',
'.*rc.js',
'ide-helper.js',
@@ -366,7 +369,7 @@ module.exports = {
'@typescript-eslint/consistent-type-definitions': ['warn', 'interface'],
'@typescript-eslint/consistent-type-exports': 'error',
'@typescript-eslint/consistent-type-imports': 'error',
"@typescript-eslint/prefer-nullish-coalescing": ['error', {ignorePrimitives: {boolean: true}}],
"@typescript-eslint/prefer-nullish-coalescing": ['error', { ignorePrimitives: { boolean: true } }],
'jsdoc/require-jsdoc': 'off',
@@ -389,14 +392,6 @@ module.exports = {
env: {
jest: true,
},
},
{
files: [
'streaming/**/*',
],
rules: {
'import/no-commonjs': 'off',
},
},
}
],
};
});

View File

@@ -50,7 +50,6 @@
matchManagers: ['bundler'],
matchPackageNames: [
'rack', // Needs to be synced with Rails version
'sprockets', // Requires manual upgrade https://github.com/rails/sprockets/blob/master/UPGRADING.md#guide-to-upgrading-from-sprockets-3x-to-4x
'strong_migrations', // Requires manual upgrade
'sidekiq', // Requires manual upgrade
'sidekiq-unique-jobs', // Requires manual upgrades and sync with Sidekiq version
@@ -100,6 +99,16 @@
matchUpdateTypes: ['patch', 'minor'],
groupName: 'eslint (non-major)',
},
{
// Group actions/*-artifact in the same PR
matchManagers: ['github-actions'],
matchPackageNames: [
'actions/download-artifact',
'actions/upload-artifact',
],
matchUpdateTypes: ['major'],
groupName: 'artifact actions (major)',
},
{
// Update @types/* packages every week, with one grouped PR
matchPackagePrefixes: '@types/',

View File

@@ -21,6 +21,8 @@ on:
type: string
labels:
type: string
file_to_build:
type: string
jobs:
build-image:
@@ -86,6 +88,7 @@ jobs:
- uses: docker/build-push-action@v5
with:
context: .
file: ${{ inputs.file_to_build }}
build-args: |
MASTODON_VERSION_PRERELEASE=${{ inputs.version_prerelease }}
MASTODON_VERSION_METADATA=${{ inputs.version_metadata }}

View File

@@ -25,6 +25,7 @@ jobs:
needs: compute-suffix
uses: ./.github/workflows/build-container-image.yml
with:
file_to_build: Dockerfile
platforms: linux/amd64,linux/arm64
use_native_arm64_builder: false
cache: false
@@ -40,3 +41,24 @@ jobs:
type=raw,value=nightly
type=schedule,pattern=${{ needs.compute-suffix.outputs.prerelease }}
secrets: inherit
build-image-streaming:
needs: compute-suffix
uses: ./.github/workflows/build-container-image.yml
with:
file_to_build: streaming/Dockerfile
platforms: linux/amd64,linux/arm64
use_native_arm64_builder: false
cache: false
push_to_images: |
ghcr.io/${{ github.repository_owner }}/mastodon-streaming
version_prerelease: ${{ needs.compute-suffix.outputs.prerelease }}
labels: |
org.opencontainers.image.description=Nightly build image used for testing purposes
flavor: |
latest=true
tags: |
type=raw,value=edge
type=raw,value=nightly
type=schedule,pattern=${{ needs.compute-suffix.outputs.prerelease }}
secrets: inherit

View File

@@ -29,6 +29,7 @@ jobs:
needs: compute-suffix
uses: ./.github/workflows/build-container-image.yml
with:
file_to_build: Dockerfile
platforms: linux/amd64,linux/arm64
use_native_arm64_builder: false
push_to_images: |
@@ -39,3 +40,19 @@ jobs:
tags: |
type=ref,event=pr
secrets: inherit
build-image-streaming:
needs: compute-suffix
uses: ./.github/workflows/build-container-image.yml
with:
file_to_build: streaming/Dockerfile
platforms: linux/amd64,linux/arm64
use_native_arm64_builder: false
push_to_images: |
ghcr.io/${{ github.repository_owner }}/mastodon-streaming
version_metadata: ${{ needs.compute-suffix.outputs.metadata }}
flavor: |
latest=auto
tags: |
type=ref,event=pr
secrets: inherit

View File

@@ -12,6 +12,7 @@ jobs:
build-image:
uses: ./.github/workflows/build-container-image.yml
with:
file_to_build: Dockerfile
platforms: linux/amd64,linux/arm64
use_native_arm64_builder: false
push_to_images: |
@@ -26,3 +27,23 @@ jobs:
type=pep440,pattern={{raw}}
type=pep440,pattern=v{{major}}.{{minor}}
secrets: inherit
build-image-streaming:
if: startsWith(github.ref, 'refs/tags/v4.3.')
uses: ./.github/workflows/build-container-image.yml
with:
file_to_build: streaming/Dockerfile
platforms: linux/amd64,linux/arm64
use_native_arm64_builder: false
push_to_images: |
ghcr.io/${{ github.repository_owner }}/mastodon-streaming
# Do not use cache when building releases, so apt update is always ran and the release always contain the latest packages
cache: false
# Only tag with latest when ran against the latest stable branch
# This needs to be updated after each minor version release
flavor: |
latest=${{ startsWith(github.ref, 'refs/tags/v4.3.') }}
tags: |
type=pep440,pattern={{raw}}
type=pep440,pattern=v{{major}}.{{minor}}
secrets: inherit

View File

@@ -7,6 +7,7 @@ on:
- .github/workflows/build-releases.yml
- .github/workflows/test-image-build.yml
- Dockerfile
- streaming/Dockerfile
permissions:
contents: read
@@ -18,4 +19,17 @@ jobs:
uses: ./.github/workflows/build-container-image.yml
with:
file_to_build: Dockerfile
platforms: linux/amd64 # Testing only on native platform so it is performant
cache: true
build-image-streaming:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-streaming
cancel-in-progress: true
uses: ./.github/workflows/build-container-image.yml
with:
file_to_build: streaming/Dockerfile
platforms: linux/amd64 # Testing only on native platform so it is performant
cache: true

View File

@@ -1,33 +1,21 @@
# This configuration was generated by
# `haml-lint --auto-gen-config`
# on 2023-10-26 09:32:34 -0400 using Haml-Lint version 0.51.0.
# on 2023-12-15 11:02:19 -0500 using Haml-Lint version 0.52.0.
# The point is for the user to remove these configuration records
# one by one as the lints are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of Haml-Lint, may require this file to be generated again.
linters:
# Offense count: 16
# Offense count: 11
LineLength:
exclude:
- 'app/views/admin/account_actions/new.html.haml'
- 'app/views/admin/accounts/index.html.haml'
- 'app/views/admin/ip_blocks/new.html.haml'
- 'app/views/admin/roles/_form.html.haml'
- 'app/views/admin/settings/discovery/show.html.haml'
- 'app/views/auth/registrations/edit.html.haml'
- 'app/views/auth/registrations/new.html.haml'
- 'app/views/filters/_filter_fields.html.haml'
- 'app/views/media/player.html.haml'
- 'app/views/settings/applications/_fields.html.haml'
- 'app/views/settings/imports/index.html.haml'
- 'app/views/settings/preferences/appearance/show.html.haml'
- 'app/views/settings/preferences/notifications/show.html.haml'
- 'app/views/settings/preferences/other/show.html.haml'
# Offense count: 9
RuboCop:
exclude:
- 'app/views/admin/accounts/_buttons.html.haml'
- 'app/views/admin/accounts/_local_account.html.haml'
- 'app/views/admin/roles/_form.html.haml'

View File

@@ -105,6 +105,21 @@ Rails/Exit:
- 'config/boot.rb'
- 'lib/mastodon/cli/*.rb'
Rails/SkipsModelValidations:
Exclude:
- 'db/*migrate/**/*'
# Reason: We want to preserve the ability to migrate from arbitrary old versions,
# and cannot guarantee that every installation has run every migration as they upgrade.
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsunusedignoredcolumns
Rails/UnusedIgnoredColumns:
Enabled: false
# Reason: Prevailing style choice
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsnegateinclude
Rails/NegateInclude:
Enabled: false
# Reason: Some single letter camel case files shouldn't be split
# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecfilepath
RSpec/FilePath:

View File

@@ -26,9 +26,7 @@ Lint/NonLocalExitFromIterator:
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
Metrics/AbcSize:
Max: 144
Exclude:
- 'app/serializers/initial_state_serializer.rb'
Max: 100
# Configuration parameters: CountBlocks, Max.
Metrics/BlockNesting:
@@ -109,25 +107,11 @@ Rails/ApplicationController:
# Include: app/models/**/*.rb
Rails/HasAndBelongsToMany:
Exclude:
- 'app/models/concerns/account_associations.rb'
- 'app/models/concerns/account/associations.rb'
- 'app/models/preview_card.rb'
- 'app/models/status.rb'
- 'app/models/tag.rb'
# Configuration parameters: Include.
# Include: app/models/**/*.rb
Rails/HasManyOrHasOneDependent:
Exclude:
- 'app/models/concerns/account_counters.rb'
- 'app/models/conversation.rb'
- 'app/models/custom_emoji.rb'
- 'app/models/custom_emoji_category.rb'
- 'app/models/domain_block.rb'
- 'app/models/invite.rb'
- 'app/models/status.rb'
- 'app/models/user.rb'
- 'app/models/web/push_subscription.rb'
# Configuration parameters: Include.
# Include: app/controllers/**/*.rb, app/mailers/**/*.rb
Rails/LexicallyScopedActionFilter:
@@ -135,23 +119,6 @@ Rails/LexicallyScopedActionFilter:
- 'app/controllers/auth/passwords_controller.rb'
- 'app/controllers/auth/registrations_controller.rb'
# This cop supports unsafe autocorrection (--autocorrect-all).
Rails/NegateInclude:
Exclude:
- 'app/controllers/concerns/signature_verification.rb'
- 'app/helpers/jsonld_helper.rb'
- 'app/lib/activitypub/activity/create.rb'
- 'app/lib/activitypub/activity/move.rb'
- 'app/lib/feed_manager.rb'
- 'app/lib/link_details_extractor.rb'
- 'app/models/concerns/attachmentable.rb'
- 'app/models/concerns/remotable.rb'
- 'app/models/custom_filter.rb'
- 'app/services/activitypub/process_status_update_service.rb'
- 'app/services/fetch_link_card_service.rb'
- 'app/workers/web/push_notification_worker.rb'
- 'lib/paperclip/color_extractor.rb'
Rails/OutputSafety:
Exclude:
- 'config/initializers/simple_form.rb'
@@ -174,7 +141,7 @@ Rails/SkipsModelValidations:
Exclude:
- 'app/controllers/admin/invites_controller.rb'
- 'app/controllers/concerns/session_tracking_concern.rb'
- 'app/models/concerns/account_merging.rb'
- 'app/models/concerns/account/merging.rb'
- 'app/models/concerns/expireable.rb'
- 'app/models/status.rb'
- 'app/models/trends/links.rb'
@@ -197,22 +164,6 @@ Rails/SkipsModelValidations:
- 'app/workers/move_worker.rb'
- 'app/workers/scheduler/ip_cleanup_scheduler.rb'
- 'app/workers/scheduler/scheduled_statuses_scheduler.rb'
- 'db/migrate/20161203164520_add_from_account_id_to_notifications.rb'
- 'db/migrate/20170105224407_add_shortcode_to_media_attachments.rb'
- 'db/migrate/20170209184350_add_reply_to_statuses.rb'
- 'db/migrate/20170304202101_add_type_to_media_attachments.rb'
- 'db/migrate/20180528141303_fix_accounts_unique_index.rb'
- 'db/migrate/20180609104432_migrate_web_push_subscriptions2.rb'
- 'db/migrate/20181207011115_downcase_custom_emoji_domains.rb'
- 'db/migrate/20190511134027_add_silenced_at_suspended_at_to_accounts.rb'
- 'db/migrate/20191007013357_update_pt_locales.rb'
- 'db/migrate/20220316233212_update_kurdish_locales.rb'
- 'db/post_migrate/20190511152737_remove_suspended_silenced_account_fields.rb'
- 'db/post_migrate/20200917193528_migrate_notifications_type.rb'
- 'db/post_migrate/20201017234926_fill_account_suspension_origin.rb'
- 'db/post_migrate/20220617202502_migrate_roles.rb'
- 'db/post_migrate/20221101190723_backfill_admin_action_logs.rb'
- 'db/post_migrate/20221206114142_backfill_admin_action_logs_again.rb'
- 'lib/mastodon/cli/accounts.rb'
- 'lib/mastodon/cli/maintenance.rb'
- 'spec/lib/activitypub/activity/follow_spec.rb'
@@ -228,19 +179,6 @@ Rails/UniqueValidationWithoutIndex:
- 'app/models/identity.rb'
- 'app/models/webauthn_credential.rb'
# Configuration parameters: Include.
# Include: app/models/**/*.rb
Rails/UnusedIgnoredColumns:
Exclude:
- 'app/models/account.rb'
- 'app/models/account_stat.rb'
- 'app/models/admin/action_log.rb'
- 'app/models/custom_filter.rb'
- 'app/models/email_domain_block.rb'
- 'app/models/report.rb'
- 'app/models/status_edit.rb'
- 'app/models/user.rb'
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: EnforcedStyle.
# SupportedStyles: exists, where
@@ -254,7 +192,7 @@ Rails/WhereExists:
- 'app/lib/feed_manager.rb'
- 'app/lib/status_cache_hydrator.rb'
- 'app/lib/suspicious_sign_in_detector.rb'
- 'app/models/concerns/account_interactions.rb'
- 'app/models/concerns/account/interactions.rb'
- 'app/models/featured_tag.rb'
- 'app/models/poll.rb'
- 'app/models/session_activation.rb'
@@ -309,7 +247,7 @@ Style/FetchEnvVar:
- 'config/initializers/devise.rb'
- 'config/initializers/paperclip.rb'
- 'config/initializers/vapid.rb'
- 'lib/mastodon/premailer_webpack_strategy.rb'
- 'lib/premailer_webpack_strategy.rb'
- 'lib/mastodon/redis_config.rb'
- 'lib/tasks/repo.rake'
- 'spec/features/profile_spec.rb'
@@ -344,8 +282,8 @@ Style/GuardClause:
- 'app/lib/request_pool.rb'
- 'app/lib/webfinger.rb'
- 'app/lib/webfinger_resource.rb'
- 'app/models/concerns/account_counters.rb'
- 'app/models/concerns/ldap_authenticable.rb'
- 'app/models/concerns/account/counters.rb'
- 'app/models/concerns/user/ldap_authenticable.rb'
- 'app/models/tag.rb'
- 'app/models/user.rb'
- 'app/services/fan_out_on_write_service.rb'
@@ -359,8 +297,8 @@ Style/GuardClause:
- 'config/initializers/devise.rb'
- 'db/migrate/20170901141119_truncate_preview_cards.rb'
- 'db/post_migrate/20220704024901_migrate_settings_to_user_roles.rb'
- 'lib/devise/two_factor_ldap_authenticatable.rb'
- 'lib/devise/two_factor_pam_authenticatable.rb'
- 'lib/devise/strategies/two_factor_ldap_authenticatable.rb'
- 'lib/devise/strategies/two_factor_pam_authenticatable.rb'
- 'lib/mastodon/cli/accounts.rb'
- 'lib/mastodon/cli/maintenance.rb'
- 'lib/mastodon/cli/media.rb'
@@ -374,8 +312,8 @@ 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/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'
@@ -394,22 +332,6 @@ Style/IfUnlessModifier:
- 'config/initializers/devise.rb'
- 'config/initializers/ffmpeg.rb'
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: InverseMethods, InverseBlocks.
Style/InverseMethods:
Exclude:
- 'app/models/custom_filter.rb'
- 'app/services/update_account_service.rb'
- 'spec/controllers/activitypub/replies_controller_spec.rb'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle.
# SupportedStyles: line_count_dependent, lambda, literal
Style/Lambda:
Exclude:
- 'config/initializers/simple_form.rb'
- 'config/routes.rb'
# This cop supports unsafe autocorrection (--autocorrect-all).
Style/MapToHash:
Exclude:
@@ -474,40 +396,26 @@ Style/RedundantFetchBlock:
- 'config/initializers/paperclip.rb'
- 'config/puma.rb'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: AllowMultipleReturnValues.
Style/RedundantReturn:
Exclude:
- 'app/controllers/api/v1/directories_controller.rb'
- 'app/controllers/auth/confirmations_controller.rb'
- 'app/lib/ostatus/tag_manager.rb'
- 'app/models/form/import.rb'
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: ConvertCodeThatCanStartToReturnNil, AllowedMethods, MaxChainLength.
# AllowedMethods: present?, blank?, presence, try, try!
Style/SafeNavigation:
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/two_factor_ldap_authenticatable.rb'
- 'lib/devise/two_factor_pam_authenticatable.rb'
- '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 safe autocorrection (--autocorrect).
Style/StderrPuts:
Exclude:
- 'config/boot.rb'
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: Mode.
Style/StringConcatenation:
@@ -526,13 +434,6 @@ Style/StringLiterals:
- 'config/initializers/webauthn.rb'
- 'config/routes.rb'
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: AllowMethodsWithArguments, AllowedMethods, AllowedPatterns, AllowComments.
# AllowedMethods: define_method, mail, respond_to
Style/SymbolProc:
Exclude:
- 'config/initializers/3_omniauth.rb'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle, AllowSafeAssignment.
# SupportedStyles: require_parentheses, require_no_parentheses, require_parentheses_when_complex

View File

@@ -50,6 +50,10 @@ You can contribute in the following ways:
If your contributions are accepted into Mastodon, you can request to be paid through [our OpenCollective](https://opencollective.com/mastodon).
## API Changes and Additions
Please note that any changes or additions made to the API should have an accompanying pull request on [our documentation repository](https://github.com/mastodon/documentation).
## Bug reports
Bug reports and feature suggestions must use descriptive and concise titles and be submitted to [GitHub Issues](https://github.com/mastodon/mastodon/issues). Please use the search function to make sure that you are not submitting duplicates, and that a similar report or request has not already been resolved or rejected.

View File

@@ -1,112 +1,259 @@
# syntax=docker/dockerfile:1.4
# This needs to be bookworm-slim because the Ruby image is built on bookworm-slim
ARG NODE_VERSION="20.9-bookworm-slim"
FROM ghcr.io/moritzheiber/ruby-jemalloc:3.2.2-slim as ruby
FROM node:${NODE_VERSION} as build
# Please see https://docs.docker.com/engine/reference/builder for information about
# the extended buildx capabilities used in this file.
# Make sure multiarch TARGETPLATFORM is available for interpolation
# See: https://docs.docker.com/build/building/multi-platform/
ARG TARGETPLATFORM=${TARGETPLATFORM}
ARG BUILDPLATFORM=${BUILDPLATFORM}
COPY --link --from=ruby /opt/ruby /opt/ruby
# Ruby image to use for base image, change with [--build-arg RUBY_VERSION="3.2.2"]
ARG RUBY_VERSION="3.2.2"
# # Node version to use in base image, change with [--build-arg NODE_MAJOR_VERSION="20"]
ARG NODE_MAJOR_VERSION="20"
# Debian image to use for base image, change with [--build-arg DEBIAN_VERSION="bookworm"]
ARG DEBIAN_VERSION="bookworm"
# 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
# Ruby image to use for base image based on combined variables (ex: 3.2.2-slim-bookworm)
FROM docker.io/ruby:${RUBY_VERSION}-slim-${DEBIAN_VERSION} as ruby
ENV DEBIAN_FRONTEND="noninteractive" \
PATH="${PATH}:/opt/ruby/bin"
# Resulting version string is vX.X.X-MASTODON_VERSION_PRERELEASE+MASTODON_VERSION_METADATA
# Example: v4.2.0-nightly.2023.11.09+something
# Overwrite existance of 'alpha.0' in version.rb [--build-arg MASTODON_VERSION_PRERELEASE="nightly.2023.11.09"]
ARG MASTODON_VERSION_PRERELEASE=""
# Append build metadata or fork information to version.rb [--build-arg MASTODON_VERSION_METADATA="something"]
ARG MASTODON_VERSION_METADATA=""
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
# Allow Ruby on Rails to serve static files
# See: https://docs.joinmastodon.org/admin/config/#rails_serve_static_files
ARG RAILS_SERVE_STATIC_FILES="true"
# Allow to use YJIT compiler
# See: https://github.com/ruby/ruby/blob/master/doc/yjit/yjit.md
ARG RUBY_YJIT_ENABLE="1"
# Timezone used by the Docker container and runtime, change with [--build-arg TZ=Europe/Berlin]
ARG TZ="Etc/UTC"
# Linux UID (user id) for the mastodon user, change with [--build-arg UID=1234]
ARG UID="991"
# Linux GID (group id) for the mastodon user, change with [--build-arg GID=1234]
ARG GID="991"
# Apply Mastodon build options based on options above
ENV \
# Apply Mastodon version information
MASTODON_VERSION_PRERELEASE="${MASTODON_VERSION_PRERELEASE}" \
MASTODON_VERSION_METADATA="${MASTODON_VERSION_METADATA}" \
# Apply Mastodon static files and YJIT options
RAILS_SERVE_STATIC_FILES=${RAILS_SERVE_STATIC_FILES} \
RUBY_YJIT_ENABLE=${RUBY_YJIT_ENABLE} \
# Apply timezone
TZ=${TZ}
ENV \
# Configure the IP to bind Mastodon to when serving traffic
BIND="0.0.0.0" \
# Use production settings for Yarn, Node and related nodejs based tools
NODE_ENV="production" \
# Use production settings for Ruby on Rails
RAILS_ENV="production" \
# Add Ruby and Mastodon installation to the PATH
DEBIAN_FRONTEND="noninteractive" \
PATH="${PATH}:/opt/ruby/bin:/opt/mastodon/bin" \
# Optimize jemalloc 5.x performance
MALLOC_CONF="narenas:2,background_thread:true,thp:never,dirty_decay_ms:1000,muzzy_decay_ms:0"
# Set default shell used for running commands
SHELL ["/bin/bash", "-o", "pipefail", "-o", "errexit", "-c"]
ARG TARGETPLATFORM
RUN echo "Target platform is $TARGETPLATFORM"
RUN \
# Remove automatic apt cache Docker cleanup scripts
rm -f /etc/apt/apt.conf.d/docker-clean; \
# Sets timezone
echo "${TZ}" > /etc/localtime; \
# Creates mastodon user/group and sets home directory
groupadd -g "${GID}" mastodon; \
useradd -l -u "${UID}" -g "${GID}" -m -d /opt/mastodon mastodon; \
# Creates /mastodon symlink to /opt/mastodon
ln -s /opt/mastodon /mastodon;
# Set /opt/mastodon as working directory
WORKDIR /opt/mastodon
# hadolint ignore=DL3008
RUN apt-get update && \
apt-get -yq dist-upgrade && \
apt-get install -y --no-install-recommends build-essential \
git \
libicu-dev \
libidn-dev \
libpq-dev \
libjemalloc-dev \
zlib1g-dev \
libgdbm-dev \
libgmp-dev \
libssl-dev \
libyaml-dev \
ca-certificates \
libreadline8 \
python3 \
shared-mime-info && \
bundle config set --local deployment 'true' && \
bundle config set --local without 'development test' && \
bundle config set silence_root_warning true && \
corepack enable
# hadolint ignore=DL3008,DL3005
RUN \
# Mount Apt cache and lib directories from Docker buildx caches
--mount=type=cache,id=apt-cache-${TARGETPLATFORM},target=/var/cache/apt,sharing=locked \
--mount=type=cache,id=apt-lib-${TARGETPLATFORM},target=/var/lib/apt,sharing=locked \
# Apt update & upgrade to check for security updates to Debian image
apt-get update; \
apt-get dist-upgrade -yq; \
# Install jemalloc, curl and other necessary components
apt-get install -y --no-install-recommends \
ca-certificates \
curl \
ffmpeg \
file \
imagemagick \
libjemalloc2 \
patchelf \
procps \
tini \
tzdata \
; \
# Patch Ruby to use jemalloc
patchelf --add-needed libjemalloc.so.2 /usr/local/bin/ruby; \
# Discard patchelf after use
apt-get purge -y \
patchelf \
;
COPY Gemfile* package.json yarn.lock .yarnrc.yml /opt/mastodon/
# Create temporary build layer from base image
FROM ruby as build
# Copy Node package configuration files into working directory
COPY package.json yarn.lock .yarnrc.yml /opt/mastodon/
COPY .yarn /opt/mastodon/.yarn
COPY --from=node /usr/local/bin /usr/local/bin
COPY --from=node /usr/local/lib /usr/local/lib
ARG TARGETPLATFORM
# hadolint ignore=DL3008
RUN \
# Mount Apt cache and lib directories from Docker buildx caches
--mount=type=cache,id=apt-cache-${TARGETPLATFORM},target=/var/cache/apt,sharing=locked \
--mount=type=cache,id=apt-lib-${TARGETPLATFORM},target=/var/lib/apt,sharing=locked \
# Install build tools and bundler dependencies from APT
apt-get install -y --no-install-recommends \
g++ \
gcc \
git \
libgdbm-dev \
libgmp-dev \
libicu-dev \
libidn-dev \
libpq-dev \
libssl-dev \
make \
shared-mime-info \
zlib1g-dev \
;
RUN \
# Configure Corepack
rm /usr/local/bin/yarn*; \
corepack enable; \
corepack prepare --activate;
# Create temporary bundler specific build layer from build layer
FROM build as bundler
ARG TARGETPLATFORM
# Copy Gemfile config into working directory
COPY Gemfile* /opt/mastodon/
RUN \
# Mount Ruby Gem caches
--mount=type=cache,id=gem-cache-${TARGETPLATFORM},target=/usr/local/bundle/cache/,sharing=locked \
# Configure bundle to prevent changes to Gemfile and Gemfile.lock
bundle config set --global frozen "true"; \
# Configure bundle to not cache downloaded Gems
bundle config set --global cache_all "false"; \
# Configure bundle to only process production Gems
bundle config set --local without "development test"; \
# Configure bundle to not warn about root user
bundle config set silence_root_warning "true"; \
# Download and install required Gems
bundle install -j"$(nproc)";
# Create temporary node specific build layer from build layer
FROM build as yarn
ARG TARGETPLATFORM
# Copy Node package configuration files into working directory
COPY package.json yarn.lock .yarnrc.yml /opt/mastodon/
COPY streaming/package.json /opt/mastodon/streaming/
COPY .yarn /opt/mastodon/.yarn
RUN bundle install -j"$(nproc)"
# hadolint ignore=DL3008
RUN \
--mount=type=cache,id=corepack-cache-${TARGETPLATFORM},target=/usr/local/share/.cache/corepack,sharing=locked \
--mount=type=cache,id=yarn-cache-${TARGETPLATFORM},target=/usr/local/share/.cache/yarn,sharing=locked \
# Install Node packages
yarn workspaces focus --production @mastodon/mastodon;
RUN yarn workspaces focus --all --production && \
yarn cache clean
# Create temporary assets build layer from build layer
FROM build as precompiler
FROM node:${NODE_VERSION}
# Copy Mastodon sources into precompiler layer
COPY . /opt/mastodon/
# Use those args to specify your own version flags & suffixes
ARG MASTODON_VERSION_PRERELEASE=""
ARG MASTODON_VERSION_METADATA=""
# Copy bundler and node packages from build layer to container
COPY --from=yarn /opt/mastodon /opt/mastodon/
COPY --from=bundler /opt/mastodon /opt/mastodon/
COPY --from=bundler /usr/local/bundle/ /usr/local/bundle/
ARG UID="991"
ARG GID="991"
ARG TARGETPLATFORM
COPY --link --from=ruby /opt/ruby /opt/ruby
RUN \
# Use Ruby on Rails to create Mastodon assets
OTP_SECRET=precompile_placeholder SECRET_KEY_BASE=precompile_placeholder bundle exec rails assets:precompile; \
# Cleanup temporary files
rm -fr /opt/mastodon/tmp;
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
# Prep final Mastodon Ruby layer
FROM ruby as mastodon
ENV DEBIAN_FRONTEND="noninteractive" \
PATH="${PATH}:/opt/ruby/bin:/opt/mastodon/bin"
ARG TARGETPLATFORM
# Ignoring these here since we don't want to pin any versions and the Debian image removes apt-get content after use
# hadolint ignore=DL3008,DL3009
RUN apt-get update && \
echo "Etc/UTC" > /etc/localtime && \
groupadd -g "${GID}" mastodon && \
useradd -l -u "$UID" -g "${GID}" -m -d /opt/mastodon mastodon && \
apt-get -y --no-install-recommends install whois \
wget \
procps \
libssl3 \
libpq5 \
imagemagick \
ffmpeg \
libjemalloc2 \
libicu72 \
libidn12 \
libyaml-0-2 \
file \
ca-certificates \
tzdata \
libreadline8 \
tini && \
ln -s /opt/mastodon /mastodon && \
corepack enable
# hadolint ignore=DL3008
RUN \
# Mount Apt cache and lib directories from Docker buildx caches
--mount=type=cache,id=apt-cache-${TARGETPLATFORM},target=/var/cache/apt,sharing=locked \
--mount=type=cache,id=apt-lib-${TARGETPLATFORM},target=/var/lib/apt,sharing=locked \
# Mount Corepack and Yarn caches from Docker buildx caches
--mount=type=cache,id=corepack-cache-${TARGETPLATFORM},target=/usr/local/share/.cache/corepack,sharing=locked \
--mount=type=cache,id=yarn-cache-${TARGETPLATFORM},target=/usr/local/share/.cache/yarn,sharing=locked \
# Apt update install non-dev versions of necessary components
apt-get install -y --no-install-recommends \
libssl3 \
libpq5 \
libicu72 \
libidn12 \
libreadline8 \
libyaml-0-2 \
;
# Note: no, cleaning here since Debian does this automatically
# See the file /etc/apt/apt.conf.d/docker-clean within the Docker image's filesystem
# Copy Mastodon sources into final layer
COPY . /opt/mastodon/
COPY --chown=mastodon:mastodon . /opt/mastodon
COPY --chown=mastodon:mastodon --from=build /opt/mastodon /opt/mastodon
# Copy compiled assets to layer
COPY --from=precompiler /opt/mastodon/public/packs /opt/mastodon/public/packs
COPY --from=precompiler /opt/mastodon/public/assets /opt/mastodon/public/assets
# Copy bundler components to layer
COPY --from=bundler /usr/local/bundle/ /usr/local/bundle/
ENV RAILS_ENV="production" \
NODE_ENV="production" \
RAILS_SERVE_STATIC_FILES="true" \
BIND="0.0.0.0" \
MASTODON_VERSION_PRERELEASE="${MASTODON_VERSION_PRERELEASE}" \
MASTODON_VERSION_METADATA="${MASTODON_VERSION_METADATA}"
RUN \
# Precompile bootsnap code for faster Rails startup
bundle exec bootsnap precompile --gemfile app/ lib/;
# Set the run user
RUN \
# Pre-create and chown system volume to Mastodon user
mkdir -p /opt/mastodon/public/system; \
chown mastodon:mastodon /opt/mastodon/public/system; \
# Set Mastodon user as owner of tmp folder
chown -R mastodon:mastodon /opt/mastodon/tmp;
# Set the running user for resulting container
USER mastodon
WORKDIR /opt/mastodon
# Precompile assets
RUN OTP_SECRET=precompile_placeholder SECRET_KEY_BASE=precompile_placeholder rails assets:precompile
# Set the work dir and the container entry point
ENTRYPOINT ["/usr/bin/tini", "--"]
EXPOSE 3000 4000
# Expose default Puma ports
EXPOSE 3000
# Set container tini as default entry point
ENTRYPOINT ["/usr/bin/tini", "--"]

View File

@@ -5,7 +5,7 @@ ruby '>= 3.0.0'
gem 'puma', '~> 6.3'
gem 'rails', '~> 7.1.1'
gem 'sprockets', '~> 3.7.2'
gem 'propshaft'
gem 'thor', '~> 1.2'
gem 'rack', '~> 2.2.7'
@@ -89,7 +89,6 @@ gem 'sidekiq-unique-jobs', '~> 7.1'
gem 'sidekiq-bulk', '~> 0.2.0'
gem 'simple-navigation', '~> 4.4'
gem 'simple_form', '~> 5.2'
gem 'sprockets-rails', '~> 3.4', require: 'sprockets/railtie'
gem 'stoplight', '~> 3.0.1'
gem 'strong_migrations', '1.6.4'
gem 'tty-prompt', '~> 0.23', require: false

View File

@@ -118,7 +118,7 @@ GEM
minitest (>= 5.1)
mutex_m
tzinfo (~> 2.0)
addressable (2.8.5)
addressable (2.8.6)
public_suffix (>= 2.0.2, < 6.0)
aes_key_wrap (1.1.0)
android_key_attestation (0.3.0)
@@ -156,7 +156,7 @@ GEM
nokogiri (~> 1, >= 1.10.8)
base64 (0.2.0)
bcp47_spec (0.2.1)
bcrypt (3.1.19)
bcrypt (3.1.20)
better_errors (2.10.1)
erubi (>= 1.0.0)
rack (>= 0.9.0)
@@ -168,14 +168,14 @@ GEM
erubi (~> 1.4)
parser (>= 2.4)
smart_properties
bigdecimal (3.1.4)
bigdecimal (3.1.5)
bindata (2.4.15)
binding_of_caller (1.0.0)
debug_inspector (>= 0.0.1)
blurhash (0.1.7)
bootsnap (1.17.0)
msgpack (~> 1.2)
brakeman (6.0.1)
brakeman (6.1.0)
browser (5.3.1)
brpoplpush-redis_script (0.1.3)
concurrent-ruby (~> 1.0, >= 1.0.5)
@@ -197,7 +197,7 @@ GEM
activesupport
cbor (0.5.9.6)
charlock_holmes (0.7.7)
chewy (7.3.4)
chewy (7.4.0)
activesupport (>= 5.2)
elasticsearch (>= 7.12.0, < 7.14.0)
elasticsearch-dsl
@@ -220,9 +220,9 @@ GEM
database_cleaner-core (~> 2.0.0)
database_cleaner-core (2.0.1)
date (3.3.4)
debug (1.8.0)
irb (>= 1.5.0)
reline (>= 0.3.1)
debug (1.9.0)
irb (~> 1.10)
reline (>= 0.3.8)
debug_inspector (1.1.0)
devise (4.9.3)
bcrypt (~> 3.0)
@@ -245,7 +245,7 @@ GEM
docile (1.4.0)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
doorkeeper (5.6.7)
doorkeeper (5.6.8)
railties (>= 5)
dotenv (2.8.1)
dotenv-rails (2.8.1)
@@ -326,7 +326,7 @@ GEM
ruby-progressbar (~> 1.4)
globalid (1.2.1)
activesupport (>= 6.1)
haml (6.2.0)
haml (6.3.0)
temple (>= 0.8.2)
thor
tilt
@@ -335,7 +335,7 @@ GEM
activesupport (>= 5.1)
haml (>= 4.0.6)
railties (>= 5.1)
haml_lint (0.51.0)
haml_lint (0.52.0)
haml (>= 4.0)
parallel (~> 1.10)
rainbow
@@ -377,11 +377,11 @@ GEM
terminal-table (>= 1.5.1)
idn-ruby (0.1.5)
io-console (0.6.0)
irb (1.9.1)
irb (1.10.1)
rdoc
reline (>= 0.3.8)
jmespath (1.6.2)
json (2.6.3)
json (2.7.1)
json-canonicalization (1.0.0)
json-jwt (1.15.3)
activesupport (>= 4.2)
@@ -484,7 +484,8 @@ GEM
nokogiri (1.15.5)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
oj (3.16.1)
oj (3.16.3)
bigdecimal (>= 3.0)
omniauth (2.1.1)
hashie (>= 3.4.6)
rack (>= 2.2.3)
@@ -514,7 +515,7 @@ GEM
openssl (> 2.0)
orm_adapter (0.5.0)
ox (2.14.17)
parallel (1.23.0)
parallel (1.24.0)
parser (3.2.2.4)
ast (~> 2.4.1)
racc
@@ -522,7 +523,7 @@ GEM
pastel (0.8.0)
tty-color (~> 0.5)
pg (1.5.4)
pghero (3.3.4)
pghero (3.4.0)
activerecord (>= 6)
posix-spawn (0.3.15)
premailer (1.21.0)
@@ -534,6 +535,11 @@ GEM
net-smtp
premailer (~> 1.7, >= 1.7.9)
private_address_check (0.5.0)
propshaft (0.8.0)
actionpack (>= 7.0.0)
activesupport (>= 7.0.0)
rack
railties (>= 7.0.0)
psych (5.1.1.1)
stringio
public_suffix (5.0.4)
@@ -608,7 +614,7 @@ GEM
link_header (~> 0.0, >= 0.0.8)
rdf-normalize (0.6.1)
rdf (~> 3.2)
rdoc (6.6.0)
rdoc (6.6.1)
psych (>= 4.0.0)
redcarpet (3.6.0)
redis (4.8.1)
@@ -616,8 +622,8 @@ GEM
redis (>= 4)
redlock (1.3.2)
redis (>= 3.0.0, < 6.0)
regexp_parser (2.8.2)
reline (0.4.0)
regexp_parser (2.8.3)
reline (0.4.1)
io-console (~> 0.5)
request_store (1.5.1)
rack (>= 1.4)
@@ -656,7 +662,7 @@ GEM
rspec-mocks (~> 3.0)
sidekiq (>= 5, < 8)
rspec-support (3.12.1)
rubocop (1.57.2)
rubocop (1.59.0)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
@@ -664,7 +670,7 @@ GEM
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.28.1, < 2.0)
rubocop-ast (>= 1.30.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.30.0)
@@ -673,10 +679,10 @@ GEM
rubocop (~> 1.41)
rubocop-factory_bot (2.24.0)
rubocop (~> 1.33)
rubocop-performance (1.19.1)
rubocop (>= 1.7.0, < 2.0)
rubocop-ast (>= 0.4.0)
rubocop-rails (2.22.2)
rubocop-performance (1.20.0)
rubocop (>= 1.48.1, < 2.0)
rubocop-ast (>= 1.30.0, < 2.0)
rubocop-rails (2.23.0)
activesupport (>= 4.2.0)
rack (>= 1.1)
rubocop (>= 1.33.0, < 2.0)
@@ -702,7 +708,7 @@ GEM
scenic (1.7.0)
activerecord (>= 4.0.0)
railties (>= 4.0.0)
selenium-webdriver (4.15.0)
selenium-webdriver (4.16.0)
rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 3.0)
websocket (~> 1.0)
@@ -736,18 +742,11 @@ GEM
simplecov-lcov (0.8.0)
simplecov_json_formatter (0.1.4)
smart_properties (1.17.0)
sprockets (3.7.2)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
sprockets-rails (3.4.2)
actionpack (>= 5.2)
activesupport (>= 5.2)
sprockets (>= 3.0.0)
stackprof (0.2.25)
statsd-ruby (1.5.0)
stoplight (3.0.2)
redlock (~> 1.0)
stringio (3.0.9)
stringio (3.1.0)
strong_migrations (1.6.4)
activerecord (>= 5.2)
swd (1.3.0)
@@ -755,12 +754,12 @@ GEM
attr_required (>= 0.0.5)
httpclient (>= 2.4)
sysexits (1.2.0)
temple (0.10.2)
temple (0.10.3)
terminal-table (3.0.2)
unicode-display_width (>= 1.1.1, < 3)
terrapin (0.6.0)
climate_control (>= 0.0.3, < 1.0)
test-prof (1.3.0)
test-prof (1.3.1)
thor (1.3.0)
tilt (2.3.0)
timeout (0.4.1)
@@ -911,6 +910,7 @@ DEPENDENCIES
posix-spawn
premailer-rails
private_address_check (~> 0.5)
propshaft
public_suffix (~> 5.0)
puma (~> 6.3)
pundit (~> 2.3)
@@ -949,8 +949,6 @@ DEPENDENCIES
simple_form (~> 5.2)
simplecov (~> 0.22)
simplecov-lcov (~> 0.8)
sprockets (~> 3.7.2)
sprockets-rails (~> 3.4)
stackprof
stoplight (~> 3.0.1)
strong_migrations (= 1.6.4)

6
Vagrantfile vendored
View File

@@ -10,7 +10,11 @@ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
sudo apt-add-repository 'deb https://dl.yarnpkg.com/debian/ stable main'
# Add repo for NodeJS
curl -sL https://deb.nodesource.com/setup_16.x | sudo bash -
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
NODE_MAJOR=20
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list
sudo apt-get update
# Add firewall rule to redirect 80 to PORT and save
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port #{ENV["PORT"]}

View File

@@ -50,7 +50,7 @@ class AccountsController < ApplicationController
end
def only_media_scope
Status.joins(:media_attachments).merge(@account.media_attachments.reorder(nil)).group(:id)
Status.joins(:media_attachments).merge(@account.media_attachments).group(:id)
end
def no_replies_scope

View File

@@ -16,7 +16,7 @@ module Admin
@moderation_notes = @account.targeted_moderation_notes.latest
@warnings = @account.strikes.custom.latest
render template: 'admin/accounts/show'
render 'admin/accounts/show'
end
end

View File

@@ -6,7 +6,7 @@ module Admin
def index
authorize :audit_log, :index?
@auditable_accounts = Account.where(id: Admin::ActionLog.reorder(nil).select('distinct account_id')).select(:id, :username)
@auditable_accounts = Account.where(id: Admin::ActionLog.select('distinct account_id')).select(:id, :username)
end
private

View File

@@ -4,7 +4,7 @@ require 'csv'
module Admin
class ExportDomainAllowsController < BaseController
include AdminExportControllerConcern
include Admin::ExportControllerConcern
before_action :set_dummy_import!, only: [:new]

View File

@@ -4,7 +4,7 @@ require 'csv'
module Admin
class ExportDomainBlocksController < BaseController
include AdminExportControllerConcern
include Admin::ExportControllerConcern
before_action :set_dummy_import!, only: [:new]

View File

@@ -24,7 +24,7 @@ module Admin
@relay.enable!
redirect_to admin_relays_path
else
render action: :new
render :new
end
end

View File

@@ -26,7 +26,7 @@ module Admin
@form = Admin::StatusBatchAction.new
@statuses = @report.statuses.with_includes
render template: 'admin/reports/show'
render 'admin/reports/show'
end
end

View File

@@ -4,9 +4,9 @@ class Api::BaseController < ApplicationController
DEFAULT_STATUSES_LIMIT = 20
DEFAULT_ACCOUNTS_LIMIT = 40
include RateLimitHeaders
include AccessTokenTrackingConcern
include ApiCachingConcern
include Api::RateLimitHeaders
include Api::AccessTokenTrackingConcern
include Api::CachingConcern
include Api::ContentSecurityPolicy
skip_before_action :require_functional!, unless: :limited_federation_mode?
@@ -64,7 +64,7 @@ class Api::BaseController < ApplicationController
end
def doorkeeper_unauthorized_render_options(error: nil)
{ json: { error: (error.try(:description) || 'Not authorized') } }
{ json: { error: error.try(:description) || 'Not authorized' } }
end
def doorkeeper_forbidden_render_options(*)
@@ -105,7 +105,11 @@ class Api::BaseController < ApplicationController
end
def require_not_suspended!
render json: { error: 'Your login is currently disabled' }, status: 403 if current_user&.account&.suspended?
render json: { error: 'Your login is currently disabled' }, status: 403 if current_user&.account&.unavailable?
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!
@@ -136,6 +140,10 @@ class Api::BaseController < ApplicationController
private
def pagination_options_invalid?
params.slice(:limit, :offset).values.map(&:to_i).any?(&:negative?)
end
def respond_with_error(code)
render json: { error: Rack::Utils::HTTP_STATUS_CODES[code] }, status: code
end

View File

@@ -26,7 +26,7 @@ class Api::V1::Accounts::FollowerAccountsController < Api::BaseController
end
def hide_results?
@account.suspended? || (@account.hides_followers? && current_account&.id != @account.id) || (current_account && @account.blocking?(current_account))
@account.unavailable? || (@account.hides_followers? && current_account&.id != @account.id) || (current_account && @account.blocking?(current_account))
end
def default_accounts

View File

@@ -26,7 +26,7 @@ class Api::V1::Accounts::FollowingAccountsController < Api::BaseController
end
def hide_results?
@account.suspended? || (@account.hides_following? && current_account&.id != @account.id) || (current_account && @account.blocking?(current_account))
@account.unavailable? || (@account.hides_following? && current_account&.id != @account.id) || (current_account && @account.blocking?(current_account))
end
def default_accounts

View File

@@ -25,6 +25,6 @@ class Api::V1::Accounts::NotesController < Api::BaseController
end
def relationships_presenter
AccountRelationshipsPresenter.new([@account.id], current_user.account_id)
AccountRelationshipsPresenter.new([@account], current_user.account_id)
end
end

View File

@@ -25,6 +25,6 @@ class Api::V1::Accounts::PinsController < Api::BaseController
end
def relationships_presenter
AccountRelationshipsPresenter.new([@account.id], current_user.account_id)
AccountRelationshipsPresenter.new([@account], current_user.account_id)
end
end

View File

@@ -5,7 +5,7 @@ class Api::V1::Accounts::RelationshipsController < Api::BaseController
before_action :require_user!
def index
@accounts = Account.where(id: account_ids).select('id')
@accounts = Account.where(id: account_ids).select(:id, :domain)
@accounts.merge!(Account.without_suspended) unless truthy_param?(:with_suspended)
render json: @accounts, each_serializer: REST::RelationshipSerializer, relationships: relationships
end

View File

@@ -19,7 +19,7 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
end
def load_statuses
@account.suspended? ? [] : cached_account_statuses
@account.unavailable? ? [] : cached_account_statuses
end
def cached_account_statuses

View File

@@ -49,7 +49,7 @@ class Api::V1::AccountsController < Api::BaseController
end
def mute
MuteService.new.call(current_user.account, @account, notifications: truthy_param?(:notifications), duration: (params[:duration]&.to_i || 0))
MuteService.new.call(current_user.account, @account, notifications: truthy_param?(:notifications), duration: params[:duration].to_i)
render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships
end
@@ -88,7 +88,7 @@ class Api::V1::AccountsController < Api::BaseController
end
def relationships(**options)
AccountRelationshipsPresenter.new([@account.id], current_user.account_id, **options)
AccountRelationshipsPresenter.new([@account], current_user.account_id, **options)
end
def account_params

View File

@@ -12,7 +12,7 @@ class Api::V1::DirectoriesController < Api::BaseController
private
def require_enabled!
return not_found unless Setting.profile_directory
not_found unless Setting.profile_directory
end
def set_accounts

View File

@@ -25,11 +25,11 @@ class Api::V1::FollowRequestsController < Api::BaseController
private
def account
Account.find(params[:id])
@account ||= Account.find(params[:id])
end
def relationships(**options)
AccountRelationshipsPresenter.new([params[:id]], current_user.account_id, **options)
AccountRelationshipsPresenter.new([account], current_user.account_id, **options)
end
def load_accounts

View File

@@ -8,6 +8,12 @@ class Api::V2::SearchController < Api::BaseController
before_action -> { authorize_if_got_token! :read, :'read:search' }
before_action :validate_search_params!
with_options unless: :user_signed_in? do
before_action :query_pagination_error, if: :pagination_requested?
before_action :remote_resolve_error, if: :remote_resolve_requested?
end
before_action :require_valid_pagination_options!
def index
@search = Search.new(search_results)
render json: @search, serializer: REST::SearchSerializer
@@ -21,12 +27,22 @@ class Api::V2::SearchController < Api::BaseController
def validate_search_params!
params.require(:q)
end
return if user_signed_in?
def query_pagination_error
render json: { error: 'Search queries pagination is not supported without authentication' }, status: 401
end
return render json: { error: 'Search queries pagination is not supported without authentication' }, status: 401 if params[:offset].present?
def remote_resolve_error
render json: { error: 'Search queries that resolve remote resources are not supported without authentication' }, status: 401
end
render json: { error: 'Search queries that resolve remote resources are not supported without authentication' }, status: 401 if truthy_param?(:resolve)
def remote_resolve_requested?
truthy_param?(:resolve)
end
def pagination_requested?
params[:offset].present?
end
def search_results
@@ -34,7 +50,15 @@ class Api::V2::SearchController < Api::BaseController
params[:q],
current_account,
limit_param(RESULTS_LIMIT),
search_params.merge(resolve: truthy_param?(:resolve), exclude_unreviewed: truthy_param?(:exclude_unreviewed), following: truthy_param?(:following))
combined_search_params
)
end
def combined_search_params
search_params.merge(
resolve: truthy_param?(:resolve),
exclude_unreviewed: truthy_param?(:exclude_unreviewed),
following: truthy_param?(:following)
)
end

View File

@@ -1,7 +1,7 @@
# frozen_string_literal: true
class Auth::ConfirmationsController < Devise::ConfirmationsController
include CaptchaConcern
include Auth::CaptchaConcern
layout 'auth'
@@ -63,7 +63,7 @@ class Auth::ConfirmationsController < Devise::ConfirmationsController
end
def captcha_user_bypass?
return true if @confirmation_user.nil? || @confirmation_user.confirmed?
@confirmation_user.nil? || @confirmation_user.confirmed?
end
def set_pack

View File

@@ -2,7 +2,7 @@
class Auth::RegistrationsController < Devise::RegistrationsController
include RegistrationHelper
include RegistrationSpamConcern
include Auth::RegistrationSpamConcern
layout :determine_layout
@@ -125,7 +125,7 @@ class Auth::RegistrationsController < Devise::RegistrationsController
end
def require_not_suspended!
forbidden if current_account.suspended?
forbidden if current_account.unavailable?
end
def set_rules

View File

@@ -11,7 +11,7 @@ class Auth::SessionsController < Devise::SessionsController
prepend_before_action :set_pack
prepend_before_action :check_suspicious!, only: [:create]
include TwoFactorAuthenticationConcern
include Auth::TwoFactorAuthenticationConcern
before_action :set_body_classes

View File

@@ -34,8 +34,8 @@ module AccountOwnedConcern
end
def check_account_suspension
if @account.suspended_permanently?
permanent_suspension_response
if @account.permanently_unavailable?
permanent_unavailability_response
elsif @account.suspended? && !skip_temporary_suspension_response?
temporary_suspension_response
end
@@ -45,7 +45,7 @@ module AccountOwnedConcern
false
end
def permanent_suspension_response
def permanent_unavailability_response
expires_in(3.minutes, public: true)
gone
end

View File

@@ -1,6 +1,6 @@
# frozen_string_literal: true
module AdminExportControllerConcern
module Admin::ExportControllerConcern
extend ActiveSupport::Concern
private

View File

@@ -1,6 +1,6 @@
# frozen_string_literal: true
module AccessTokenTrackingConcern
module Api::AccessTokenTrackingConcern
extend ActiveSupport::Concern
ACCESS_TOKEN_UPDATE_FREQUENCY = 24.hours.freeze

View File

@@ -1,6 +1,6 @@
# frozen_string_literal: true
module ApiCachingConcern
module Api::CachingConcern
extend ActiveSupport::Concern
def cache_if_unauthenticated!

View File

@@ -1,6 +1,6 @@
# frozen_string_literal: true
module RateLimitHeaders
module Api::RateLimitHeaders
extend ActiveSupport::Concern
class_methods do

View File

@@ -1,6 +1,6 @@
# frozen_string_literal: true
module CaptchaConcern
module Auth::CaptchaConcern
extend ActiveSupport::Concern
include Hcaptcha::Adapters::ViewMethods

View File

@@ -1,6 +1,6 @@
# frozen_string_literal: true
module RegistrationSpamConcern
module Auth::RegistrationSpamConcern
extend ActiveSupport::Concern
def set_registration_form_time

View File

@@ -1,6 +1,6 @@
# frozen_string_literal: true
module TwoFactorAuthenticationConcern
module Auth::TwoFactorAuthenticationConcern
extend ActiveSupport::Concern
included do

View File

@@ -43,7 +43,7 @@ module ChallengableConcern
def render_challenge
@body_classes = 'lighter'
render template: 'auth/challenges/new', layout: 'auth'
render 'auth/challenges/new', layout: 'auth'
end
def challenge_passed?

View File

@@ -1,6 +1,6 @@
# frozen_string_literal: true
module ExportControllerConcern
module Settings::ExportControllerConcern
extend ActiveSupport::Concern
included do

View File

@@ -11,7 +11,7 @@ class Disputes::AppealsController < Disputes::BaseController
redirect_to disputes_strike_path(@strike), notice: I18n.t('disputes.strikes.appealed_msg')
rescue ActiveRecord::RecordInvalid => e
@appeal = e.record
render template: 'disputes/strikes/show'
render 'disputes/strikes/show'
end
private

View File

@@ -26,7 +26,7 @@ class FiltersController < ApplicationController
if @filter.save
redirect_to filters_path
else
render action: :new
render :new
end
end
@@ -34,7 +34,7 @@ class FiltersController < ApplicationController
if @filter.update(resource_params)
redirect_to filters_path
else
render action: :edit
render :edit
end
end

View File

@@ -36,7 +36,7 @@ class Oauth::AuthorizedApplicationsController < Doorkeeper::AuthorizedApplicatio
end
def require_not_suspended!
forbidden if current_account.suspended?
forbidden if current_account.unavailable?
end
def set_cache_headers

View File

@@ -34,7 +34,7 @@ class RelationshipsController < ApplicationController
end
def set_relationships
@relationships = AccountRelationshipsPresenter.new(@accounts.pluck(:id), current_user.account_id)
@relationships = AccountRelationshipsPresenter.new(@accounts, current_user.account_id)
end
def form_account_batch_params

View File

@@ -23,6 +23,6 @@ class Settings::BaseController < ApplicationController
end
def require_not_suspended!
forbidden if current_account.suspended?
forbidden if current_account.unavailable?
end
end

View File

@@ -25,7 +25,7 @@ class Settings::DeletesController < Settings::BaseController
end
def require_not_suspended!
forbidden if current_account.suspended?
forbidden if current_account.unavailable?
end
def challenge_passed?

View File

@@ -3,7 +3,7 @@
module Settings
module Exports
class BlockedAccountsController < BaseController
include ExportControllerConcern
include Settings::ExportControllerConcern
def index
send_export_file

View File

@@ -3,7 +3,7 @@
module Settings
module Exports
class BlockedDomainsController < BaseController
include ExportControllerConcern
include Settings::ExportControllerConcern
def index
send_export_file

View File

@@ -3,7 +3,7 @@
module Settings
module Exports
class BookmarksController < BaseController
include ExportControllerConcern
include Settings::ExportControllerConcern
def index
send_export_file

View File

@@ -3,7 +3,7 @@
module Settings
module Exports
class FollowingAccountsController < BaseController
include ExportControllerConcern
include Settings::ExportControllerConcern
def index
send_export_file

View File

@@ -3,7 +3,7 @@
module Settings
module Exports
class ListsController < BaseController
include ExportControllerConcern
include Settings::ExportControllerConcern
def index
send_export_file

View File

@@ -3,7 +3,7 @@
module Settings
module Exports
class MutedAccountsController < BaseController
include ExportControllerConcern
include Settings::ExportControllerConcern
def index
send_export_file

View File

@@ -15,7 +15,7 @@ class StatusesCleanupController < ApplicationController
if @policy.update(resource_params)
redirect_to statuses_cleanup_path, notice: I18n.t('generic.changes_saved_msg')
else
render action: :show
render :show
end
rescue ActionController::ParameterMissing
# Do nothing

View File

@@ -42,7 +42,7 @@ module WellKnown
end
def check_account_suspension
gone if @account.suspended_permanently?
gone if @account.permanently_unavailable?
end
def gone

View File

@@ -0,0 +1,12 @@
# frozen_string_literal: true
module Admin::AccountActionsHelper
def account_action_type_label(type)
safe_join(
[
I18n.t("simple_form.labels.admin_account_action.types.#{type}"),
content_tag(:span, I18n.t("simple_form.hints.admin_account_action.types.#{type}"), class: 'hint'),
]
)
end
end

View File

@@ -0,0 +1,19 @@
# frozen_string_literal: true
module Admin::AccountsHelper
def admin_accounts_moderation_options
[
[t('admin.accounts.moderation.active'), 'active'],
[t('admin.accounts.moderation.silenced'), 'silenced'],
[t('admin.accounts.moderation.disabled'), 'disabled'],
[t('admin.accounts.moderation.suspended'), 'suspended'],
[safe_join([t('admin.accounts.moderation.pending'), "(#{pending_user_count_label})"], ' '), 'pending'],
]
end
private
def pending_user_count_label
number_with_delimiter User.pending.count
end
end

View File

@@ -0,0 +1,12 @@
# frozen_string_literal: true
module Admin::IpBlocksHelper
def ip_blocks_severity_label(severity)
safe_join(
[
I18n.t("simple_form.labels.ip_block.severities.#{severity}"),
content_tag(:span, I18n.t("simple_form.hints.ip_block.severities.#{severity}"), class: 'hint'),
]
)
end
end

View File

@@ -0,0 +1,24 @@
# frozen_string_literal: true
module Admin
module RolesHelper
def privilege_label(privilege)
safe_join(
[
t("admin.roles.privileges.#{privilege}"),
content_tag(:span, t("admin.roles.privileges.#{privilege}_description"), class: 'hint'),
]
)
end
def disable_permissions?(permissions)
permissions.filter { |privilege| role_flag_value(privilege).zero? }
end
private
def role_flag_value(privilege)
UserRole::FLAGS[privilege] & current_user.role.computed_permissions
end
end
end

View File

@@ -0,0 +1,15 @@
# frozen_string_literal: true
module Admin::Settings::DiscoveryHelper
def discovery_warning_hint_text
authorized_fetch_overridden? ? t('admin.settings.security.authorized_fetch_overridden_hint') : nil
end
def discovery_hint_text
t('admin.settings.security.authorized_fetch_hint')
end
def discovery_recommended_value
authorized_fetch_overridden? ? :overridden : nil
end
end

View File

@@ -110,11 +110,11 @@ module ApplicationHelper
def can?(action, record)
return false if record.nil?
policy(record).public_send("#{action}?")
policy(record).public_send(:"#{action}?")
end
def fa_icon(icon, attributes = {})
class_names = attributes[:class]&.split(' ') || []
class_names = attributes[:class]&.split || []
class_names << 'fa'
class_names += icon.split.map { |cl| "fa-#{cl}" }

View File

@@ -0,0 +1,12 @@
# frozen_string_literal: true
module FiltersHelper
def filter_action_label(action)
safe_join(
[
t("simple_form.labels.filters.actions.#{action}"),
content_tag(:span, t("simple_form.hints.filters.actions.#{action}"), class: 'hint'),
]
)
end
end

View File

@@ -1,9 +1,16 @@
/* eslint-disable @typescript-eslint/no-unsafe-call,
@typescript-eslint/no-unsafe-return,
@typescript-eslint/no-unsafe-assignment,
@typescript-eslint/no-unsafe-member-access
-- the settings store is not yet typed */
import type { PropsWithChildren } from 'react';
import { useCallback, useState } from 'react';
import { useCallback, useState, useEffect } from 'react';
import { defineMessages, useIntl } from 'react-intl';
import { changeSetting } from 'flavours/glitch/actions/settings';
import { bannerSettings } from 'flavours/glitch/settings';
import { useAppSelector, useAppDispatch } from 'flavours/glitch/store';
import { IconButton } from './icon_button';
@@ -19,13 +26,25 @@ export const DismissableBanner: React.FC<PropsWithChildren<Props>> = ({
id,
children,
}) => {
const [visible, setVisible] = useState(!bannerSettings.get(id));
const dismissed = useAppSelector((state) =>
state.settings.getIn(['dismissed_banners', id], false),
);
const dispatch = useAppDispatch();
const [visible, setVisible] = useState(!bannerSettings.get(id) && !dismissed);
const intl = useIntl();
const handleDismiss = useCallback(() => {
setVisible(false);
bannerSettings.set(id, true);
}, [id]);
dispatch(changeSetting(['dismissed_banners', id], true));
}, [id, dispatch]);
useEffect(() => {
if (!visible && !dismissed) {
dispatch(changeSetting(['dismissed_banners', id], true));
}
}, [id, dispatch, visible, dismissed]);
if (!visible) {
return null;

View File

@@ -125,7 +125,7 @@ class ComposeForm extends ImmutablePureComponent {
return !(isSubmitting || isUploading || isChangingUpload || length(fulltext) > maxChars || (!fulltext.trim().length && !anyMedia));
};
handleSubmit = (overriddenVisibility = null) => {
handleSubmit = (e, overriddenVisibility = null) => {
if (this.props.text !== this.textareaRef.current.value) {
// Something changed the text inside the textarea (e.g. browser extensions like Grammarly)
// Update the state to match the current text
@@ -136,6 +136,10 @@ class ComposeForm extends ImmutablePureComponent {
return;
}
if (e) {
e.preventDefault();
}
// Submit unless there are media with missing descriptions
if (this.props.mediaDescriptionConfirmation && this.props.media && this.props.media.some(item => !item.get('description'))) {
const firstWithoutDescription = this.props.media.find(item => !item.get('description'));
@@ -150,10 +154,8 @@ class ComposeForm extends ImmutablePureComponent {
// Handles the secondary submit button.
handleSecondarySubmit = () => {
const {
sideArm,
} = this.props;
this.handleSubmit(sideArm === 'none' ? null : sideArm);
const { sideArm } = this.props;
this.handleSubmit(null, sideArm === 'none' ? null : sideArm);
};
onSuggestionsClearRequested = () => {
@@ -342,7 +344,6 @@ class ComposeForm extends ImmutablePureComponent {
disabled={!this.canSubmit()}
isEditing={isEditing}
onSecondarySubmit={this.handleSecondarySubmit}
onSubmit={this.handleSubmit}
privacy={privacy}
sideArm={sideArm}
/>

View File

@@ -29,16 +29,11 @@ class Publisher extends ImmutablePureComponent {
disabled: PropTypes.bool,
intl: PropTypes.object.isRequired,
onSecondarySubmit: PropTypes.func,
onSubmit: PropTypes.func,
privacy: PropTypes.oneOf(['direct', 'private', 'unlisted', 'public']),
sideArm: PropTypes.oneOf(['none', 'direct', 'private', 'unlisted', 'public']),
isEditing: PropTypes.bool,
};
handleSubmit = () => {
this.props.onSubmit();
};
render () {
const { disabled, intl, onSecondarySubmit, privacy, sideArm, isEditing } = this.props;
@@ -82,9 +77,9 @@ class Publisher extends ImmutablePureComponent {
<div className='compose-form__publish-button-wrapper'>
<Button
className='primary'
type='submit'
text={publishText}
title={`${intl.formatMessage(messages.publish)}: ${intl.formatMessage(privacyNames[privacy])}`}
onClick={this.handleSubmit}
disabled={disabled}
/>
</div>

View File

@@ -294,9 +294,9 @@ class LoginForm extends React.PureComponent {
onFocus={this.handleFocus}
onBlur={this.handleBlur}
onKeyDown={this.handleKeyDown}
autocomplete='off'
autocapitalize='off'
spellcheck='false'
autoComplete='off'
autoCapitalize='off'
spellCheck='false'
/>
<Button onClick={this.handleSubmit} disabled={isSubmitting || error}><FormattedMessage id='interaction_modal.login.action' defaultMessage='Take me home' /></Button>

View File

@@ -59,7 +59,7 @@ class ConfirmationModal extends PureComponent {
{ onDoNotAsk && (
<div className='confirmation-modal__do_not_ask_again'>
<input type='checkbox' id='confirmation-modal__do_not_ask_again-checkbox' ref={this.setDoNotAskRef} />
<label for='confirmation-modal__do_not_ask_again-checkbox'>
<label htmlFor='confirmation-modal__do_not_ask_again-checkbox'>
<FormattedMessage id='confirmation_modal.do_not_ask_again' defaultMessage='Do not ask for confirmation again' />
</label>
</div>

View File

@@ -66,7 +66,7 @@ class NavigationPanel extends Component {
return (
<div className='navigation-panel'>
{banner &&
<div class='navigation-panel__banner'>
<div className='navigation-panel__banner'>
{banner}
</div>
}

View File

@@ -592,7 +592,6 @@ class Video extends PureComponent {
aria-label={alt}
title={alt}
lang={lang}
volume={volume}
onClick={this.togglePlay}
onKeyDown={this.handleVideoKeyDown}
onPlay={this.handlePlay}

View File

@@ -110,6 +110,15 @@ const initialState = ImmutableMap({
body: '',
}),
}),
dismissed_banners: ImmutableMap({
'public_timeline': false,
'community_timeline': false,
'home.explore_prompt': false,
'explore/links': false,
'explore/statuses': false,
'explore/tags': false,
}),
});
const defaultColumns = fromJS([

View File

@@ -658,10 +658,6 @@ $ui-header-height: 55px;
flex: 1 1 auto;
align-items: center;
justify-content: center;
@supports (display: grid) {
// hack to fix Chrome <57
contain: strict;
}
& > span {
max-width: 500px;
@@ -1083,22 +1079,16 @@ $ui-header-height: 55px;
&__description {
flex: 1 1 auto;
line-height: 20px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
h6 {
color: $highlight-text-color;
font-weight: 500;
font-size: 14px;
overflow: hidden;
text-overflow: ellipsis;
}
p {
color: $darker-text-color;
overflow: hidden;
text-overflow: ellipsis;
}
}
}

View File

@@ -21,7 +21,7 @@ function actionWithSkipLoadingTrue<Args extends object>(args: Args) {
}
export const followAccountSuccess = createAction(
'accounts/followAccountSuccess',
'accounts/followAccount/SUCCESS',
actionWithSkipLoadingTrue<{
relationship: ApiRelationshipJSON;
alreadyFollowing: boolean;
@@ -29,7 +29,7 @@ export const followAccountSuccess = createAction(
);
export const unfollowAccountSuccess = createAction(
'accounts/unfollowAccountSuccess',
'accounts/unfollowAccount/SUCCESS',
actionWithSkipLoadingTrue<{
relationship: ApiRelationshipJSON;
statuses: unknown;
@@ -38,60 +38,60 @@ export const unfollowAccountSuccess = createAction(
);
export const authorizeFollowRequestSuccess = createAction<{ id: string }>(
'accounts/followRequestAuthorizeSuccess',
'accounts/followRequestAuthorize/SUCCESS',
);
export const rejectFollowRequestSuccess = createAction<{ id: string }>(
'accounts/followRequestRejectSuccess',
'accounts/followRequestReject/SUCCESS',
);
export const followAccountRequest = createAction(
'accounts/followRequest',
'accounts/follow/REQUEST',
actionWithSkipLoadingTrue<{ id: string; locked: boolean }>,
);
export const followAccountFail = createAction(
'accounts/followFail',
'accounts/follow/FAIL',
actionWithSkipLoadingTrue<{ id: string; error: string; locked: boolean }>,
);
export const unfollowAccountRequest = createAction(
'accounts/unfollowRequest',
'accounts/unfollow/REQUEST',
actionWithSkipLoadingTrue<{ id: string }>,
);
export const unfollowAccountFail = createAction(
'accounts/unfollowFail',
'accounts/unfollow/FAIL',
actionWithSkipLoadingTrue<{ id: string; error: string }>,
);
export const blockAccountSuccess = createAction<{
relationship: ApiRelationshipJSON;
statuses: unknown;
}>('accounts/blockSuccess');
}>('accounts/block/SUCCESS');
export const unblockAccountSuccess = createAction<{
relationship: ApiRelationshipJSON;
}>('accounts/unblockSuccess');
}>('accounts/unblock/SUCCESS');
export const muteAccountSuccess = createAction<{
relationship: ApiRelationshipJSON;
statuses: unknown;
}>('accounts/muteSuccess');
}>('accounts/mute/SUCCESS');
export const unmuteAccountSuccess = createAction<{
relationship: ApiRelationshipJSON;
}>('accounts/unmuteSuccess');
}>('accounts/unmute/SUCCESS');
export const pinAccountSuccess = createAction<{
relationship: ApiRelationshipJSON;
}>('accounts/pinSuccess');
}>('accounts/pin/SUCCESS');
export const unpinAccountSuccess = createAction<{
relationship: ApiRelationshipJSON;
}>('accounts/unpinSuccess');
}>('accounts/unpin/SUCCESS');
export const fetchRelationshipsSuccess = createAction(
'relationships/fetchSuccess',
'relationships/fetch/SUCCESS',
actionWithSkipLoadingTrue<{ relationships: ApiRelationshipJSON[] }>,
);

View File

@@ -5,9 +5,9 @@ import type { Account } from 'mastodon/models/account';
export const blockDomainSuccess = createAction<{
domain: string;
accounts: Account[];
}>('domain_blocks/blockSuccess');
}>('domain_blocks/block/SUCCESS');
export const unblockDomainSuccess = createAction<{
domain: string;
accounts: Account[];
}>('domain_blocks/unblockSuccess');
}>('domain_blocks/unblock/SUCCESS');

View File

@@ -18,6 +18,6 @@ export const notificationsUpdate = createAction(
playSound: boolean;
}) => ({
payload: args,
meta: { playSound: playSound ? { sound: 'boop' } : undefined },
meta: { sound: playSound ? 'boop' : undefined },
}),
);

View File

@@ -6,7 +6,7 @@ import { FormattedMessage } from 'react-intl';
import classNames from 'classnames';
import api from 'mastodon/api';
import Hashtag from 'mastodon/components/hashtag';
import { Hashtag } from 'mastodon/components/hashtag';
export default class Trends extends PureComponent {

View File

@@ -1,11 +1,18 @@
/* eslint-disable @typescript-eslint/no-unsafe-call,
@typescript-eslint/no-unsafe-return,
@typescript-eslint/no-unsafe-assignment,
@typescript-eslint/no-unsafe-member-access
-- the settings store is not yet typed */
import type { PropsWithChildren } from 'react';
import { useCallback, useState } from 'react';
import { useCallback, useState, useEffect } from 'react';
import { defineMessages, useIntl } from 'react-intl';
import { ReactComponent as CloseIcon } from '@material-symbols/svg-600/outlined/close.svg';
import { changeSetting } from 'mastodon/actions/settings';
import { bannerSettings } from 'mastodon/settings';
import { useAppSelector, useAppDispatch } from 'mastodon/store';
import { IconButton } from './icon_button';
@@ -21,13 +28,25 @@ export const DismissableBanner: React.FC<PropsWithChildren<Props>> = ({
id,
children,
}) => {
const [visible, setVisible] = useState(!bannerSettings.get(id));
const dismissed = useAppSelector((state) =>
state.settings.getIn(['dismissed_banners', id], false),
);
const dispatch = useAppDispatch();
const [visible, setVisible] = useState(!bannerSettings.get(id) && !dismissed);
const intl = useIntl();
const handleDismiss = useCallback(() => {
setVisible(false);
bannerSettings.set(id, true);
}, [id]);
dispatch(changeSetting(['dismissed_banners', id], true));
}, [id, dispatch]);
useEffect(() => {
if (!visible && !dismissed) {
dispatch(changeSetting(['dismissed_banners', id], true));
}
}, [id, dispatch, visible, dismissed]);
if (!visible) {
return null;

View File

@@ -257,7 +257,7 @@ class Dropdown extends PureComponent {
};
findTarget = () => {
return this.target?.buttonRef?.current;
return this.target?.buttonRef?.current ?? this.target;
};
componentWillUnmount = () => {

View File

@@ -1,120 +0,0 @@
// @ts-check
import PropTypes from 'prop-types';
import { Component } from 'react';
import { FormattedMessage } from 'react-intl';
import classNames from 'classnames';
import { Link } from 'react-router-dom';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { Sparklines, SparklinesCurve } from 'react-sparklines';
import { ShortNumber } from 'mastodon/components/short_number';
import { Skeleton } from 'mastodon/components/skeleton';
class SilentErrorBoundary extends Component {
static propTypes = {
children: PropTypes.node,
};
state = {
error: false,
};
componentDidCatch() {
this.setState({ error: true });
}
render() {
if (this.state.error) {
return null;
}
return this.props.children;
}
}
/**
* Used to render counter of how much people are talking about hashtag
* @type {(displayNumber: JSX.Element, pluralReady: number) => JSX.Element}
*/
export const accountsCountRenderer = (displayNumber, pluralReady) => (
<FormattedMessage
id='trends.counter_by_accounts'
defaultMessage='{count, plural, one {{counter} person} other {{counter} people}} in the past {days, plural, one {day} other {# days}}'
values={{
count: pluralReady,
counter: <strong>{displayNumber}</strong>,
days: 2,
}}
/>
);
// @ts-expect-error
export const ImmutableHashtag = ({ hashtag }) => (
<Hashtag
name={hashtag.get('name')}
to={`/tags/${hashtag.get('name')}`}
people={hashtag.getIn(['history', 0, 'accounts']) * 1 + hashtag.getIn(['history', 1, 'accounts']) * 1}
// @ts-expect-error
history={hashtag.get('history').reverse().map((day) => day.get('uses')).toArray()}
/>
);
ImmutableHashtag.propTypes = {
hashtag: ImmutablePropTypes.map.isRequired,
};
// @ts-expect-error
const Hashtag = ({ name, to, people, uses, history, className, description, withGraph }) => (
<div className={classNames('trends__item', className)}>
<div className='trends__item__name'>
<Link to={to}>
{name ? <>#<span>{name}</span></> : <Skeleton width={50} />}
</Link>
{description ? (
<span>{description}</span>
) : (
typeof people !== 'undefined' ? <ShortNumber value={people} renderer={accountsCountRenderer} /> : <Skeleton width={100} />
)}
</div>
{typeof uses !== 'undefined' && (
<div className='trends__item__current'>
<ShortNumber value={uses} />
</div>
)}
{withGraph && (
<div className='trends__item__sparkline'>
<SilentErrorBoundary>
<Sparklines width={50} height={28} data={history ? history : Array.from(Array(7)).map(() => 0)}>
<SparklinesCurve style={{ fill: 'none' }} />
</Sparklines>
</SilentErrorBoundary>
</div>
)}
</div>
);
Hashtag.propTypes = {
name: PropTypes.string,
to: PropTypes.string,
people: PropTypes.number,
description: PropTypes.node,
uses: PropTypes.number,
history: PropTypes.arrayOf(PropTypes.number),
className: PropTypes.string,
withGraph: PropTypes.bool,
};
Hashtag.defaultProps = {
withGraph: true,
};
export default Hashtag;

View File

@@ -0,0 +1,145 @@
import type { JSX } from 'react';
import { Component } from 'react';
import { FormattedMessage } from 'react-intl';
import classNames from 'classnames';
import { Link } from 'react-router-dom';
import type Immutable from 'immutable';
import { Sparklines, SparklinesCurve } from 'react-sparklines';
import { ShortNumber } from 'mastodon/components/short_number';
import { Skeleton } from 'mastodon/components/skeleton';
interface SilentErrorBoundaryProps {
children: React.ReactNode;
}
class SilentErrorBoundary extends Component<SilentErrorBoundaryProps> {
state = {
error: false,
};
componentDidCatch() {
this.setState({ error: true });
}
render() {
if (this.state.error) {
return null;
}
return this.props.children;
}
}
/**
* Used to render counter of how much people are talking about hashtag
* @param displayNumber Counter number to display
* @param pluralReady Whether the count is plural
* @returns Formatted counter of how much people are talking about hashtag
*/
export const accountsCountRenderer = (
displayNumber: JSX.Element,
pluralReady: number,
) => (
<FormattedMessage
id='trends.counter_by_accounts'
defaultMessage='{count, plural, one {{counter} person} other {{counter} people}} in the past {days, plural, one {day} other {# days}}'
values={{
count: pluralReady,
counter: <strong>{displayNumber}</strong>,
days: 2,
}}
/>
);
interface ImmutableHashtagProps {
hashtag: Immutable.Map<string, unknown>;
}
export const ImmutableHashtag = ({ hashtag }: ImmutableHashtagProps) => (
<Hashtag
name={hashtag.get('name') as string}
to={`/tags/${hashtag.get('name') as string}`}
people={
(hashtag.getIn(['history', 0, 'accounts']) as number) * 1 +
(hashtag.getIn(['history', 1, 'accounts']) as number) * 1
}
history={(
hashtag.get('history') as Immutable.Collection.Indexed<
Immutable.Map<string, number>
>
)
.reverse()
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
.map((day) => day.get('uses')!)
.toArray()}
/>
);
export interface HashtagProps {
className?: string;
description?: React.ReactNode;
history?: number[];
name: string;
people: number;
to: string;
uses?: number;
withGraph?: boolean;
}
export const Hashtag: React.FC<HashtagProps> = ({
name,
to,
people,
uses,
history,
className,
description,
withGraph = true,
}) => (
<div className={classNames('trends__item', className)}>
<div className='trends__item__name'>
<Link to={to}>
{name ? (
<>
#<span>{name}</span>
</>
) : (
<Skeleton width={50} />
)}
</Link>
{description ? (
<span>{description}</span>
) : typeof people !== 'undefined' ? (
<ShortNumber value={people} renderer={accountsCountRenderer} />
) : (
<Skeleton width={100} />
)}
</div>
{typeof uses !== 'undefined' && (
<div className='trends__item__current'>
<ShortNumber value={uses} />
</div>
)}
{withGraph && (
<div className='trends__item__sparkline'>
<SilentErrorBoundary>
<Sparklines
width={50}
height={28}
data={history ? history : Array.from(Array(7)).map(() => 0)}
>
<SparklinesCurve style={{ fill: 'none' }} />
</Sparklines>
</SilentErrorBoundary>
</div>
)}
</div>
);

View File

@@ -1,80 +0,0 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { render, fireEvent } from '@testing-library/react';
class Media extends Component {
constructor(props) {
super(props);
this.state = {
paused: props.paused || false,
};
}
handleMediaClick = () => {
const { onClick } = this.props;
this.setState(prevState => ({
paused: !prevState.paused,
}));
if (typeof onClick === 'function') {
onClick();
}
const { title } = this.props;
const mediaElements = document.querySelectorAll(`div[title="${title}"]`);
setTimeout(() => {
mediaElements.forEach(element => {
if (element !== this && !element.classList.contains('paused')) {
element.click();
}
});
}, 0);
};
render() {
const { title } = this.props;
const { paused } = this.state;
return (
<button title={title} onClick={this.handleMediaClick}>
Media Component - {paused ? 'Paused' : 'Playing'}
</button>
);
}
}
Media.propTypes = {
title: PropTypes.string.isRequired,
onClick: PropTypes.func,
paused: PropTypes.bool,
};
describe('Media attachments test', () => {
let currentMedia = null;
const togglePlayMock = jest.fn();
it('plays a new media file and pauses others that were playing', () => {
const container = render(
<div>
<Media title='firstMedia' paused onClick={togglePlayMock} />
<Media title='secondMedia' paused onClick={togglePlayMock} />
</div>,
);
fireEvent.click(container.getByTitle('firstMedia'));
expect(togglePlayMock).toHaveBeenCalledTimes(1);
currentMedia = container.getByTitle('firstMedia');
expect(currentMedia.textContent).toMatch(/Playing/);
fireEvent.click(container.getByTitle('secondMedia'));
expect(togglePlayMock).toHaveBeenCalledTimes(2);
currentMedia = container.getByTitle('secondMedia');
expect(currentMedia.textContent).toMatch(/Playing/);
});
});

View File

@@ -5,7 +5,7 @@ import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import Hashtag from 'mastodon/components/hashtag';
import { Hashtag } from 'mastodon/components/hashtag';
const messages = defineMessages({
lastStatusAt: { id: 'account.featured_tags.last_status_at', defaultMessage: 'Last post on {date}' },

View File

@@ -20,7 +20,6 @@ import { formatTime, getPointerPosition, fileNameFromURL } from 'mastodon/featur
import { Blurhash } from '../../components/blurhash';
import { displayMedia, useBlurhash } from '../../initial_state';
import { currentMedia, setCurrentMedia } from '../../reducers/media_attachments';
import Visualizer from './visualizer';
@@ -166,32 +165,15 @@ class Audio extends PureComponent {
}
togglePlay = () => {
const audios = document.querySelectorAll('audio');
audios.forEach((audio) => {
const button = audio.previousElementSibling;
button.addEventListener('click', () => {
if(audio.paused) {
audios.forEach((e) => {
if (e !== audio) {
e.pause();
}
});
audio.play();
this.setState({ paused: false });
} else {
audio.pause();
this.setState({ paused: true });
}
});
});
if (currentMedia !== null) {
currentMedia.pause();
if (!this.audioContext) {
this._initAudioContext();
}
this.audio.play();
setCurrentMedia(this.audio);
if (this.state.paused) {
this.setState({ paused: false }, () => this.audio.play());
} else {
this.setState({ paused: true }, () => this.audio.pause());
}
};
handleResize = debounce(() => {
@@ -213,7 +195,6 @@ class Audio extends PureComponent {
};
handlePause = () => {
this.audio.pause();
this.setState({ paused: true });
if (this.audioContext) {

View File

@@ -13,7 +13,7 @@ import { debounce } from 'lodash';
import { expandFollowedHashtags, fetchFollowedHashtags } from 'mastodon/actions/tags';
import ColumnHeader from 'mastodon/components/column_header';
import Hashtag from 'mastodon/components/hashtag';
import { Hashtag } from 'mastodon/components/hashtag';
import ScrollableList from 'mastodon/components/scrollable_list';
import Column from 'mastodon/features/ui/components/column';

View File

@@ -298,9 +298,9 @@ class LoginForm extends React.PureComponent {
onFocus={this.handleFocus}
onBlur={this.handleBlur}
onKeyDown={this.handleKeyDown}
autocomplete='off'
autocapitalize='off'
spellcheck='false'
autoComplete='off'
autoCapitalize='off'
spellCheck='false'
/>
<Button onClick={this.handleSubmit} disabled={isSubmitting || error}><FormattedMessage id='interaction_modal.login.action' defaultMessage='Take me home' /></Button>

View File

@@ -82,7 +82,7 @@ class NavigationPanel extends Component {
</div>
{banner &&
<div class='navigation-panel__banner'>
<div className='navigation-panel__banner'>
{banner}
</div>
}

View File

@@ -22,7 +22,6 @@ import { Icon } from 'mastodon/components/icon';
import { playerSettings } from 'mastodon/settings';
import { displayMedia, useBlurhash } from '../../initial_state';
import { currentMedia, setCurrentMedia } from '../../reducers/media_attachments';
import { isFullscreen, requestFullscreen, exitFullscreen } from '../ui/util/fullscreen';
const messages = defineMessages({
@@ -182,7 +181,6 @@ class Video extends PureComponent {
};
handlePause = () => {
this.video.pause();
this.setState({ paused: true });
};
@@ -346,32 +344,11 @@ class Video extends PureComponent {
};
togglePlay = () => {
const videos = document.querySelectorAll('video');
videos.forEach((video) => {
const button = video.nextElementSibling;
button.addEventListener('click', () => {
if (video.paused) {
videos.forEach((e) => {
if (e !== video) {
e.pause();
}
});
video.play();
this.setState({ paused: false });
} else {
video.pause();
this.setState({ paused: true });
}
});
});
if (currentMedia !== null) {
currentMedia.pause();
if (this.state.paused) {
this.setState({ paused: false }, () => this.video.play());
} else {
this.setState({ paused: true }, () => this.video.pause());
}
this.video.play();
setCurrentMedia(this.video);
};
toggleFullscreen = () => {
@@ -612,7 +589,6 @@ class Video extends PureComponent {
aria-label={alt}
title={alt}
lang={lang}
volume={volume}
onClick={this.togglePlay}
onKeyDown={this.handleVideoKeyDown}
onPlay={this.handlePlay}

View File

@@ -499,6 +499,7 @@
"report_notification.open": "Ubrir informe",
"search.placeholder": "Buscar",
"search.search_or_paste": "Buscar u apegar URL",
"search_popout.full_text_search_logged_out_message": "Nomás disponible iniciando la sesión.",
"search_results.all": "Totz",
"search_results.hashtags": "Etiquetas",
"search_results.nothing_found": "No se podió trobar cosa pa estes termins de busqueda",

View File

@@ -482,6 +482,7 @@
"onboarding.follows.lead": "La teva línia de temps inici només està a les teves mans. Com més gent segueixis, més activa i interessant serà. Aquests perfils poden ser un bon punt d'inici—sempre pots acabar deixant de seguir-los!:",
"onboarding.follows.title": "Personalitza la pantalla d'inci",
"onboarding.profile.discoverable": "Fes el meu perfil descobrible",
"onboarding.profile.discoverable_hint": "En acceptar d'ésser descobert a Mastodon els teus missatges poden aparèixer dins les tendències i els resultats de cerques, i el teu perfil es pot suggerir a qui tingui interessos semblants als teus.",
"onboarding.profile.display_name": "Nom que es mostrarà",
"onboarding.profile.display_name_hint": "El teu nom complet o el teu malnom…",
"onboarding.profile.lead": "Sempre ho pots completar més endavant a la configuració, on hi ha encara més opcions disponibles.",

View File

@@ -21,6 +21,7 @@
"account.blocked": "Blocked",
"account.browse_more_on_origin_server": "Browse more on the original profile",
"account.cancel_follow_request": "Cancel follow",
"account.copy": "Copy link to profile",
"account.direct": "Privately mention @{name}",
"account.disable_notifications": "Stop notifying me when @{name} posts",
"account.domain_blocked": "Domain blocked",
@@ -191,6 +192,7 @@
"conversation.mark_as_read": "Mark as read",
"conversation.open": "View conversation",
"conversation.with": "With {names}",
"copy_icon_button.copied": "Copied to clipboard",
"copypaste.copied": "Copied",
"copypaste.copy_to_clipboard": "Copy to clipboard",
"directory.federated": "From known fediverse",
@@ -222,6 +224,7 @@
"emoji_button.search_results": "Search results",
"emoji_button.symbols": "Symbols",
"emoji_button.travel": "Travel & Places",
"empty_column.account_hides_collections": "This user has chosen to not make this information available",
"empty_column.account_suspended": "Account suspended",
"empty_column.account_timeline": "No posts here!",
"empty_column.account_unavailable": "Profile unavailable",
@@ -478,6 +481,8 @@
"onboarding.follows.empty": "Unfortunately, no results can be shown right now. You can try using search or browsing the explore page to find people to follow, or try again later.",
"onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!",
"onboarding.follows.title": "Personalize your home feed",
"onboarding.profile.discoverable": "Make my profile discoverable",
"onboarding.profile.discoverable_hint": "When you opt in to discoverability on Mastodon, your posts may appear in search results and trending, and your profile may be suggested to people with similar interests to you.",
"onboarding.profile.display_name": "Display name",
"onboarding.profile.display_name_hint": "Your full name or your fun name…",
"onboarding.profile.lead": "You can always complete this later in the settings, where even more customisation options are available.",
@@ -530,6 +535,7 @@
"privacy.unlisted.short": "Unlisted",
"privacy_policy.last_updated": "Last updated {date}",
"privacy_policy.title": "Privacy Policy",
"recommended": "Recommended",
"refresh": "Refresh",
"regeneration_indicator.label": "Loading…",
"regeneration_indicator.sublabel": "Your home feed is being prepared!",
@@ -600,6 +606,7 @@
"search.quick_action.status_search": "Posts matching {x}",
"search.search_or_paste": "Search or paste URL",
"search_popout.full_text_search_disabled_message": "Unavailable on {domain}.",
"search_popout.full_text_search_logged_out_message": "Only available when logged in.",
"search_popout.language_code": "ISO language code",
"search_popout.options": "Search options",
"search_popout.quick_actions": "Quick actions",

View File

@@ -21,6 +21,7 @@
"account.blocked": "Blokita",
"account.browse_more_on_origin_server": "Foliumi pli ĉe la originala profilo",
"account.cancel_follow_request": "Nuligi peton por sekvado",
"account.copy": "Kopii ligilon al profilo",
"account.direct": "Private mencii @{name}",
"account.disable_notifications": "Ne plu sciigi min, kiam @{name} mesaĝas",
"account.domain_blocked": "Domajno blokita",
@@ -191,6 +192,7 @@
"conversation.mark_as_read": "Marki legita",
"conversation.open": "Vidi konversacion",
"conversation.with": "Kun {names}",
"copy_icon_button.copied": "Kopiis al kliptabulo",
"copypaste.copied": "Kopiita",
"copypaste.copy_to_clipboard": "Kopii al dosierujo",
"directory.federated": "El konata fediverso",
@@ -202,7 +204,9 @@
"dismissable_banner.community_timeline": "Jen la plej novaj publikaj afiŝoj de uzantoj, kies kontojn gastigas {domain}.",
"dismissable_banner.dismiss": "Eksigi",
"dismissable_banner.explore_links": "Tiuj novaĵoj estas aktuale priparolataj de uzantoj en tiu ĉi kaj aliaj serviloj, sur la malcentrigita reto.",
"dismissable_banner.explore_statuses": "Ĉi tioj estas afiŝoj de socia reto kiu populariĝas hodiau.",
"dismissable_banner.explore_tags": "Ĉi tiuj kradvostoj populariĝas en ĉi tiu kaj aliaj serviloj en la malcentraliza reto nun.",
"dismissable_banner.public_timeline": "Ĉi tioj estas plej lastaj publikaj afiŝoj de personoj ĉe socia reto kiu personoj ĉe {domain} sekvas.",
"embed.instructions": "Enkorpigu ĉi tiun afiŝon en vian retejon per kopio de la suba kodo.",
"embed.preview": "Ĝi aperos tiel:",
"emoji_button.activity": "Agadoj",
@@ -220,6 +224,7 @@
"emoji_button.search_results": "Serĉaj rezultoj",
"emoji_button.symbols": "Simboloj",
"emoji_button.travel": "Vojaĝoj kaj lokoj",
"empty_column.account_hides_collections": "Ĉi tiu uzanto elektis ne disponebligi ĉi tiu informon",
"empty_column.account_suspended": "Konto suspendita",
"empty_column.account_timeline": "Neniu afiŝo ĉi tie!",
"empty_column.account_unavailable": "Profilo ne disponebla",
@@ -229,6 +234,8 @@
"empty_column.direct": "Vi ankoraŭ ne havas privatan mencion. Kiam vi sendos aŭ ricevos iun, tiu aperos ĉi tie.",
"empty_column.domain_blocks": "Ankoraŭ neniu domajno estas blokita.",
"empty_column.explore_statuses": "Nenio tendencas nun. Rekontrolu poste!",
"empty_column.favourited_statuses": "Vi ankoraŭ ne havas stelumitan afiŝon.",
"empty_column.favourites": "Ankoraŭ neniu stelumis tiun afiŝon.",
"empty_column.follow_requests": "Vi ne ankoraŭ havas iun peton de sekvado. Kiam vi ricevos unu, ĝi aperos ĉi tie.",
"empty_column.followed_tags": "Vi ankoraŭ ne sekvas iujn kradvortojn. Kiam vi faras, ili aperos ĉi tie.",
"empty_column.hashtag": "Ankoraŭ estas nenio per ĉi tiu kradvorto.",
@@ -292,19 +299,36 @@
"hashtag.column_settings.tag_mode.any": "Iu ajn",
"hashtag.column_settings.tag_mode.none": "Neniu",
"hashtag.column_settings.tag_toggle": "Aldoni pliajn etikedojn por ĉi tiu kolumno",
"hashtag.counter_by_accounts": "{count, plural,one {{counter} partoprenanto} other {{counter} partoprenantoj}}",
"hashtag.counter_by_uses": "{count, plural,one {{counter} afiŝo} other {{counter} afiŝoj}}",
"hashtag.counter_by_uses_today": "{count, plural,one {{counter} afiŝo} other {{counter} afiŝoj}} hodiau",
"hashtag.follow": "Sekvi la kradvorton",
"hashtag.unfollow": "Ne plu sekvi la kradvorton",
"hashtags.and_other": "…kaj {count, plural,other {# pli}}",
"home.actions.go_to_explore": "Vidi kio populariĝas",
"home.actions.go_to_suggestions": "Trovi homojn por sekvi",
"home.column_settings.basic": "Bazaj agordoj",
"home.column_settings.show_reblogs": "Montri diskonigojn",
"home.column_settings.show_replies": "Montri respondojn",
"home.explore_prompt.body": "Via hejmafiŝaro havos miksitajn afiŝojn de kradvortoj kiujn vi elektis sekvi, personoj kiujn vi elektis sekvi, kaj afiŝoj kiujn ili suprenigis.",
"home.explore_prompt.title": "Ĉi tio estas via hejma paĝo en Mastodon.",
"home.hide_announcements": "Kaŝi la anoncojn",
"home.pending_critical_update.body": "Ĝisdatigu vian servilon de Mastodon kiel eble plej baldau!",
"home.pending_critical_update.link": "Vidi ĝisdatigojn",
"home.pending_critical_update.title": "Kritika sekurĝisdatigo estas disponebla!",
"home.show_announcements": "Montri anoncojn",
"interaction_modal.description.favourite": "Per konto ĉe Mastodon, vi povas stelumiti ĉi tiun afiŝon por sciigi la afiŝanton ke vi aprezigas ŝin kaj konservas por la estonteco.",
"interaction_modal.description.follow": "Kun konto ĉe Mastodon, vi povos sekvi {name} por vidi ties mesaĝojn en via hejmo.",
"interaction_modal.description.reblog": "Kun konto ĉe Mastodon, vi povas diskonigi ĉi tiun afiŝon, por ke viaj propraj sekvantoj vidu ĝin.",
"interaction_modal.description.reply": "Kun konto ĉe Mastodon, vi povos respondi al ĉi tiu mesaĝo.",
"interaction_modal.login.action": "Prenu min hejmen",
"interaction_modal.login.prompt": "Domajno de via hejma servilo, ekz. mastodon.social",
"interaction_modal.no_account_yet": "Ĉu ne estas ĉe Mastodon?",
"interaction_modal.on_another_server": "En alia servilo",
"interaction_modal.on_this_server": "En ĉi tiu servilo",
"interaction_modal.sign_in": "Vi ne estas ensalutita al ĉi tiu servilo.",
"interaction_modal.sign_in_hint": "Gvideto: Tio estas la retejo kie vi registris. Vi ankau povas tajpi vian plenan uzantonomon!",
"interaction_modal.title.favourite": "Stelumi la afiŝon de {name}",
"interaction_modal.title.follow": "Sekvi {name}",
"interaction_modal.title.reblog": "Akceli la afiŝon de {name}",
"interaction_modal.title.reply": "Respondi al la afiŝo de {name}",
@@ -320,6 +344,8 @@
"keyboard_shortcuts.direct": "por malfermi la kolumnon pri privataj mencioj",
"keyboard_shortcuts.down": "iri suben en la listo",
"keyboard_shortcuts.enter": "malfermi mesaĝon",
"keyboard_shortcuts.favourite": "Stelumi afiŝon",
"keyboard_shortcuts.favourites": "Malfermi la liston de la stelumoj",
"keyboard_shortcuts.federated": "Malfermi la frataran templinion",
"keyboard_shortcuts.heading": "Klavaraj mallongigoj",
"keyboard_shortcuts.home": "Malfermi la hejman templinion",
@@ -366,6 +392,7 @@
"lists.search": "Serĉi inter la homoj, kiujn vi sekvas",
"lists.subheading": "Viaj listoj",
"load_pending": "{count,plural, one {# nova elemento} other {# novaj elementoj}}",
"loading_indicator.label": "Ŝargado…",
"media_gallery.toggle_visible": "{number, plural, one {Kaŝi la bildon} other {Kaŝi la bildojn}}",
"moved_to_account_banner.text": "Via konto {disabledAccount} estas malvalidigita ĉar vi movis ĝin al {movedToAccount}.",
"mute_modal.duration": "Daŭro",
@@ -382,6 +409,7 @@
"navigation_bar.domain_blocks": "Blokitaj domajnoj",
"navigation_bar.edit_profile": "Redakti profilon",
"navigation_bar.explore": "Esplori",
"navigation_bar.favourites": "Stelumoj",
"navigation_bar.filters": "Silentigitaj vortoj",
"navigation_bar.follow_requests": "Petoj de sekvado",
"navigation_bar.followed_tags": "Sekvataj kradvortoj",
@@ -389,6 +417,7 @@
"navigation_bar.lists": "Listoj",
"navigation_bar.logout": "Adiaŭi",
"navigation_bar.mutes": "Silentigitaj uzantoj",
"navigation_bar.opened_in_classic_interface": "Afiŝoj, kontoj, kaj aliaj specifaj paĝoj kiuj estas malfermititaj defaulta en la klasika reta interfaco.",
"navigation_bar.personal": "Persone",
"navigation_bar.pins": "Alpinglitaj mesaĝoj",
"navigation_bar.preferences": "Preferoj",
@@ -398,6 +427,7 @@
"not_signed_in_indicator.not_signed_in": "Necesas saluti por aliri tiun rimedon.",
"notification.admin.report": "{name} raportis {target}",
"notification.admin.sign_up": "{name} kreis konton",
"notification.favourite": "{name} stelumis vian afiŝon",
"notification.follow": "{name} eksekvis vin",
"notification.follow_request": "{name} petis sekvi vin",
"notification.mention": "{name} menciis vin",
@@ -411,6 +441,7 @@
"notifications.column_settings.admin.report": "Novaj raportoj:",
"notifications.column_settings.admin.sign_up": "Novaj registriĝoj:",
"notifications.column_settings.alert": "Sciigoj de la retumilo",
"notifications.column_settings.favourite": "Stelumoj:",
"notifications.column_settings.filter_bar.advanced": "Montri ĉiujn kategoriojn",
"notifications.column_settings.filter_bar.category": "Rapida filtra breto",
"notifications.column_settings.filter_bar.show_bar": "Montri la breton de filtrilo",
@@ -428,6 +459,7 @@
"notifications.column_settings.update": "Redaktoj:",
"notifications.filter.all": "Ĉiuj",
"notifications.filter.boosts": "Diskonigoj",
"notifications.filter.favourites": "Stelumoj",
"notifications.filter.follows": "Sekvoj",
"notifications.filter.mentions": "Mencioj",
"notifications.filter.polls": "Balotenketaj rezultoj",
@@ -441,14 +473,29 @@
"notifications_permission_banner.enable": "Ŝalti retumilajn sciigojn",
"notifications_permission_banner.how_to_control": "Por ricevi sciigojn kiam Mastodon ne estas malfermita, ebligu labortablajn sciigojn. Vi povas regi precize kiuj specoj de interagoj generas labortablajn sciigojn per la supra butono {icon} post kiam ili estas ebligitaj.",
"notifications_permission_banner.title": "Neniam preterlasas iun ajn",
"onboarding.action.back": "Prenu min reen",
"onboarding.actions.back": "Prenu min reen",
"onboarding.actions.go_to_explore": "See what's trending",
"onboarding.actions.go_to_home": "Go to your home feed",
"onboarding.compose.template": "Saluton #Mastodon!",
"onboarding.follows.empty": "Bedaŭrinde, neniu rezulto estas montrebla nuntempe. Vi povas provi serĉi aŭ foliumi la esploran paĝon por trovi kontojn por sekvi, aŭ retrovi baldaŭ.",
"onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!",
"onboarding.follows.title": "Popular on Mastodon",
"onboarding.profile.discoverable": "Trovebligi mian profilon",
"onboarding.profile.discoverable_hint": "Kiam vi aliĝi al trovebleco ĉe Mastodon, viaj afiŝoj eble aperos en serĉaj rezultoj kaj populariĝoj, kaj via profilo eble estas sugestota al personoj kun similaj intereseoj al vi.",
"onboarding.profile.display_name": "Publika nomo",
"onboarding.profile.display_name_hint": "Via plena nomo aŭ via kromnomo…",
"onboarding.profile.lead": "Vi ĉiam povas plenigi ĉi tion poste en la agordoj, kie eĉ pli da personecigagordoj estas disponeblaj.",
"onboarding.profile.note": "Sinprezento",
"onboarding.profile.note_hint": "Vi povas @mencii aliajn homojn aŭ #kradvortojn…",
"onboarding.profile.save_and_continue": "Konservi kaj daŭrigi",
"onboarding.profile.title": "Profila fikso",
"onboarding.profile.upload_avatar": "Alŝuti profilbildon",
"onboarding.profile.upload_header": "Alŝuti profilkapbildon",
"onboarding.share.lead": "Sciigi personojn pri kiel ili povas trovi vin ĉe Mastodon!",
"onboarding.share.message": "Mi estas {username} en #Mastodon! Sekvu min ĉe {url}",
"onboarding.share.next_steps": "Eblaj malantauaj paŝoj:",
"onboarding.share.title": "Disvastigi vian profilon",
"onboarding.start.lead": "Your new Mastodon account is ready to go. Here's how you can make the most of it:",
"onboarding.start.skip": "Want to skip right ahead?",
"onboarding.start.title": "Vi atingas ĝin!",
@@ -460,6 +507,9 @@
"onboarding.steps.setup_profile.title": "Customize your profile",
"onboarding.steps.share_profile.body": "Let your friends know how to find you on Mastodon!",
"onboarding.steps.share_profile.title": "Share your profile",
"onboarding.tips.2fa": "<strong>Ĉu vi scias?</strong> Vi povas sekurigi vian konton per efektivigi dufaktora autentigo en via kontoagordoj.",
"onboarding.tips.accounts_from_other_servers": "<strong>Ĉu vi scias?</strong> Ĉar Mastodon estas sencentra, kelkaj profiloj kiujn vi trovi estas gastigitaj ĉe aliaj serviloj kiuj ne estas via.",
"onboarding.tips.migration": "<strong>Ĉu vi scias?</strong> Se vi sentas ke {domain} ne estas bona servilelekto por vi en la estonteco, vi povas translokiĝi al alia servilo de Mastodon sen malgajni viajn sekvantojn.",
"password_confirmation.mismatching": "Pasvorto konfirmo ne kongruas",
"picture_in_picture.restore": "Remetu ĝin",
"poll.closed": "Finita",

View File

@@ -606,7 +606,7 @@
"search.quick_action.status_search": "Publicaciones que coinciden con {x}",
"search.search_or_paste": "Buscar o pegar URL",
"search_popout.full_text_search_disabled_message": "No disponible en {domain}.",
"search_popout.full_text_search_logged_out_message": "Solo disponible si inicias sesión.",
"search_popout.full_text_search_logged_out_message": "Sólo disponible al iniciar sesión.",
"search_popout.language_code": "Código de idioma ISO",
"search_popout.options": "Opciones de búsqueda",
"search_popout.quick_actions": "Acciones rápidas",

View File

@@ -606,6 +606,7 @@
"search.quick_action.status_search": "Sobivad postitused {x}",
"search.search_or_paste": "Otsi või kleebi URL",
"search_popout.full_text_search_disabled_message": "Pole saadaval kohas {domain}.",
"search_popout.full_text_search_logged_out_message": "Saadaval vaid kui sisse logitud.",
"search_popout.language_code": "Keele ISO-kood",
"search_popout.options": "Otsimisvalikud",
"search_popout.quick_actions": "Kiirtegevused",

View File

@@ -1,7 +1,7 @@
{
"about.blocks": "کارسازهای نظارت شده",
"about.contact": "تماس:",
"about.disclaimer": "ماستودون نرم‌افزار آزاد و یک شرکت غیر انتفاعی آلمانی با مسئولیت محدود است.",
"about.disclaimer": "ماستودون نرم‌افزار آزاد و نشان تجاری یک شرکت غیر انتفاعی با مسئولیت محدود آلمانی است.",
"about.domain_blocks.no_reason_available": "دلیلی موجود نیست",
"about.domain_blocks.preamble": "ماستودون عموماً می‌گذارد محتوا را از از هر کارساز دیگری در دنیای شبکه‌های اجتماعی غیرمتمرکز دیده و با آنان برهم‌کنش داشته باشید. این‌ها استثناهایی هستند که روی این کارساز خاص وضع شده‌اند.",
"about.domain_blocks.silenced.explanation": "عموماً نمایه‌ها و محتوا از این کارساز را نمی‌بینید، مگر این که به طور خاص دنبالشان گشته یا با پی گیری، داوطلب دیدنشان شوید.",
@@ -21,6 +21,7 @@
"account.blocked": "مسدود",
"account.browse_more_on_origin_server": "مرور بیش‌تر روی نمایهٔ اصلی",
"account.cancel_follow_request": "رد کردن درخواست پی‌گیری",
"account.copy": "رونوشت از پیوند به نمایه",
"account.direct": "اشارهٔ خصوصی به @{name}",
"account.disable_notifications": "آگاه کردن من هنگام فرسته‌های @{name} را متوقّف کن",
"account.domain_blocked": "دامنه مسدود شد",
@@ -191,6 +192,7 @@
"conversation.mark_as_read": "علامت‌گذاری به عنوان خوانده شده",
"conversation.open": "دیدن گفتگو",
"conversation.with": "با {names}",
"copy_icon_button.copied": "در بریده‌دان رونوشت شد",
"copypaste.copied": "رونوشت شد",
"copypaste.copy_to_clipboard": "رونوشت به تخته‌گیره",
"directory.federated": "از کارسازهای شناخته‌شده",
@@ -486,6 +488,8 @@
"onboarding.profile.note_hint": "می‌توانید افراد دیگر را @نام‌بردن یا #برچسب بزنید…",
"onboarding.profile.save_and_continue": "ذخیره کن و ادامه بده",
"onboarding.profile.title": "تنظیم نمایه",
"onboarding.profile.upload_avatar": "بازگذاری تصویر نمایه",
"onboarding.profile.upload_header": "بارگذاری تصویر سردر نمایه",
"onboarding.share.lead": "بگذارید افراد بدانند چگونه می‌توانند در ماستادون بیابندتان!",
"onboarding.share.message": "من {username} روی #ماستودون هستم! مرا در {url} پی‌بگیرید",
"onboarding.share.next_steps": "گام‌های ممکن بعدی:",
@@ -600,6 +604,7 @@
"search.quick_action.status_search": "فرسته‌های جور با {x}",
"search.search_or_paste": "جست‌وجو یا جایگذاری نشانی",
"search_popout.full_text_search_disabled_message": "روی {domain} موجود نیست.",
"search_popout.full_text_search_logged_out_message": "تنها زمانی که وارد شده‌اید دردسترس است.",
"search_popout.language_code": "کد زبان ایزو",
"search_popout.options": "گزینه‌های جست‌وجو",
"search_popout.quick_actions": "کنش‌های سریع",

View File

@@ -0,0 +1,145 @@
{
"about.blocks": "Mga pinatimping server",
"about.contact": "Kontak:",
"about.disclaimer": "Ang Mastodon ay software na malaya at bukas-na-pinagmulan, at isang tatak-pangkalakal ng Mastodon gGmbH.",
"about.domain_blocks.no_reason_available": "Hindi makuha ang dahilan",
"about.domain_blocks.silenced.title": "Limitado",
"about.domain_blocks.suspended.title": "Suspendido",
"about.rules": "Mga alituntunin ng server",
"account.account_note_header": "Tala",
"account.add_or_remove_from_list": "I-dagdag o tanggalin mula sa mga listahan",
"account.badges.bot": "Pakusa",
"account.badges.group": "Pangkat",
"account.block": "Hadlangan si @{name}",
"account.block_domain": "Hadlangan ang domain na {domain}",
"account.block_short": "Hadlangan",
"account.blocked": "Hinadlangan",
"account.browse_more_on_origin_server": "Tingnan pa sa pangunahing profile",
"account.cancel_follow_request": "I-kansela ang pagsunod",
"account.copy": "I-sipi ang kawing sa profile",
"account.direct": "Palihim banggitin si @{name}",
"account.disable_notifications": "I-tigil ang pagpapaalam sa akin tuwing nagpopost si @{name}",
"account.domain_blocked": "Hinadlangan ang domain",
"account.edit_profile": "Baguhin ang profile",
"account.enable_notifications": "Ipaalam sa akin kapag nag-post si @{name}",
"account.endorse": "I-tampok sa profile",
"account.featured_tags.last_status_at": "Huling post noong {date}",
"account.featured_tags.last_status_never": "Walang mga post",
"account.featured_tags.title": "Nakatampok na hashtag ni {name}",
"account.follow": "Sundan",
"account.followers": "Mga tagasunod",
"account.followers.empty": "Wala pang sumusunod sa tagagamit na ito.",
"account.following": "Sinusundan",
"account.follows.empty": "Wala pang sinusundan ang tagagamit na ito.",
"account.follows_you": "Sinusunod ka",
"account.go_to_profile": "Pumunta sa profile",
"account.hide_reblogs": "Itago ang mga pagpapalakas mula sa {name}",
"account.in_memoriam": "Sa Alaala Ni.",
"account.joined_short": "Sumali",
"account.languages": "Palitan ang mga nakasumuscribing wika",
"account.link_verified_on": "Sinuri ang pagmamay-ari ng kawing ito sa {date}",
"account.locked_info": "Nakakandado ang pagsasariling kalagayan ng account na ito. Manomano sinusuri ng may-ari kung sino ang maaaring sumunod sa kanya.",
"account.media": "Medya",
"account.mention": "Banggitin si @{name}",
"account.moved_to": "Ipinahihiwatig ni {name} na ang kanilang bagong account ngayon ay:",
"bundle_column_error.error.title": "Naku!",
"bundle_column_error.network.body": "Nagkaroon ng kamalian habang sinusubukang i-karga ang pahinang ito. Maaaring dahil ito sa pansamantalang problema ng iyong koneksyon sa internet o ang server na ito.",
"bundle_column_error.network.title": "Kamaliang network",
"bundle_column_error.retry": "Subukang muli",
"bundle_column_error.return": "Bumalik sa tahanan",
"bundle_column_error.routing.body": "Hindi mahanap ang hiniling na pahina. Sigurado ka ba na ang URL sa address bar ay tama?",
"bundle_column_error.routing.title": "404",
"bundle_modal_error.close": "I-sara",
"bundle_modal_error.message": "May nangyaring mali habang kinakarga ang bahaging ito.",
"bundle_modal_error.retry": "Subukang muli",
"closed_registrations.other_server_instructions": "Dahil desentralisado ang Mastodon, pwede kang gumawa ng account sa iba pang server at makipag-ugnayan pa rin dito.",
"closed_registrations_modal.description": "Hindi pa pwedeng gumawa ng account sa {domain}, pero tandaan na hindi mo kailangan ng account partikular sa {domain} para gamitin ang Mastodon.",
"closed_registrations_modal.find_another_server": "Maghanap ng iba pang server",
"closed_registrations_modal.preamble": "Dahil desentralisado ang Mastodon, kahit saan ka pa gumawa ng account, maaari ka pa ring sumunod at makipag-ugnayan sa kahit-sino rito sa server na ito. Pwede mo pang i-host nang pasarili!",
"closed_registrations_modal.title": "Pagrerehistro sa Mastodon",
"column.about": "Tungkol dito",
"column.blocks": "Nakahadlang na mga tagagamit",
"column.bookmarks": "Mga bookmark",
"column.community": "Lokal na timeline",
"column.direct": "Mga palihim na banggit",
"column.directory": "Tingnan ang mga profile",
"column.domain_blocks": "Nakahadlang na mga domain",
"column.favourites": "Mga paborito",
"column.firehose": "Mga live feed",
"column.follow_requests": "Mga hiling para sundan",
"column.home": "Tahanan",
"column.lists": "Mga listahan",
"column.mutes": "Mga pinatahimik na tagagamit",
"column.notifications": "Mga abiso",
"column.pins": "Mga nakapaskil na post",
"column.public": "Pinagsamang timeline",
"column_back_button.label": "Bumalik",
"column_header.hide_settings": "I-tago ang mga setting",
"column_header.moveLeft_settings": "I-lipat ang hanay pakaliwa",
"column_header.moveRight_settings": "I-lipat ang hanay pakanan",
"column_header.pin": "I-paskil",
"column_header.show_settings": "Ipakita ang mga setting",
"column_header.unpin": "Tanggalin sa pagkapaskil",
"column_subheading.settings": "Mga setting",
"community.column_settings.local_only": "Lokal lamang",
"community.column_settings.media_only": "Medya Lamang",
"community.column_settings.remote_only": "Liblib lamang",
"compose.language.change": "Magpalit ng wika",
"compose.language.search": "Maghanap ng mga wika...",
"compose.published.body": "Nailathala ang post.",
"compose.published.open": "Buksan",
"compose.saved.body": "Nai-save ang post.",
"compose_form.direct_message_warning_learn_more": "Matuto pa",
"compose_form.encryption_warning": "Ang mga post sa Mastodon ay hindi naka-encrypt nang dulo-dulo. Huwag magbahagi ng anumang sensitibong impormasyon sa Mastodon.",
"compose_form.hashtag_warning": "Hindi maililista ang post na ito sa anumang hashtag dahil hindi ito nakapubliko. Mga nakapublikong post lamang ang mahahanap ayon sa hashtag.",
"copy_icon_button.copied": "Sinipi sa clipboard",
"copypaste.copied": "Sinipi",
"copypaste.copy_to_clipboard": "I-sipi sa clipboard",
"directory.federated": "Mula sa kilalang fediverse",
"directory.local": "Mula sa {domain} lamang",
"directory.new_arrivals": "Mga bagong dating",
"directory.recently_active": "Kamakailang aktibo",
"disabled_account_banner.account_settings": "Mga setting ng account",
"disabled_account_banner.text": "Ang iyong account na {disabledAccount} ay hindi pinapagana ngayon.",
"dismissable_banner.community_timeline": "Ito ang mga pinakamakailang nakapublikong post mula sa mga taong ang mga account hinohost ng {domain}.",
"dismissable_banner.dismiss": "Alisin",
"dismissable_banner.explore_links": "Ito ang mga balitang kwento na pinaka-binabahagi sa social web ngayon. Ang mga mas bagong balitang kwento na pinost ng mas marami pang mga iba't ibang tao ay tinataasan ng antas.",
"dismissable_banner.explore_statuses": "Ito ang mga sumisikat na mga post sa iba't ibang bahagi ng social web ngayon. Ang mga mas bagong post na mas marami ang mga pagpapalakas at paborito ay tinataasan ng antas.",
"dismissable_banner.explore_tags": "Ito ang mga sumisikat na mga hashtag sa iba't ibang bahagi ng social web ngayon. Ang mga hashtag ginagamit ng mas maraming mga iba't ibang tao ay tinataasan ng antas.",
"dismissable_banner.public_timeline": "Ito ang mga pinakamakailang nakapublikong post mula sa mga taong nasa social web na sinusundan ng mga tao sa {domain}.",
"embed.instructions": "I-embed ang post na ito sa iyong pook-sapot sa pamamagitan ng pagsipi ng kodigo sa ilalim.",
"embed.preview": "Ito ang magiging itsura:",
"emoji_button.activity": "Aktibidad",
"emoji_button.clear": "Linisin",
"emoji_button.custom": "Pasadya",
"emoji_button.flags": "Mga watawat",
"emoji_button.food": "Pagkain at Inumin",
"emoji_button.label": "Maglagay ng emoji",
"emoji_button.nature": "Kalikasan",
"emoji_button.not_found": "Walang mahanap na mga tugmang emoji",
"emoji_button.objects": "Mga bagay",
"emoji_button.people": "Mga tao",
"emoji_button.recent": "Madalas na ginagamit",
"emoji_button.search": "Maghanap...",
"emoji_button.search_results": "Resulta ng paghahanap",
"emoji_button.symbols": "Mga tanda",
"emoji_button.travel": "Paglakbay at Mga Lugar",
"empty_column.account_hides_collections": "Pinili ng tagagamit na ito na hindi makuha ang impormasyong ito",
"empty_column.account_suspended": "Sinuspinde ang account",
"empty_column.account_timeline": "Walang mga post dito!",
"empty_column.account_unavailable": "Hindi makuha ang profile",
"empty_column.blocks": "Hindi ka pa naghahadlang ng sinumang tagagamit.",
"empty_column.bookmarked_statuses": "Wala ka pang naka-bookmark na post. Kapag nag-bookmark ka ng isa, makikita yun dito.",
"empty_column.community": "Walang laman ang lokal na timeline. Magsulat ng anuman papubliko para makaandar tayo!",
"empty_column.direct": "Wala ka pang mga palihim na banggit. Kapag nagpadala o tumanggap ka ng isa, makikita yun dito.",
"empty_column.domain_blocks": "Wala pang nakahadlang na domain.",
"empty_column.explore_statuses": "Wala pang sumisikat sa ngayon. Balik na lang sa muli!",
"empty_column.favourited_statuses": "Wala ka pang mga paboritong post. Kapag nag-paborito ka ng isa, makikita yun dito.",
"empty_column.favourites": "Wala pang may paborito ng post na ito. Kung may sinumang nagpaborito, makikita sila rito.",
"empty_column.follow_requests": "Wala ka pang mga hiling para sundan ka. Kapag nakatanggap ka ng isa, makikita yun dito.",
"empty_column.followed_tags": "Wala ka pang sinusunod na hashtag. Kapag may sinundan ka na, makikita sila rito.",
"empty_column.hashtag": "Wala pang laman ang hashtag na ito.",
"empty_column.home": "Walang laman ang timeline ng tahanan mo! Sumunod sa marami pang tao para mapunan ito.",
"empty_column.list": "Wala pang laman ang listahang ito. Kapag naglathala ng mga bagong post ang mga miyembro ng listahang ito, makikita iyon dito.",
"empty_column.lists": "Wala ka pang mga listahan. Kapag gumawa ka ng isa, makikita yun dito."
}

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