Porównaj commity

...

1442 Commity

Autor SHA1 Wiadomość Data
Alex Gleason 967bf8f30a Merge branch 'vitest-fixes' into 'develop'
Vitest fixes

See merge request soapbox-pub/soapbox!2700
2023-09-17 01:54:27 +00:00
Alex Gleason 9f15991ab5 Merge branch 'exif-fix' into 'develop'
Swap out exif-js for exifr

Closes #1519

See merge request soapbox-pub/soapbox!2701
2023-09-17 01:54:12 +00:00
Alex Gleason 5c39df09de
Swap out exif-js for exifr 2023-09-16 20:14:24 -05:00
Alex Gleason ecb7a0d825
Upgrade axios-mock-adapter 2023-09-16 18:46:55 -05:00
Alex Gleason 5ab87616c1
vitest: jest --> vi 2023-09-16 15:16:59 -05:00
Alex Gleason afaac6eed2
vitest: add setup file, use @testing-library/jest-dom 2023-09-16 15:16:35 -05:00
Alex Gleason 79b837cb89
Upgrade @testing-library deps, move to devDependencies 2023-09-16 14:40:10 -05:00
Alex Gleason f5a3a26dae
tsconfig: fix third-party types 2023-09-16 14:36:53 -05:00
Alex Gleason cf1f2326a2 Merge branch 'renovate/clsx-2.x' into 'develop'
fix(deps): update dependency clsx to v2

See merge request soapbox-pub/soapbox!2694
2023-09-16 19:12:35 +00:00
Soapbox Bot d6c24ac8a5 fix(deps): update dependency clsx to v2 2023-09-16 18:07:25 +00:00
Alex Gleason 7ccb5edd2c Merge branch 'eslint-upgrades' into 'develop'
Eslint upgrades

See merge request soapbox-pub/soapbox!2698
2023-09-16 17:43:37 +00:00
Alex Gleason 14e296fb90
audio: fix compat/compat eslint error 2023-09-16 12:21:37 -05:00
Alex Gleason 1640c2bc87
yarn lint:js --fix 2023-09-16 12:20:19 -05:00
Alex Gleason 64ded8039f
eslint: @typescript-eslint/no-duplicate-imports --> import/no-duplicates 2023-09-16 12:19:33 -05:00
Alex Gleason 7e4915864a
Upgrade eslint everything 2023-09-16 12:16:17 -05:00
Alex Gleason 4d14157926 Merge branch 'renovate/major-typescript-eslint-monorepo' into 'develop'
chore(deps): update typescript-eslint monorepo to v6 (major)

See merge request soapbox-pub/soapbox!2689
2023-09-16 14:02:17 +00:00
Alex Gleason 663c8de42b Merge branch 'renovate/fontsource-roboto-mono-5.x' into 'develop'
fix(deps): update dependency @fontsource/roboto-mono to v5

See merge request soapbox-pub/soapbox!2692
2023-09-16 14:01:11 +00:00
Soapbox Bot b300681817 fix(deps): update dependency @fontsource/roboto-mono to v5 2023-09-16 13:06:17 +00:00
Soapbox Bot d85e003efb chore(deps): update typescript-eslint monorepo to v6 2023-09-16 13:05:45 +00:00
Alex Gleason f1c08007ad Merge branch 'upgrade-stylelint' into 'develop'
Upgrade stylelint, fix scss linting

See merge request soapbox-pub/soapbox!2691
2023-09-16 12:19:44 +00:00
Alex Gleason d3709b6e1e Merge branch 'renovate/fontsource-inter-5.x' into 'develop'
fix(deps): update dependency @fontsource/inter to v5

See merge request soapbox-pub/soapbox!2690
2023-09-16 12:19:17 +00:00
Alex Gleason 2a5f24e46a
Upgrade stylelint, fix scss linting 2023-09-16 07:17:00 -05:00
Soapbox Bot 828e43af42 fix(deps): update dependency @fontsource/inter to v5 2023-09-16 12:06:17 +00:00
Alex Gleason a9cced80fe Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2682
2023-09-16 11:30:58 +00:00
Alex Gleason 6fc9eee210 Merge branch 'renovate/docker-24.x' into 'develop'
chore(deps): update docker docker tag to v24

See merge request soapbox-pub/soapbox!2619
2023-09-16 11:29:32 +00:00
Alex Gleason 70922bba8e Merge branch 'renovate/floating-ui-react-0.x' into 'develop'
fix(deps): update dependency @floating-ui/react to ^0.25.0

See merge request soapbox-pub/soapbox!2655
2023-09-16 11:28:38 +00:00
Alex Gleason 99b460d1fa Merge branch 'renovate/stylelint-config-standard-scss-11.x' into 'develop'
chore(deps): update dependency stylelint-config-standard-scss to v11

See merge request soapbox-pub/soapbox!2685
2023-09-16 11:27:59 +00:00
Alex Gleason 873837e5da Merge branch 'cycles' into 'develop'
Resolve some circular dependencies

See merge request soapbox-pub/soapbox!2688
2023-09-16 11:19:30 +00:00
Alex Gleason 816d48a395
entity hooks: resolve some circular dependencies 2023-09-16 06:08:46 -05:00
Alex Gleason 1a036ecee0
Card: prevent circular dependencies 2023-09-16 05:52:04 -05:00
Alex Gleason caa05b7b7f
hooks: resolve some circular dependencies 2023-09-16 05:47:11 -05:00
Alex Gleason 91dad5f96c Merge branch 'fix-tailwindcss-aspect-ratio' into 'develop'
Put @tailwindscss/aspect-ratio in production, not development

See merge request soapbox-pub/soapbox!2680
2023-09-16 08:41:17 +00:00
NEETzsche 0f00a699ff Put @tailwindscss/aspect-ratio in production, not development 2023-09-16 08:41:17 +00:00
Soapbox Bot 2fa4626167 chore(deps): update dependency stylelint-config-standard-scss to v11 2023-09-16 05:05:58 +00:00
Tassoman a4b2d83e57
Translated using Weblate (Italian)
Currently translated at 99.6% (1587 of 1592 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/it/
2023-09-16 06:16:23 +02:00
Salif Mehmed d31ed78b41
Translated using Weblate (Bulgarian)
Currently translated at 17.8% (284 of 1592 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/bg/
2023-09-16 06:16:23 +02:00
Alex Gleason de5eb96553 Merge branch 'bundle-analyzer' into 'develop'
Emit a report.html bundle analysis

Closes #1517

See merge request soapbox-pub/soapbox!2687
2023-09-16 04:16:15 +00:00
Alex Gleason 26debebd9e
Emit a report.html bundle analysis
Fixes https://gitlab.com/soapbox-pub/soapbox/-/issues/1517
2023-09-15 23:05:58 -05:00
Alex Gleason a969878763 Merge branch 'server-generated-meta' into 'develop'
vite: don't strip comments from index.html, restore server-generated-meta

See merge request soapbox-pub/soapbox!2686
2023-09-16 03:49:32 +00:00
Alex Gleason 49f8b1e55e
vite: don't strip comments from index.html, restore server-generated-meta 2023-09-15 22:38:29 -05:00
Alex Gleason 36b41e06e4 Merge branch 'vitest' into 'develop'
Switch to Vitest

See merge request soapbox-pub/soapbox!2683
2023-09-16 01:21:50 +00:00
Alex Gleason 215221f64f
jest.requireActual --> vi.importActual 2023-09-15 19:51:40 -05:00
Alex Gleason 839cc7b9ae Merge branch 'webpackchunkname' into 'develop'
Remove `webpackChunkName` magic comments

See merge request soapbox-pub/soapbox!2684
2023-09-16 00:41:43 +00:00
Alex Gleason da49327b35
Remove `@testing-library/jest-dom` imports 2023-09-15 19:30:51 -05:00
Alex Gleason 79a764177d
Remove `webpackChunkName` magic comments 2023-09-15 19:27:59 -05:00
Alex Gleason 2ffc79b75b
Remove Jest 2023-09-15 19:19:49 -05:00
Alex Gleason fd2bad74e9
Switch to flexsearch-es 2023-09-15 19:14:05 -05:00
Alex Gleason 50736e025f
vitest: run without NODE_ENV=test (???) 2023-09-15 18:53:30 -05:00
Alex Gleason f8392d22d3
vitest: put cache properly in node_modules 2023-09-15 17:19:13 -05:00
Alex Gleason da2f942563
Add vitest, make some tests actually kind of work! 2023-09-15 16:24:01 -05:00
Alex Gleason 0a30a31e61 Merge branch 'vite-sw2' into 'develop'
Build the ServiceWorker with Vite

See merge request soapbox-pub/soapbox!2681
2023-09-15 19:55:09 +00:00
Alex Gleason dcad4bb4f7
Build the ServiceWorker with Vite 2023-09-15 14:37:09 -05:00
Alex Gleason ba22fed03c
entry.ts --> sw.ts 2023-09-15 14:20:51 -05:00
Alex Gleason 0088d908c0
sw: convert web-push-locales to TypeScript, load it with compileTime plugin 2023-09-15 14:11:45 -05:00
Alex Gleason a9624dea9a
package.json: empty outDir when building, add `yarn preview` 2023-09-15 14:08:50 -05:00
Alex Gleason 1c7b95f12a
Attempt to register sw.js on pageload 2023-09-15 14:07:59 -05:00
Alex Gleason d34eaa8be2 Merge branch 'vite-fixes' into 'develop'
Vite fixes

See merge request soapbox-pub/soapbox!2679
2023-09-15 02:57:54 +00:00
Alex Gleason 5aa5966938
Remove offline plugin 2023-09-14 20:41:48 -05:00
Alex Gleason 50047f90cf
gitignore vite temp files 2023-09-14 20:40:58 -05:00
Alex Gleason 0fd465af09
sw: delete unnecessary file 2023-09-14 20:40:30 -05:00
Alex Gleason e6d9be15de
vite: reorganize output directory 2023-09-14 20:40:20 -05:00
Alex Gleason f0e5aaded4
vite: disable inline assets so CSP will pass 2023-09-14 20:38:56 -05:00
Alex Gleason 02866ac53f Merge branch 'bugfixes' into 'develop'
ProfilePage: don't load account note panel until account is loaded

Closes #1514

See merge request soapbox-pub/soapbox!2677
2023-09-14 19:18:52 +00:00
Alex Gleason 1e3b89ad13
ProfileFamiliarFollowers: use a div for the text element, fix console error 2023-09-14 13:48:21 -05:00
Alex Gleason d628249232
ProfilePage: don't load account note panel until account is loaded
Fixes https://gitlab.com/soapbox-pub/soapbox/-/issues/1514
2023-09-14 13:45:09 -05:00
Alex Gleason b787b4cca7
ProfileFamiliarFollowers: add `key` prop, fix console error 2023-09-14 13:45:02 -05:00
Alex Gleason c242f8e9c7 Merge branch 'hotkeys' into 'develop'
Temporarily disable hotkeys

Closes #1515

See merge request soapbox-pub/soapbox!2676
2023-09-14 18:14:51 +00:00
Alex Gleason e83351f376
Temporarily disable hotkeys 2023-09-14 13:04:14 -05:00
Alex Gleason 76e8e2e999
Create a wrapper component around react-hotkeys 2023-09-14 12:59:30 -05:00
Alex Gleason 023e9135a8 Merge branch 'alexgleason-develop-patch-78175' into 'develop'
Restore 404.html

See merge request soapbox-pub/soapbox!2675
2023-09-14 03:56:16 +00:00
Alex Gleason 2951c57a32 Restore 404.html 2023-09-14 03:46:18 +00:00
Alex Gleason 005d8fa246 Merge branch 'i18n-dynamic' into 'develop'
Fix locale dynamic imports

See merge request soapbox-pub/soapbox!2674
2023-09-14 03:22:47 +00:00
Alex Gleason 97c1dbbd79
Fix locale dynamic imports 2023-09-13 21:59:39 -05:00
Alex Gleason 09ca18891f Merge branch 'browserlist-update' into 'develop'
browserlist: target newer browsers

See merge request soapbox-pub/soapbox!2673
2023-09-13 22:05:19 +00:00
Alex Gleason 4819b3d595
browserlist: target newer browsers 2023-09-13 16:52:23 -05:00
Alex Gleason a4e78db516 Merge branch 'vite-babel' into 'develop'
Add back Babel

See merge request soapbox-pub/soapbox!2672
2023-09-13 21:50:01 +00:00
Alex Gleason 6e5520ce17
Add back Babel 2023-09-13 16:38:46 -05:00
Soapbox Bot 4a74110432 fix(deps): update dependency @floating-ui/react to ^0.25.0 2023-09-13 20:05:04 +00:00
Alex Gleason ecf34537d8 Merge branch 'set-immediate' into 'develop'
Thread: replace call to setImmediate

See merge request soapbox-pub/soapbox!2670
2023-09-13 19:18:51 +00:00
Alex Gleason 19bf51165c
Thread: replace call to setImmediate 2023-09-13 14:17:30 -05:00
Alex Gleason 2fb13a0145 Merge branch 'stop-python-deps' into 'develop'
GitLab CI: stop python dependency scanning

See merge request soapbox-pub/soapbox!2669
2023-09-13 19:16:30 +00:00
Alex Gleason 3f0fc573be
GitLab CI: stop python dependency scanning 2023-09-13 14:15:35 -05:00
Alex Gleason a6237b18f8 Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2665
2023-09-13 19:10:55 +00:00
Alex Gleason ec9eae8174 Merge branch 'rm-webpack' into 'develop'
Delete Webpack

See merge request soapbox-pub/soapbox!2667
2023-09-13 19:10:17 +00:00
Alex Gleason 7b8745c44d Merge branch 'develop' into 'develop'
fix scheduled post cancel button text

See merge request soapbox-pub/soapbox!2668
2023-09-13 19:06:18 +00:00
animegrafmays 301c5224bf clarify we mean to discard the post 2023-09-13 15:02:48 -04:00
animegrafmays 870f2c85a2 fix scheduled post cancel button text 2023-09-13 14:54:27 -04:00
Alex Gleason 64686101c6
npx yarn-deduplicate yarn.lock 2023-09-13 13:42:05 -05:00
Alex Gleason 96c09847c4
Add back necessary sass deps 2023-09-13 13:39:57 -05:00
Alex Gleason e1357fbf66
npx yarn-deduplicate yarn.lock 2023-09-13 13:17:46 -05:00
Alex Gleason 059342ceb8
Remove webpack 2023-09-13 13:16:03 -05:00
Alex Gleason 54413ceb8e Merge branch 'vite3' into 'develop'
Build with Vite

Closes #1326

See merge request soapbox-pub/soapbox!2666
2023-09-13 18:08:05 +00:00
Alex Gleason d94fb91c64
GitLab CI: ignore the broken manageTranslations script for now 2023-09-13 13:00:35 -05:00
Alex Gleason b32de7dab0
vite: serve on port 3036 2023-09-13 12:24:49 -05:00
Alex Gleason 26355eb4ec
tsconfig: remove webworker lib, use triple-slash directive 2023-09-13 12:19:57 -05:00
Alex Gleason 88d1dc8e8a
GitLab CI: disable Jest for now 2023-09-13 12:14:03 -05:00
Alex Gleason 24391b5705
Merge remote-tracking branch 'origin/develop' into vite3 2023-09-13 12:13:23 -05:00
Alex Gleason 0f9c42abbc Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2652
2023-09-13 17:13:08 +00:00
Hosted Weblate 80e8aa5c6d
Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/
2023-09-13 19:12:56 +02:00
Endermancrop 904158c3e7
Translated using Weblate (Persian)
Currently translated at 71.3% (1137 of 1593 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/fa/
2023-09-13 19:12:55 +02:00
Poesty Li d5137058aa
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1593 of 1593 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-09-13 19:12:55 +02:00
marcin mikołajczak e64bac64c4
Translated using Weblate (Polish)
Currently translated at 99.5% (1586 of 1593 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/pl/
2023-09-13 19:12:55 +02:00
Tassoman 192977f0be
Translated using Weblate (Italian)
Currently translated at 100.0% (1593 of 1593 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/it/
2023-09-13 19:12:55 +02:00
Alex Gleason b4ef27acea Merge branch 'rm-license-scanning' into 'develop'
GitLab CI: remove deprecated license scanning

See merge request soapbox-pub/soapbox!2664
2023-09-13 17:12:40 +00:00
Alex Gleason 6a4b55da39
GitLab CI: remove deprecated license scanning 2023-09-13 12:12:05 -05:00
Alex Gleason 2acab99e5b
Make Vite devserver work 2023-09-13 12:04:17 -05:00
Hosted Weblate 9bf65353f5
Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/
2023-09-12 12:09:05 +02:00
Endermancrop 3b912ef5e7
Translated using Weblate (Persian)
Currently translated at 71.3% (1137 of 1593 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/fa/
2023-09-12 12:08:55 +02:00
Poesty Li c7711c3ab0
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1593 of 1593 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-09-12 12:08:55 +02:00
marcin mikołajczak 983471b003
Translated using Weblate (Polish)
Currently translated at 99.5% (1586 of 1593 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/pl/
2023-09-12 12:08:55 +02:00
Tassoman 7f360a57bf
Translated using Weblate (Italian)
Currently translated at 100.0% (1593 of 1593 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/it/
2023-09-12 12:08:55 +02:00
marcin mikołajczak f7b84982e3 Merge branch 'account-notes-panel' into 'develop'
Move account notes to a panel

See merge request soapbox-pub/soapbox!2661
2023-09-12 10:08:45 +00:00
marcin mikołajczak beb221576d Update en.json
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-09-12 11:52:37 +02:00
marcin mikołajczak b3cdb12e20 Merge branch 'compose-form-focus' into 'develop'
Fix compose form focus on home page

See merge request soapbox-pub/soapbox!2663
2023-09-12 09:37:01 +00:00
marcin mikołajczak c6df84b223 Fix compose form focus on home page
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-09-12 11:17:30 +02:00
marcin mikołajczak a2b4913fe7 Merge branch 'picture-picker-drag-files' into 'develop'
Allow to drag files to avatar/header pickers

See merge request soapbox-pub/soapbox!2662
2023-09-12 05:50:52 +00:00
marcin mikołajczak bc1b2fc07e Move account notes to a panel
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-09-12 01:13:31 +02:00
marcin mikołajczak 82c6f658e8 Allow to drag files to avatar/header pickers
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-09-12 01:11:07 +02:00
marcin mikołajczak d64f49334a Merge branch 'since-date-title' into 'develop'
Add title to created_at label

See merge request soapbox-pub/soapbox!2650
2023-09-11 22:05:55 +00:00
marcin mikołajczak 6319a4f65a
Merge branch 'compose-form-focus' into 'develop'
Compose: Don't focus on spoiler input on first render

See merge request soapbox-pub/soapbox!2659
2023-09-10 16:19:13 +00:00
marcin mikołajczak c942a101ec Compose: Don't focus on spoiler input on first render
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-09-10 16:49:48 +02:00
Alex Gleason 857c18f458
Merge branch 'bun-types' into 'develop'
bun: improve types so it runs with bun

See merge request soapbox-pub/soapbox!2658
2023-09-08 18:51:44 +00:00
Alex Gleason b476d6441e
bun: improve types so it runs with bun 2023-09-08 13:28:23 -05:00
Soapbox Bot 990944ddda chore(deps): update docker docker tag to v24 2023-09-06 03:05:29 +00:00
Alex Gleason b8e5fad334
Merge branch 'ditto-fe-config' into 'develop'
features: enable frontendConfigurations on Ditto

See merge request soapbox-pub/soapbox!2656
2023-09-04 00:14:56 +00:00
Alex Gleason a22c628c73
features: enable frontendConfigurations on Ditto 2023-09-03 18:48:07 -05:00
Alex Gleason 1398a4ba15
Merge branch 'favourites-own-account' into 'develop'
favourites: fix isOwnAccount check

See merge request soapbox-pub/soapbox!2654
2023-09-01 19:05:45 +00:00
Alex Gleason 41616c084e
favourites: fix isOwnAccount check 2023-09-01 13:48:24 -05:00
Alex Gleason 2ad7cb3b70
Merge branch 'ziro2264-develop-patch-29679' into 'develop'
Fix non-link list items not showing up properly

See merge request soapbox-pub/soapbox!2653
2023-08-31 13:34:42 +00:00
Ahmad Ansori Palembani edce3bb6b8 fix: body is not used if `ListItem` is not a link 2023-08-31 09:14:04 +00:00
Alex Gleason 85ddc7729a Merge branch 'nostr-cors-fix' into 'develop'
api: don't send the X-Nostr-Sign header unless the backend supports it

Closes #1505

See merge request soapbox-pub/soapbox!2651
2023-08-28 21:48:35 +00:00
Alex Gleason 6a8efcfc03
api: don't send the X-Nostr-Sign header unless the backend supports it 2023-08-28 16:28:51 -05:00
marcin mikołajczak f518a7e5e4 Add title to created_at label
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-08-28 19:58:11 +02:00
marcin mikołajczak 631c94f771 Merge branch 'links-a11y' into 'develop'
Prefer accessible links

See merge request soapbox-pub/soapbox!2648
2023-08-27 22:34:22 +00:00
marcin mikołajczak a6bdf651bf Fix types?
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-08-28 00:16:44 +02:00
marcin mikołajczak eafb6d318a Merge branch 'events' into 'develop'
Improve event information display

See merge request soapbox-pub/soapbox!2645
2023-08-27 22:06:19 +00:00
Alex Gleason 62d56634e0 Merge branch 'nip46' into 'develop'
Nostr: sign events with NIP-46

See merge request soapbox-pub/soapbox!2649
2023-08-27 15:50:09 +00:00
Alex Gleason 1011be5333
Nostr: sign events with NIP-46 2023-08-27 10:22:56 -05:00
marcin mikołajczak 14e2e07305 Prefer accessible links
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-08-25 23:19:56 +02:00
marcin mikołajczak c2a8044aa4 Merge branch 'badges-i18n' into 'develop'
Make all profile badges translatable

See merge request soapbox-pub/soapbox!2647
2023-08-25 21:04:05 +00:00
marcin mikołajczak d391193a03 Make all profile badges translatable
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-08-25 22:43:21 +02:00
Alex Gleason eb05a67671 Merge branch 'elainejackson-develop-patch-85233' into 'develop'
Fix Mastodon Media Uploads

See merge request soapbox-pub/soapbox!2646
2023-08-21 18:44:45 +00:00
Elaine Jackson d46d86529e Fix Mastodon Media Uploads 2023-08-21 18:42:44 +00:00
marcin mikołajczak 8bd8e60d4a Add keys to fragments
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-08-20 21:53:03 +02:00
marcin mikołajczak 29c9098a91 Improve event information display
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-08-20 14:51:23 +02:00
Alex Gleason a3470e6bb4 Merge branch 'fix-mastodon-nginx-conf' into 'develop'
Fix Mastodon Nginx Configuration

See merge request soapbox-pub/soapbox!2644
2023-08-18 17:53:46 +00:00
Elaine Jackson ef263434d3 Update file mastodon.conf 2023-08-18 17:52:25 +00:00
Alex Gleason 9242397229 Merge branch 'ditto-public-tl' into 'develop'
features: enable public timeline on Ditto

See merge request soapbox-pub/soapbox!2643
2023-08-18 02:48:28 +00:00
Alex Gleason 227c895562
features: enable public timeline on Ditto 2023-08-17 21:07:55 -05:00
Alex Gleason 3983242bbd Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2642
2023-08-17 20:56:20 +00:00
jonnysemon 2aeee0afe1
Translated using Weblate (Arabic)
Currently translated at 99.5% (1585 of 1592 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ar/
2023-08-17 22:49:44 +02:00
marcin mikołajczak 6af776f289 Merge branch 'events' into 'develop'
Add missing margin-bottom to events list heading

See merge request soapbox-pub/soapbox!2641
2023-08-14 21:09:02 +00:00
marcin mikołajczak 95829aa289 Add margin-bottom to events list heading
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-08-14 22:37:42 +02:00
Alex Gleason f409bc771b Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2608
2023-08-10 20:31:28 +00:00
marcin mikołajczak 5a678f84c7
Translated using Weblate (Polish)
Currently translated at 99.4% (1584 of 1592 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/pl/
2023-08-10 21:58:07 +02:00
Adrien Bourmault 9044172b1e
Translated using Weblate (French)
Currently translated at 88.0% (1402 of 1592 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/fr/
2023-08-10 21:58:07 +02:00
Hosted Weblate e81634d0e5
Update translation files
Updated by "Remove blank strings" hook in Weblate.

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/
2023-08-10 21:58:07 +02:00
Adrien Bourmault ae6c84ef36
Translated using Weblate (French)
Currently translated at 87.5% (1394 of 1592 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/fr/
2023-08-10 21:58:07 +02:00
Liberal dev 9db8157ff1
Translated using Weblate (Korean)
Currently translated at 70.6% (1125 of 1592 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ko/
2023-08-10 21:58:06 +02:00
Poesty Li d07635131c
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1592 of 1592 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-08-10 21:58:06 +02:00
Tomíček Rosič ed0fe6198c
Translated using Weblate (Icelandic)
Currently translated at 70.9% (1129 of 1592 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/is/
2023-08-10 21:58:06 +02:00
Hosted Weblate 3d9e7a8fec
Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/
2023-08-10 21:58:06 +02:00
marcin mikołajczak 6b982af9cd
Translated using Weblate (Polish)
Currently translated at 96.8% (1544 of 1594 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/pl/
2023-08-10 21:58:06 +02:00
marcin mikołajczak 74fe1d2df1
Translated using Weblate (Polish)
Currently translated at 96.2% (1534 of 1594 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/pl/
2023-08-10 21:58:06 +02:00
jonnysemon 1e7a5fb655
Translated using Weblate (Arabic)
Currently translated at 99.6% (1589 of 1594 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ar/
2023-08-10 21:58:06 +02:00
Alex Gleason 085f686c7d Merge branch 'oakes/mute-block-response' into 'develop'
Update unmute/unblock buttons correctly

See merge request soapbox-pub/soapbox!2640
2023-08-10 19:57:58 +00:00
oakes f19ac4b19e Import response data from mute/block endpoints 2023-08-10 15:33:27 -04:00
Alex Gleason fd74551fad Merge branch 'oakes/follow-hashtag' into 'develop'
Fix "follow hashtag" toggle

See merge request soapbox-pub/soapbox!2638
2023-08-02 22:44:24 +00:00
Alex Gleason 331252eb4f Merge branch 'oakes/hide-favorites' into 'develop'
Default to hiding Likes tab for other users

See merge request soapbox-pub/soapbox!2637
2023-08-02 20:14:12 +00:00
oakes c384aa6db2 Pass id to useEffect so it runs when id changes 2023-08-02 15:38:50 -04:00
oakes efb3097c80 Set default for 'checked' property 2023-08-02 15:33:04 -04:00
oakes 0a7d0105ff Default to hiding Likes tab 2023-07-31 13:29:27 -04:00
Alex Gleason 5a988cb528 Merge branch 'fix-reports' into 'develop'
Fix reported statuses not showing up

Closes #1494

See merge request soapbox-pub/soapbox!2635
2023-07-31 01:47:39 +00:00
Alex Gleason ef42144896
Fix reported statuses not showing up
Fixes https://gitlab.com/soapbox-pub/soapbox/-/issues/1494
2023-07-30 20:46:01 -05:00
Alex Gleason 0e1fdf7406 Merge branch 'list-btn-crash' into 'develop'
Fix "Add or remove from list" crashing the page

Closes #1492 and #1493

See merge request soapbox-pub/soapbox!2636
2023-07-31 00:05:55 +00:00
Alex Gleason 79cc3a7d3f
Fix "Add or remove from list" crashing the page
Fixes https://gitlab.com/soapbox-pub/soapbox/-/issues/1493
2023-07-30 18:41:45 -05:00
marcin mikołajczak 40fde3fc2c Merge branch 'fix-account-search' into 'develop'
Use account selector in Search input

See merge request soapbox-pub/soapbox!2634
2023-07-30 14:07:53 +00:00
marcin mikołajczak 9959b148f0 Use account selector in Search input
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-07-30 15:45:15 +02:00
Alex Gleason 4fca1c2393 Merge branch 'ditto-scopes' into 'develop'
Disable privacyScopes on Ditto

See merge request soapbox-pub/soapbox!2633
2023-07-27 15:13:46 +00:00
Alex Gleason b0ee86139c
Disable privacyScopes on Ditto 2023-07-27 09:52:09 -05:00
Alex Gleason 0d5b21ca04 Merge branch 'ditto-trends' into 'develop'
Ditto trends

See merge request soapbox-pub/soapbox!2632
2023-07-26 18:08:18 +00:00
Alex Gleason f9b4a89ead
Hashtag: fix conditional display of "x people talking" 2023-07-25 23:23:33 -05:00
Alex Gleason 497ca73ede
Enable trending tags for Ditto 2023-07-25 16:45:15 -05:00
Alex Gleason 889184caf5 Merge branch 'revert-530329bf' into 'develop'
Revert "Merge branch 'disable-errors-middleware' into 'develop'"

See merge request soapbox-pub/soapbox!2631
2023-07-24 20:30:31 +00:00
Alex Gleason 196d9d5b2b Merge branch 'audio-avatar-fix' into 'develop'
Fix aspect ratio of avatars in audio player

Closes #1345

See merge request soapbox-pub/soapbox!2630
2023-07-24 20:03:11 +00:00
Alex Gleason 878cb40d53 Revert "Merge branch 'disable-errors-middleware' into 'develop'"
This reverts merge request !2614
2023-07-24 20:01:28 +00:00
Alex Gleason c6c7f7eb2f
Fix aspect ratio of avatars in audio player
Fixes https://gitlab.com/soapbox-pub/soapbox/-/issues/1345
2023-07-24 14:50:13 -05:00
marcin mikołajczak 7a79ec9270 Merge branch 'a11y' into 'develop'
Improve focus handlding and focused state styles

See merge request soapbox-pub/soapbox!2628
2023-07-23 18:11:17 +00:00
marcin mikołajczak b5dd668609 Improve focus handlding and focused state styles
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-07-23 19:27:11 +02:00
Alex Gleason 3844086083 Merge branch 'fix-ws-follow' into 'develop'
Fix streaming follow update

Closes #1469

See merge request soapbox-pub/soapbox!2627
2023-07-22 21:57:59 +00:00
Alex Gleason 1addfb96a9
Fix streaming follow update
Fixes https://gitlab.com/soapbox-pub/soapbox/-/issues/1469
2023-07-22 16:38:34 -05:00
Alex Gleason 1883941536 Merge branch 'streaming-hooks' into 'develop'
Add hooks for Streaming API

Closes #1469

See merge request soapbox-pub/soapbox!2626
2023-07-22 20:59:46 +00:00
Alex Gleason 26dfcb728b
yarn i18n 2023-07-22 15:45:02 -05:00
Alex Gleason 85c8f674b4
Streaming: allow connecting if not logged in, gate certain topics 2023-07-22 14:55:21 -05:00
Alex Gleason 53c8858fa6
Add useHashtagStream hook, clean up hashtags timeline (remove unused code for fetching multiple hashtags) 2023-07-22 14:41:50 -05:00
Alex Gleason 4a4a2d1a87
Add useGroupStream hook 2023-07-22 14:06:15 -05:00
Alex Gleason 811a9af670
Add useListStream hook 2023-07-22 14:03:00 -05:00
Alex Gleason 4090d6ab51
Add useDirectStream hook 2023-07-22 14:00:00 -05:00
Alex Gleason 9b1352f0ad
Add useRemoteStream hook 2023-07-22 13:16:01 -05:00
Alex Gleason d99e266008
Add usePublicStream hook 2023-07-22 13:09:45 -05:00
Alex Gleason 3cef200a44
Add useCommunityStream hook, refresh socket when timelineId or path changes 2023-07-22 13:05:41 -05:00
Alex Gleason 757f6600f8
Streaming: remove unused code 2023-07-22 12:53:43 -05:00
Alex Gleason 77f0f4d377
Add Streaming hooks 2023-07-22 12:49:02 -05:00
marcin mikołajczak bea4707743 Merge branch 'calckey' into 'develop'
Rename Calckey to Firefish

See merge request soapbox-pub/soapbox!2624
2023-07-22 07:43:01 +00:00
Alex Gleason eb0dd330bd Merge branch 'changelog' into 'develop'
Update changelog

See merge request soapbox-pub/soapbox!2625
2023-07-21 22:51:51 +00:00
marcin mikołajczak 5e765ead97 Merge branch 'preserve-spoilers' into 'develop'
Add option to preserve spoilers text when replying

See merge request soapbox-pub/soapbox!2609
2023-07-21 22:43:05 +00:00
marcin mikołajczak 8e3dfce337 Update changelog
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-07-22 00:15:11 +02:00
marcin mikołajczak e6dcf3557a Merge branch 'develop' into 'preserve-spoilers'
# Conflicts:
#   app/soapbox/actions/compose.ts
2023-07-21 22:09:37 +00:00
marcin mikołajczak 46313049b0 Rename Calckey to Firefish
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-07-22 00:04:41 +02:00
Alex Gleason e1338dce14 Merge branch 'suggest-hook' into 'develop'
Add useSuggest hook

Closes #1483

See merge request soapbox-pub/soapbox!2623
2023-07-21 18:46:09 +00:00
Alex Gleason 8df3470f87
Fix auth test 2023-07-21 13:11:36 -05:00
Alex Gleason 40af1d91a4
suggest and verify by account IDs, simplify hooks 2023-07-21 12:59:31 -05:00
Alex Gleason d0a97c8c52
Export admin API hooks from an index.ts 2023-07-21 12:49:54 -05:00
Alex Gleason 99e8f6912d
Add useVerify hook 2023-07-21 12:48:47 -05:00
Alex Gleason 31e5f860d9
Add useSuggest hook
https://gitlab.com/soapbox-pub/soapbox/-/issues/1483
2023-07-21 12:36:02 -05:00
Alex Gleason 78436172db Merge branch 'auth-switch-fix' into 'develop'
Fix page crash when switching accounts

See merge request soapbox-pub/soapbox!2622
2023-07-21 02:38:02 +00:00
Alex Gleason 9e59b5d935
Fix page crash when switching accounts 2023-07-20 21:37:33 -05:00
Alex Gleason be788a0f8f Merge branch 'fix-compose-emoji' into 'develop'
Composer: fix emoji dropdown not working

Closes #1480

See merge request soapbox-pub/soapbox!2621
2023-07-21 00:42:20 +00:00
Alex Gleason 6acddfebe7
Composer: fix emoji dropdown not working 2023-07-20 19:41:37 -05:00
Alex Gleason ed9df5e529 Merge branch 'settings-zod' into 'develop'
Add preliminary settings schema

See merge request soapbox-pub/soapbox!2620
2023-07-21 00:05:23 +00:00
Alex Gleason d69d9a34b4
Add preliminary settings schema 2023-07-20 18:38:01 -05:00
Alex Gleason 4c3f3a6bdd Merge branch 'useaccount-memo' into 'develop'
useAccount: memoize the account

See merge request soapbox-pub/soapbox!2617
2023-07-20 21:45:37 +00:00
Alex Gleason 2f0d756562 Merge branch 'rm-accounts-reducer' into 'develop'
Remove legacy accounts reducer

Closes #1442 and #1470

See merge request soapbox-pub/soapbox!2612
2023-07-20 21:45:23 +00:00
Alex Gleason 30eabe047b Merge branch 'renovate/eslint-plugin-jsdoc-46.x' into 'develop'
chore(deps): update dependency eslint-plugin-jsdoc to v46

See merge request soapbox-pub/soapbox!2616
2023-07-20 21:44:16 +00:00
Alex Gleason f99135a354 Merge branch 'renovate/react-motion-0.x' into 'develop'
fix(deps): update dependency @types/react-motion to ^0.0.34

See merge request soapbox-pub/soapbox!2615
2023-07-20 21:43:50 +00:00
Alex Gleason c014b84a2b
Comment out failing feed-carousel test 2023-07-20 16:41:45 -05:00
Alex Gleason 709b985ab0
Remove intermittently failing test 2023-07-20 16:26:54 -05:00
Alex Gleason fb848f1484
useAccount: memoize the account 2023-07-20 16:23:48 -05:00
Soapbox Bot dfb69d0615 chore(deps): update dependency eslint-plugin-jsdoc to v46 2023-07-20 21:05:44 +00:00
Soapbox Bot ff400948a2 fix(deps): update dependency @types/react-motion to ^0.0.34 2023-07-20 21:05:26 +00:00
Alex Gleason 4d49d2f581
Merge remote-tracking branch 'origin/develop' into rm-accounts-reducer 2023-07-20 15:28:12 -05:00
Alex Gleason 530329bf7a Merge branch 'disable-errors-middleware' into 'develop'
Remove errors middleware

See merge request soapbox-pub/soapbox!2614
2023-07-20 20:27:25 +00:00
Alex Gleason a6386a92ed Merge branch 'useentity-error' into 'develop'
useEntity: don't refetch when there's an error

See merge request soapbox-pub/soapbox!2613
2023-07-20 20:26:42 +00:00
Alex Gleason ffa1283509 Merge branch 'rm-storybook' into 'develop'
Remove storybook

See merge request soapbox-pub/soapbox!2611
2023-07-20 20:26:18 +00:00
Alex Gleason e6e946974f
Remove errors middleware 2023-07-20 15:24:24 -05:00
Alex Gleason 6188d44e56
useEntity: don't refetch when there's an error 2023-07-20 15:17:44 -05:00
Alex Gleason 90664dd5c6
Remove legacy accounts reducer 2023-07-20 15:03:23 -05:00
Alex Gleason f2b0f9821f
Remove storybook 2023-07-20 13:52:39 -05:00
marcin mikołajczak f555128d68 Update en.json
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-07-19 00:35:02 +02:00
marcin mikołajczak 74155432cd Add option to preserve spoilers text when replying
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-07-19 00:34:06 +02:00
marcin mikołajczak 7944de8305 Merge branch 'compose-hotkey' into 'develop'
Make Compose hotkey open Compose modal when required

See merge request soapbox-pub/soapbox!2607
2023-07-17 23:35:23 +00:00
marcin mikołajczak d01f86af22 Make Compose hotkey open Compose modal when required
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-07-18 01:08:06 +02:00
Alex Gleason 36083fe1b8 Merge branch 'fix-scheduled-posts' into 'develop'
Fix scheduled posts

Closes #1445

See merge request soapbox-pub/soapbox!2606
2023-07-17 16:13:00 +00:00
Alex Gleason 59ee3b102d
Fix FE_SUBDIRECTORY lint error 2023-07-17 10:55:08 -05:00
Alex Gleason 768b5d9c41 Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2577
2023-07-17 15:22:18 +00:00
PUFF1N ded43c54ab
Translated using Weblate (Turkish)
Currently translated at 99.8% (1591 of 1594 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/tr/
2023-07-17 17:21:43 +02:00
PUFF1N 2321493abd
Translated using Weblate (Turkish)
Currently translated at 99.8% (1591 of 1594 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/tr/
2023-07-17 17:21:43 +02:00
Alexander Minkin 1b75721233
Translated using Weblate (Russian)
Currently translated at 76.0% (1212 of 1594 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ru/
2023-07-17 17:21:43 +02:00
PUFF1N adaa096aea
Translated using Weblate (Turkish)
Currently translated at 95.7% (1527 of 1594 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/tr/
2023-07-17 17:21:43 +02:00
Alexander Minkin 3297b263a7
Translated using Weblate (Russian)
Currently translated at 72.8% (1161 of 1594 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ru/
2023-07-17 17:21:43 +02:00
Hosted Weblate fe40bc47db
Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/
2023-07-17 17:21:43 +02:00
abidin toumi 19fe1748ae
Translated using Weblate (Arabic)
Currently translated at 98.9% (1579 of 1596 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ar/
2023-07-17 17:21:42 +02:00
Poesty Li 5f9b58e2c1
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1596 of 1596 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-07-17 17:21:42 +02:00
Poesty Li ceb83716f3
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1593 of 1593 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-07-17 17:21:42 +02:00
Alex Gleason 04659a74a4 Merge branch 'truncate-bio' into 'develop'
ProfileInfoPanel: truncate bio

Closes #1456

See merge request soapbox-pub/soapbox!2598
2023-07-17 15:21:34 +00:00
Alex Gleason 6b8be7af3c
Fix scheduled posts
Fixes https://gitlab.com/soapbox-pub/soapbox/-/issues/1445
2023-07-17 10:19:27 -05:00
Alex Gleason 77cf9e9d1e Merge branch 'fix-issue-1472' into 'develop'
Update Webpack configuration to fix builds on Windows.

Closes #1472

See merge request soapbox-pub/soapbox!2605
2023-07-16 15:23:25 +00:00
Elaine Jackson 155012b332 Move changes to shared.ts 2023-07-16 15:21:41 +00:00
Elaine Jackson 2546c986a6 Update publicPath output to either use environment variable provided by developer building or default to '/' to avoid broken builds on Windows. 2023-07-16 15:14:28 +00:00
Alex Gleason b4791144f2 Merge branch 'account-url' into 'develop'
Actually, account.url is not optional

See merge request soapbox-pub/soapbox!2604
2023-07-16 02:37:43 +00:00
Alex Gleason f456cb4086
Fix account.url tests 2023-07-15 21:07:48 -05:00
Alex Gleason 06b1688130
Actually, account.url is not optional 2023-07-15 19:47:59 -05:00
Alex Gleason 2dfad76cdd Merge branch 'ff-skipalert' into 'develop'
FAMILIAR_FOLLOWERS_FETCH_FAIL: skipAlert: true

See merge request soapbox-pub/soapbox!2603
2023-07-14 00:21:34 +00:00
Alex Gleason f3fbc5055f
FAMILIAR_FOLLOWERS_FETCH_FAIL: skipAlert: true 2023-07-13 19:20:27 -05:00
marcin mikołajczak fe08f06e5e Merge branch 'avatar-stack' into 'develop'
Add AvatarStack component

See merge request soapbox-pub/soapbox!2602
2023-07-10 12:57:24 +00:00
marcin mikołajczak 13cd0b726e Add AvatarStack component
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-07-10 12:43:18 +02:00
marcin mikołajczak 0ba4a63106 Merge branch 'familiar-followers' into 'develop'
Fix features.ts

See merge request soapbox-pub/soapbox!2601
2023-07-10 08:49:21 +00:00
marcin mikołajczak becb80611a Fix features.ts
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-07-10 10:24:48 +02:00
marcin mikołajczak e616045f60 Merge branch 'mkljczk-develop-patch-54530' into 'develop'
Enable familiar followers on Rebased

See merge request soapbox-pub/soapbox!2600
2023-07-10 07:24:10 +00:00
marcin mikołajczak 34acc019f7 Enable familiar followers on Rebased 2023-07-10 06:51:20 +00:00
marcin mikołajczak 84d7ce1b67 Merge branch 'calckey' into 'develop'
Support Calckey, maybe

See merge request soapbox-pub/soapbox!2599
2023-07-09 20:06:58 +00:00
marcin mikołajczak 07a8df4b61 Support Calckey, maybe
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-07-09 19:54:44 +02:00
Alex Gleason 23247802b3 Merge branch 'fix-username-lookup-case' into 'develop'
useAccountLookup, useGroupLookup: make lookup case insensitive

Closes #1460

See merge request soapbox-pub/soapbox!2597
2023-07-06 17:33:56 +00:00
Alex Gleason 8da8f18a45
ProfileInfoPanel: truncate bio
Fixes https://gitlab.com/soapbox-pub/soapbox/-/issues/1456
2023-07-06 12:21:52 -05:00
Alex Gleason 0e58f2b505
useAccountLookup, useGroupLookup: make lookup case insensitive
Fixes https://gitlab.com/soapbox-pub/soapbox/-/issues/1460
2023-07-06 11:56:27 -05:00
Alex Gleason c73cf80d26 Merge branch 'redirect-unauth' into 'develop'
Redirect to login when groups or accounts 403

See merge request soapbox-pub/soapbox!2583
2023-07-06 16:41:06 +00:00
Alex Gleason 39eb76bc18
Fix useGroupLookup test 2023-07-06 11:14:34 -05:00
Alex Gleason 6f83b7748e
Merge remote-tracking branch 'origin/develop' into redirect-unauth 2023-07-06 11:10:34 -05:00
marcin mikołajczak 0aecc2fb57 Merge branch 'edit-profile-pickers' into 'develop'
Fix HeaderPicker/AvatarPicker for missing images

See merge request soapbox-pub/soapbox!2596
2023-07-06 13:58:43 +00:00
marcin mikołajczak 7c38f751f2 Fix HeaderPicker/AvatarPicker for missing images
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-07-06 13:22:15 +02:00
marcin mikołajczak 542924fab0 Merge branch 'edit-profile-pickers' into 'develop'
Use AvatarPicker/HeaderPicker on Edit Profile page

See merge request soapbox-pub/soapbox!2594
2023-07-06 06:23:19 +00:00
marcin mikołajczak da42586ca5 Update en.json
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-07-05 21:49:56 +02:00
marcin mikołajczak a9db41de89 Use AvatarPicker/HeaderPicker on Edit Profile page
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-07-05 21:39:50 +02:00
marcin mikołajczak aca9c51924 Merge branch 'media-modal-focus-status' into 'develop'
Focus the correct status in media modal

See merge request soapbox-pub/soapbox!2592
2023-07-03 20:33:02 +00:00
marcin mikołajczak 72de8fb90f Merge branch 'hotkeys-statuses' into 'develop'
Move GlobalHotkeys back to features/ui for now

See merge request soapbox-pub/soapbox!2593
2023-07-03 12:32:07 +00:00
marcin mikołajczak bf6bf879a0 Move GlobalHotkeys back to features/ui for now
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-07-03 13:53:41 +02:00
marcin mikołajczak 55b1f9be67 Focus the correct status in media modal
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-07-03 13:39:11 +02:00
marcin mikołajczak 42e9d31a3e Merge branch 'hotkeys-statuses' into 'develop'
Fix hotkey navigation in media modal

See merge request soapbox-pub/soapbox!2589
2023-07-02 21:27:10 +00:00
marcin mikołajczak 6337a321d5 Merge branch 'chats-date-year' into 'develop'
Show year for older chat messages

See merge request soapbox-pub/soapbox!2591
2023-07-02 21:01:37 +00:00
marcin mikołajczak 32c8a94267 Move Hotkeys to a new component
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-07-02 22:39:10 +02:00
marcin mikołajczak 702d8a843e Show year for older chat messages
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-07-02 22:30:23 +02:00
Alex Gleason 362639759e Merge branch 'fix-0' into 'develop'
Fix "0" in place of ProfileFieldsPanel when no fields are set

Closes #1453

See merge request soapbox-pub/soapbox!2590
2023-07-02 19:03:29 +00:00
Alex Gleason bd4ae72248
Fix "0" in place of ProfileFieldsPanel when no fields are set
Fixes https://gitlab.com/soapbox-pub/soapbox/-/issues/1453
2023-07-02 14:02:26 -05:00
marcin mikołajczak b0bdb78543 Fix hotkey navigation in media modal
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-07-02 18:41:39 +02:00
marcin mikołajczak acdc781bc2 Merge branch 'follow-hashtags' into 'develop'
Add Followed hashtags page

See merge request soapbox-pub/soapbox!2588
2023-07-02 11:54:48 +00:00
marcin mikołajczak 8646aa5572 Add Followed hashtags page
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-07-02 13:54:02 +02:00
marcin mikołajczak 174be975c8 Support Mastodon nightly version
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-07-02 13:18:52 +02:00
Alex Gleason b1a775c2a9 Merge branch 'fix-profile-fields-panel' into 'develop'
Fix profile fields panel from not showing up

See merge request soapbox-pub/soapbox!2586
2023-07-02 04:14:59 +00:00
Alex Gleason 6f99396bc4
Fix profile fields panel from not showing up 2023-07-01 23:14:27 -05:00
Alex Gleason bdf81b1d39 Merge branch 'fix-edit-profile' into 'develop'
Fix edit profile

Closes #1451

See merge request soapbox-pub/soapbox!2585
2023-06-30 17:18:41 +00:00
Alex Gleason b8c42c9371
Fix edit profile
Fixes https://gitlab.com/soapbox-pub/soapbox/-/issues/1451
2023-06-30 11:52:37 -05:00
Alex Gleason f7e82e2fc1 Merge branch 'fix-mentions' into 'develop'
Fix mentions

Closes #1449

See merge request soapbox-pub/soapbox!2584
2023-06-30 15:13:55 +00:00
Alex Gleason 6326eeb083
Fix mentions 2023-06-30 09:45:11 -05:00
Alex Gleason bcac58b9c3
Redirect to login when groups or accounts 403 2023-06-29 15:10:45 -05:00
Alex Gleason 5ffaaa4c3a Merge branch 'compose-safe' into 'develop'
Make Compose reducer type-safe

See merge request soapbox-pub/soapbox!2581
2023-06-29 17:12:32 +00:00
Chewbacca 05efc9f30e Merge branch 'refactor-group-queries' into 'develop'
Refactor group queries

See merge request soapbox-pub/soapbox!2579
2023-06-29 15:06:03 +00:00
Chewbacca 241ef58e88 Add account check 2023-06-29 10:49:37 -04:00
Chewbacca cadff9b4ab Add test for 'usePendingGroups' 2023-06-29 10:40:15 -04:00
Chewbacca 5eef027ed0 Use new api hook for 'useGroup' 2023-06-29 10:40:15 -04:00
Chewbacca 6f2e0749b6 Refactor 'usePendingGroups' into new api hooks 2023-06-29 10:40:15 -04:00
Alex Gleason 32990fa77b
Merge remote-tracking branch 'origin/develop' into compose-safe 2023-06-28 22:29:39 -05:00
Alex Gleason 11f100da51 Merge branch 'get-account-perf' into 'develop'
Fix performance issue with makeGetAccount

See merge request soapbox-pub/soapbox!2582
2023-06-29 03:12:36 +00:00
Alex Gleason 3ffc5e054d
Fix performance issue with makeGetAccount 2023-06-28 21:42:56 -05:00
Alex Gleason a336fa2137 Merge branch 'status-get' into 'develop'
status.get('x') --> status.x

See merge request soapbox-pub/soapbox!2580
2023-06-28 22:53:50 +00:00
Alex Gleason de0b05d691
Make Compose reducer type-safe 2023-06-28 17:53:17 -05:00
Alex Gleason 118cbd5994
status.get('x') --> status.x 2023-06-28 16:27:25 -05:00
Alex Gleason 0c83f840fb Merge branch 'fix-follow-relationship' into 'develop'
Fix follow notifications not having relationship

Closes #1446

See merge request soapbox-pub/soapbox!2578
2023-06-28 14:56:09 +00:00
Alex Gleason c4931d5f6f
Fix follow notifications not having relationship 2023-06-28 09:30:44 -05:00
Alex Gleason a6a1ed9576 Merge branch 'fix-instance-favicons' into 'develop'
Fix instance favicons

Closes #1447

See merge request soapbox-pub/soapbox!2576
2023-06-28 01:50:10 +00:00
Alex Gleason fcae0df1f8
Fix instance favicons
Fixes https://gitlab.com/soapbox-pub/soapbox/-/issues/1447
2023-06-27 20:21:50 -05:00
Alex Gleason 14ad6e6fb2 Merge branch 'oakes/own-account-familiar-followers' into 'develop'
Don't show familiar followers for own account

See merge request soapbox-pub/soapbox!2575
2023-06-27 20:38:49 +00:00
oakes 2cae474547 Don't show familiar followers for own account 2023-06-27 16:05:39 -04:00
Chewbacca e60a4b5be0 Merge branch 'group-mutes' into 'develop'
Support Group Muting

See merge request soapbox-pub/soapbox!2552
2023-06-27 19:14:11 +00:00
Alex Gleason 9eff8d1e9c Merge branch 'oakes/import-relationships' into 'develop'
Import relationships and fix familiar followers dialog

See merge request soapbox-pub/soapbox!2574
2023-06-27 18:54:45 +00:00
oakes 881e8662af Make fetchRelationships import the data into Entities.RELATIONSHIPS 2023-06-27 13:43:57 -04:00
oakes 985022f857 Fetch relationships after getting familiar followers 2023-06-27 13:42:33 -04:00
oakes ecdbee271b Fix how familiar followers dialog is rendered 2023-06-27 13:41:05 -04:00
Alex Gleason 5883e43711 Merge branch 'default-display-name' into 'develop'
Show username when no display name is set

See merge request soapbox-pub/soapbox!2573
2023-06-27 16:22:02 +00:00
oakes b8a3083e4d Show username when no display name is set 2023-06-27 12:11:44 -04:00
Chewbacca f981eaa27e Fix type 2023-06-27 09:34:00 -04:00
Chewbacca 9e27cb06cb Ban User from status action bar 2023-06-27 09:24:29 -04:00
Chewbacca e3fa58c0da Support Group mutes 2023-06-27 09:24:03 -04:00
Alex Gleason e58dada03a Merge branch 'modal-scrollable-list' into 'develop'
Fix scrollable list in modals and add pagination

See merge request soapbox-pub/soapbox!2570
2023-06-27 02:52:11 +00:00
Alex Gleason 4c99889812 Merge branch 'group-hooks' into 'develop'
Group entity store updates

See merge request soapbox-pub/soapbox!2571
2023-06-26 18:31:40 +00:00
Alex Gleason 64df93f5a0
Fix status test 2023-06-26 12:41:42 -05:00
Alex Gleason a8792f9a02
StatusActionBar: use GroupRelationship from entity store 2023-06-26 12:12:34 -05:00
Alex Gleason e07412f872
Remove getIn calls in status and status-action-bar components 2023-06-26 11:59:01 -05:00
Alex Gleason 98cfb6fae5
Don't let status.group be a string 2023-06-26 11:50:53 -05:00
Alex Gleason cb4477185c
Update usages of useGroupRelationships hook 2023-06-26 11:25:03 -05:00
Alex Gleason 242c6026d5
Make account hooks DRY with useAccountList 2023-06-26 11:22:02 -05:00
Alex Gleason df4975c688
Remove unused makeGetGroup 2023-06-26 11:09:44 -05:00
Alex Gleason a375159444
useGroupRelationships: switch to useBatchedEntities 2023-06-26 11:05:03 -05:00
Alex Gleason a4cc48dce6 Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2504
2023-06-26 13:27:15 +00:00
Tassoman a7e85650bf
Translated using Weblate (Italian)
Currently translated at 99.6% (1574 of 1580 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/it/
2023-06-26 06:25:19 +02:00
abidin toumi 0e95e124cc
Translated using Weblate (Arabic)
Currently translated at 99.8% (1577 of 1580 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ar/
2023-06-26 06:25:19 +02:00
marcin mikołajczak ce32608de4
Translated using Weblate (Polish)
Currently translated at 95.5% (1510 of 1580 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/pl/
2023-06-26 06:25:19 +02:00
jonnysemon 4b2e74905d
Translated using Weblate (Arabic)
Currently translated at 99.5% (1573 of 1580 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ar/
2023-06-26 06:25:19 +02:00
Poesty Li f332111a28
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1580 of 1580 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-06-26 06:25:18 +02:00
Poesty Li 28907ca9b8
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1577 of 1577 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-06-26 06:25:18 +02:00
marcin mikołajczak d16a56420e
Translated using Weblate (Polish)
Currently translated at 95.9% (1513 of 1577 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/pl/
2023-06-26 06:25:18 +02:00
Milo Ivir 0caa92f022
Translated using Weblate (Croatian)
Currently translated at 83.8% (1320 of 1575 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/hr/
2023-06-26 06:25:18 +02:00
Poesty Li 6e71a3e7aa
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1575 of 1575 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-06-26 06:25:18 +02:00
marcin mikołajczak fcfb87ec4c
Translated using Weblate (Polish)
Currently translated at 85.2% (1340 of 1572 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/pl/
2023-06-26 06:25:18 +02:00
Poesty Li 53f062a90e
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1572 of 1572 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-06-26 06:25:18 +02:00
Ahmad Dakhlallah a9882a2daf
Translated using Weblate (Arabic)
Currently translated at 99.4% (1561 of 1570 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ar/
2023-06-26 06:25:18 +02:00
Poesty Li 534f6c51bb
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1570 of 1570 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-06-26 06:25:18 +02:00
Hosted Weblate 3f0ae45f8d
Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/
2023-06-26 06:25:18 +02:00
Hosted Weblate ddc98fe804
Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/
2023-06-26 06:25:18 +02:00
jonnysemon e1f9832c44
Translated using Weblate (Arabic)
Currently translated at 96.5% (1522 of 1576 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ar/
2023-06-26 06:25:18 +02:00
Alex Gleason 4f7512c782 Merge branch 'change-entity' into 'develop'
Add changeEntity hook, useFollow, remove accounts_counters reducer

See merge request soapbox-pub/soapbox!2568
2023-06-26 00:55:29 +00:00
oakes 03d5be2c5a Add pagination to reblogged_by dialog 2023-06-25 18:50:01 -04:00
Alex Gleason 6f7bb54b19
Add useBlocks hook, switch over blocks and mutes to hooks 2023-06-25 17:48:19 -05:00
oakes 500ac3eefe Add pagination to favourited_by dialog 2023-06-25 18:44:20 -04:00
Alex Gleason 468f763299
Favourites small refactoring 2023-06-25 17:27:02 -05:00
Alex Gleason 45493880cd
Export useFollowing hook 2023-06-25 16:22:47 -05:00
Alex Gleason 9c9c790a5f
Update followers/following pages 2023-06-25 16:21:27 -05:00
Alex Gleason bfe6ab3c26
Fix useRelationships hook 2023-06-25 16:11:00 -05:00
Alex Gleason 989d99f908
Add useBatchedEntities hook for relationships 2023-06-25 15:57:38 -05:00
Alex Gleason a5e213eca0
Restore Patron reducer for now 2023-06-25 12:37:37 -05:00
Alex Gleason d4eaf1e27a
Make useOwnAccount return an object 2023-06-25 12:35:09 -05:00
Alex Gleason a8459ced75
Remove Patron reducer 2023-06-25 12:27:26 -05:00
Alex Gleason f46374fdac
Simplify makeGetAccount further 2023-06-25 12:26:48 -05:00
Alex Gleason 8955a56c27
Delete findAccountByUsername selector 2023-06-25 12:24:21 -05:00
Alex Gleason 5320f04e6e
Fetch relationship from profile page 2023-06-25 12:04:30 -05:00
Alex Gleason 072014e39e
Add useRelationship hook, disable fetching relationship for account by default 2023-06-25 12:01:34 -05:00
oakes b96828ad23 Fix scrollable list in modals 2023-06-24 18:47:16 -04:00
Alex Gleason ec8177d578
Add useAccountLookup hook, fix useRelationships 2023-06-23 21:41:36 -05:00
marcin mikołajczak 2ee47fd9a8 Merge branch 'moderation-hide-actions' into 'develop'
Add hideActions to moderation confirmation modals

See merge request soapbox-pub/soapbox!2569
2023-06-23 22:11:00 +00:00
marcin mikołajczak 29c20e6361 Add hideActions to moderation confirmation modals
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-06-23 23:11:50 +02:00
Alex Gleason 9f53a81fa1
Add useTransaction hook 2023-06-23 14:12:12 -05:00
Alex Gleason 2657c8f946
Simplify getAccountGallery selector, also fix getGroupGallery 2023-06-23 11:45:12 -05:00
Alex Gleason 1f653b1065
Gate Nostr signing to Ditto 2023-06-23 11:44:07 -05:00
Alex Gleason 448f5c6ab9
Fix media gallery being broken 2023-06-23 11:41:10 -05:00
Alex Gleason 65f8299c1f
EntityStore: change error type from any to unknown 2023-06-23 11:35:16 -05:00
Alex Gleason ab5c4a4233
Fix useRelationships getting called while logged out 2023-06-23 11:30:10 -05:00
Alex Gleason 7bfde28b0c
useFollow: don't go below 0 2023-06-22 23:47:46 -05:00
Alex Gleason 75dbeb65b6
Remove account_counters reducer and legacy follow actions 2023-06-22 23:38:50 -05:00
Alex Gleason ad1718b5f9
Add useFollow, useChangeEntity hooks 2023-06-22 23:17:40 -05:00
Alex Gleason cff5f96df4 Merge branch 'accounts-hook' into 'develop'
Switch to useAccount hook in every place it's convenient

See merge request soapbox-pub/soapbox!2566
2023-06-21 22:47:03 +00:00
Alex Gleason 88692b7020
Fix Patron badge in profile info panel 2023-06-21 17:13:29 -05:00
Alex Gleason 3a369f21fa
Switch to useAccount hook in more places 2023-06-21 16:51:08 -05:00
Alex Gleason 5f61a624c6
Remove legacy useAccount hook 2023-06-21 16:28:51 -05:00
Alex Gleason 69d8817b6d
SidebarMenu: useAccount hook 2023-06-21 16:25:35 -05:00
Alex Gleason e01ee84ee9
ProfileHoverCard: use useAccount hook, add usePatronUser hook 2023-06-21 16:20:07 -05:00
Alex Gleason 25d3925b76 Merge branch 'zod-accounts' into 'develop'
Create legacy immutable adapter for accounts reducer

See merge request soapbox-pub/soapbox!2563
2023-06-21 16:39:14 +00:00
Alex Gleason c2c94d0577
Fix crash on aliases page 2023-06-21 11:19:09 -05:00
Alex Gleason 4fc6640c2c
Skip broken tests 2023-06-20 21:44:07 -05:00
Alex Gleason ced600657b
Fix auth test 2023-06-20 21:36:25 -05:00
Alex Gleason 256d7825ee
Fix timelines test 2023-06-20 21:17:57 -05:00
Alex Gleason 7e83039999
Improve reducer type 2023-06-20 21:09:49 -05:00
Alex Gleason ade9fa007d Merge branch 'remove-follow-suggestion' into 'develop'
Fix follow suggestion removal

See merge request soapbox-pub/soapbox!2565
2023-06-21 00:56:14 +00:00
oakes fdd20981e3 Fix field name so follow suggestion is successfully removed 2023-06-20 20:25:15 -04:00
Alex Gleason c4ad5e5d78
Fix tests that set the store wrong 2023-06-20 17:48:57 -05:00
Alex Gleason e7217c5c58
Fix reducer in a way that works in tests 2023-06-20 17:33:20 -05:00
Alex Gleason eb0c499d91
factory: generate account on status if not provided 2023-06-20 16:57:40 -05:00
Alex Gleason 3000f94325
Fix account relationships 2023-06-20 16:02:43 -05:00
Alex Gleason 4258d4b27f
Fix reducer and selector, import accounts into entity store 2023-06-20 15:24:35 -05:00
Alex Gleason 412fe84d13
FIX THE TYPE ERRORS 2023-06-20 14:24:39 -05:00
Alex Gleason 011f2eb298
Merge remote-tracking branch 'origin/develop' into zod-accounts 2023-06-19 20:10:25 -05:00
Alex Gleason 5d515f0f21 Merge branch 'pick-utils' into 'develop'
utils: pick only needed fields

See merge request soapbox-pub/soapbox!2564
2023-06-19 22:47:31 +00:00
Alex Gleason 2796726cad
utils: pick only needed fields 2023-06-19 16:49:42 -05:00
Alex Gleason 89c9e32b59
Move legacy functions into separate utils file 2023-06-19 16:02:51 -05:00
Alex Gleason e789b44792
Improve legacy store types 2023-06-19 13:09:51 -05:00
Alex Gleason 8a4239d153
utils/accounts: pick only needed fields from type 2023-06-19 12:10:29 -05:00
Alex Gleason 060a9b559d
Make accounts reducer an alias to entity store with immutableish methods 2023-06-19 12:07:58 -05:00
Alex Gleason 0cebcc05a5
Use `any` keys, fixes most errors! 2023-06-19 10:58:07 -05:00
Chewbacca d5b3853afc Merge branch 'add-suggested-groups-to-search' into 'develop'
Add Suggested Groups panel to Search page

See merge request soapbox-pub/soapbox!2560
2023-06-19 12:17:34 +00:00
Chewbacca 5c41209a67 Merge branch 'fetch-group-data-timeline' into 'develop'
Fetch group relationships from timeline

See merge request soapbox-pub/soapbox!2549
2023-06-19 12:02:40 +00:00
Chewbacca 203b1222f5 Merge branch 'load-group-data' into 'develop'
Fetch group relationship from notifications

See merge request soapbox-pub/soapbox!2540
2023-06-19 12:02:31 +00:00
Alex Gleason a54b6ee8a3
Create legacy immutable adapter for accounts reducer 2023-06-18 20:10:17 -05:00
Alex Gleason 138ded3904 Merge branch 'link-header' into 'develop'
Use Link header for pagination in more places

See merge request soapbox-pub/soapbox!2562
2023-06-17 12:58:59 +00:00
Chewbacca ee76ec9bf4 Merge branch 'add-group-to-thumb-navigation' into 'develop'
Add Groups to Thumb Navigation

See merge request soapbox-pub/soapbox!2559
2023-06-16 12:51:26 +00:00
oakes e1cacb6ee4 Optionally use Link header for pagination in various timelines 2023-06-15 21:40:32 -04:00
oakes a985348bf1 Optionally use Link header for search pagination 2023-06-15 21:40:28 -04:00
Alex Gleason dadc39f731 Merge branch 'schema-improvements' into 'develop'
Improve schemas for Account, EmojiReaction, Location, and Status

See merge request soapbox-pub/soapbox!2555
2023-06-14 14:40:59 +00:00
Chewbacca 1d9130f7ac Add Suggested Groups panel to Search page 2023-06-14 08:11:39 -04:00
Chewbacca e3f92eadac Add Groups to Thumb Navigation 2023-06-14 08:05:25 -04:00
Alex Gleason bfaea4c356 Merge branch 'browserslist' into 'develop'
npx browserslist@latest --update-db

See merge request soapbox-pub/soapbox!2558
2023-06-14 03:16:36 +00:00
Alex Gleason 590ab73b99
npx browserslist@latest --update-db 2023-06-13 22:14:28 -05:00
Alex Gleason 60eaf01940
Add Resolve<T> utility type 2023-06-13 22:12:42 -05:00
Alex Gleason db070150d9
Remove unnecessary `as string` 2023-06-13 20:59:38 -05:00
Alex Gleason 405dcef4a5
Merge remote-tracking branch 'origin/develop' into schema-improvements 2023-06-13 20:58:49 -05:00
Alex Gleason 85261fc415 Merge branch 'typescript-5' into 'develop'
Upgrade to TypeScript 5.1

See merge request soapbox-pub/soapbox!2556
2023-06-14 01:58:25 +00:00
Alex Gleason 0b439b79a1
Upgrade to TypeScript 5.1 2023-06-13 16:26:30 -05:00
Alex Gleason 263db3e1f0
Improve schemas for Account, EmojiReaction, Location, and Status 2023-06-13 14:33:19 -05:00
Chewbacca ae75c9ac0d Merge branch 'group-admin-fix' into 'develop'
Allow admins to delete Group statuses

See merge request soapbox-pub/soapbox!2533
2023-06-12 12:05:59 +00:00
Chewbacca f70b7a690d Merge branch 'group-pins' into 'group-admin-fix'
Support Group Pins

See merge request soapbox-pub/soapbox!2544
2023-06-12 12:05:52 +00:00
Alex Gleason 82ff60efaa Merge branch 'auth-fix' into 'develop'
Don't call verify_credentials twice when an account fails

See merge request soapbox-pub/soapbox!2553
2023-06-10 19:39:46 +00:00
Alex Gleason 8d8e4f2ee8
Don't call verify_credentials twice when an account fails 2023-06-10 14:19:46 -05:00
Alex Gleason f2f720ca21 Merge branch 'invisible-css' into 'develop'
Move .invisible styles to Markup CSS

See merge request soapbox-pub/soapbox!2550
2023-06-07 17:03:30 +00:00
Alex Gleason a2846070c9
Move .invisible styles to Markup CSS 2023-06-07 11:35:41 -05:00
Chewbacca c82ece5a19 Fetch group relationship from timeline 2023-06-06 09:19:11 -04:00
Chewbacca 0a66a565f6 Merge branch 'improve-emoji-search' into 'develop'
Improve emoji search

See merge request soapbox-pub/soapbox!2548
2023-06-05 18:37:11 +00:00
Chewbacca c5ec755661 Remove log 2023-06-05 14:21:04 -04:00
Chewbacca 476ae0a68d Fix emoji search test 2023-06-05 13:17:48 -04:00
Chewbacca 1fed96e99e Sort the emojis 2023-06-05 12:39:32 -04:00
Chewbacca 27f831dce9 Improve emoji search 2023-06-05 12:19:59 -04:00
Chewbacca 1a55d926cb Merge branch 'fix-nav-bug' into 'develop'
Fix navigation bug on Group profiles

See merge request soapbox-pub/soapbox!2547
2023-06-05 15:35:43 +00:00
Chewbacca f1f6373cd7 Merge branch 'redirect' into 'develop'
Add redirect from statuses -> posts

See merge request soapbox-pub/soapbox!2546
2023-06-05 15:18:29 +00:00
Chewbacca 74e04350c5 Merge branch 'fix-typo' into 'develop'
Fix typo

See merge request soapbox-pub/soapbox!2545
2023-06-05 15:18:21 +00:00
Chewbacca 53a012d9bb Fix navigation bug on Group profiles 2023-06-05 11:11:57 -04:00
Chewbacca f718ca6d90 Add redirect from statuses -> posts 2023-06-05 10:41:21 -04:00
Chewbacca cae9d9158d Fix typo 2023-06-05 10:25:48 -04:00
Chewbacca 35d9348edd Support Group pins 2023-06-05 09:41:36 -04:00
Chewbacca 45e0726e59 Alphabetize messages 2023-06-05 09:41:36 -04:00
Chewbacca d75920718f Fix group factory 2023-06-05 09:41:28 -04:00
Chewbacca 60875e5dc2 Add 'owner' to Group fixture 2023-06-05 09:41:28 -04:00
Chewbacca 6cd8e50493 Allow admins to delete Group statuses 2023-06-05 09:41:28 -04:00
marcin mikołajczak 73eedea362 Merge branch 'i18n' into 'develop'
Minor strings improvements

See merge request soapbox-pub/soapbox!2542
2023-06-04 19:04:34 +00:00
marcin mikołajczak 2f3311a352 Minor strings improvements
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-06-04 20:21:22 +02:00
marcin mikołajczak 87678c77b4 Merge branch 'media-modal-navigation-hidden' into 'develop'
Media modal: Restore navigationHidden functionality

Closes #1436

See merge request soapbox-pub/soapbox!2543
2023-06-03 19:24:32 +00:00
marcin mikołajczak c80633fd9f Media modal: Restore navigationHidden functionality
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-06-03 20:55:04 +02:00
marcin mikołajczak ea298472a8 Merge branch 'dropdown-menu-improvements' into 'develop'
Dropdown menu improvements and fixes

See merge request soapbox-pub/soapbox!2541
2023-06-02 20:42:34 +00:00
marcin mikołajczak a2a1bab517 Dropdown menu improvements
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-06-02 21:40:32 +02:00
Chewbacca 8fa9854016 Merge branch 'fix-useless-call' into 'develop'
Prevent lookup if not enabled

See merge request soapbox-pub/soapbox!2539
2023-06-02 14:56:56 +00:00
Chewbacca 170743d448 Fetch group relationship from notifications 2023-06-02 10:41:07 -04:00
Chewbacca 8de2619ad1 Merge branch 'dark-mode-fixes' into 'develop'
Dark mode improvements

See merge request soapbox-pub/soapbox!2537
2023-06-02 14:28:36 +00:00
Chewbacca 53988e2581 Prevent lookup if not enabled 2023-06-02 10:28:10 -04:00
Alex Gleason 14aafa2526 Merge branch 'media-modal-fixes' into 'develop'
MediaModal: make clicking the background close the modal

Closes #1434

See merge request soapbox-pub/soapbox!2538
2023-06-01 23:46:32 +00:00
Alex Gleason 0d8317145d
MediaModal: make clicking the background close the modal
Fixes https://gitlab.com/soapbox-pub/soapbox/-/issues/1434
2023-06-01 12:55:58 -05:00
Alex Gleason 87b279d8ee
MediaModal: hide fullscreen button on mobile 2023-06-01 11:49:36 -05:00
Chewbacca 92f824bb2d Fix dark border color on Tombstones 2023-06-01 12:47:51 -04:00
Chewbacca e62f292aa8 Use dark-mode badges for Group members 2023-06-01 12:44:11 -04:00
Chewbacca b45d1ea7fa Fix dark border color 2023-06-01 12:41:23 -04:00
marcin mikołajczak 27a5c533b5 Merge branch 'search-persist-fix' into 'develop'
Fix shouldPersistSearch for Pleroma flake ids

See merge request soapbox-pub/soapbox!2535
2023-06-01 06:47:46 +00:00
Alex Gleason d50a62791a Merge branch 'media-modal-fixes' into 'develop'
Media modal fixes

Closes #1431 and #1432

See merge request soapbox-pub/soapbox!2536
2023-06-01 01:26:39 +00:00
Alex Gleason 8731bcee3e
Thread: remove border-radius 2023-05-31 20:04:34 -05:00
Alex Gleason aca4322526
MediaModal: support not having a status 2023-05-31 20:01:30 -05:00
marcin mikołajczak 99e262ab8a Fix shouldPersistSearch for Pleroma flake ids
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-05-31 20:34:08 +02:00
Chewbacca 0c499b43ff Merge branch 'media-viewer' into 'develop'
Media Viewer

See merge request soapbox-pub/soapbox!2532
2023-05-31 15:36:05 +00:00
Chewbacca 88630e7cf7 Add changelog entry 2023-05-31 11:23:28 -04:00
Chewbacca a136deb13e Update i18n 2023-05-31 09:22:03 -04:00
Chewbacca 5ff9c1c6ec Fix tests 2023-05-31 08:54:54 -04:00
Chewbacca 866c80d30b Improve the MediaModal with ability to like, comment, reply, etc 2023-05-31 08:50:03 -04:00
Chewbacca 3c00820382 Add 0 to HStack spacing 2023-05-31 08:44:45 -04:00
Chewbacca d8f698242a Add justify-between to Stack options 2023-05-31 08:44:45 -04:00
Chewbacca 602eaf1ec1 Use AppDispatch 2023-05-31 08:44:45 -04:00
Chewbacca cbf4878f7f Add 'shift' middleware to DropdownMenu 2023-05-31 08:44:45 -04:00
marcin mikołajczak d875be4465 Merge branch 'fix-search-expand' into 'develop'
Fix search expand when searching user' posts

See merge request soapbox-pub/soapbox!2534
2023-05-31 09:06:42 +00:00
marcin mikołajczak 2829a0097a Fix search expand when searching user' posts
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-05-31 10:45:33 +02:00
Chewbacca 02479efc35 Merge branch 'group-improvements' into 'develop'
Group improvements

See merge request soapbox-pub/soapbox!2525
2023-05-30 13:12:21 +00:00
Alex Gleason 4a29fcce02 Merge branch 'rm-greentext' into 'develop'
Remove greentext support

See merge request soapbox-pub/soapbox!2531
2023-05-28 20:24:36 +00:00
Alex Gleason d14cad38af
Fix soapbox config page crash 2023-05-28 14:53:23 -05:00
Alex Gleason 27ba796852
Remove greentext support
It uses Pleroma FE's vulnerable HTML parser
2023-05-28 14:45:22 -05:00
marcin mikołajczak 027c25d446 Merge branch 'fix-open-media-hotkey' into 'develop'
Fix open media hotkey

See merge request soapbox-pub/soapbox!2530
2023-05-26 23:26:56 +00:00
marcin mikołajczak 5f1bbfb194 Fix open media hotkey
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-05-27 01:12:20 +02:00
marcin mikołajczak 0a397c1cfe Merge branch 'mfa-form-page' into 'develop'
Proper spacing on MFA page

See merge request soapbox-pub/soapbox!2519
2023-05-23 16:57:45 +00:00
Chewbacca c8ff9db879 Truncate group name in panels 2023-05-23 12:32:55 -04:00
Chewbacca 5c069b8b93 Make # members clickable to Group Members page 2023-05-23 12:32:44 -04:00
Alex Gleason 917b45bdc5 Merge branch 'status-schema' into 'develop'
Status schema improvements

See merge request soapbox-pub/soapbox!2521
2023-05-23 14:22:44 +00:00
Chewbacca d18bc015f7 Merge branch 'add-group-context-to-reply-modal' into 'develop'
Add group context to reply modal

See merge request soapbox-pub/soapbox!2524
2023-05-23 14:08:22 +00:00
Chewbacca 092dee0592 Merge branch 'group-fixes' into 'develop'
Multiple Group improvements

See merge request soapbox-pub/soapbox!2523
2023-05-23 13:39:57 +00:00
Chewbacca d564728117 Add Group context to reply modal 2023-05-23 09:39:37 -04:00
Chewbacca 5d1f168325 Enable groups 2023-05-23 09:39:17 -04:00
Chewbacca cb6b688efe Normalize 'group_mention' notification into 'mention' 2023-05-23 08:57:36 -04:00
Alex Gleason 7aec21d694 Merge branch 'quote-tombstone' into 'develop'
Support quoted tombstone

See merge request soapbox-pub/soapbox!2522
2023-05-22 19:59:39 +00:00
Alex Gleason 36bbef2293
Support quoted tombstone 2023-05-22 11:47:49 -05:00
Alex Gleason 6062a06746
Improve schemas for statuses 2023-05-22 10:30:22 -05:00
Alex Gleason fa0bf8f5df
Improve statusSchema 2023-05-22 10:30:14 -05:00
Alex Gleason 752f06b925
actions: improve types 2023-05-22 10:30:03 -05:00
Alex Gleason 3341b46dda
statusSchema: add HTML fields 2023-05-22 10:29:54 -05:00
Alex Gleason bf7c08d4d1
DetailedStatus: remove unused props 2023-05-22 10:29:52 -05:00
Chewbacca e0056d4931 Reduce size of Ad icon 2023-05-22 09:49:00 -04:00
Chewbacca bfdd3a3d50 Fix header copy 2023-05-22 09:47:31 -04:00
marcin mikołajczak 8f8dd689a3 Merge branch 'account-header-menu' into 'develop'
Change key for 'copy link to profile' message

See merge request soapbox-pub/soapbox!2520
2023-05-21 22:04:54 +00:00
marcin mikołajczak 15186bada3 Proper spacing on MFA page
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-05-21 23:53:44 +02:00
marcin mikołajczak 2605f72cb8 Change key for 'copy link to profile' message
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-05-21 23:33:28 +02:00
Alex Gleason cdd0fd63b2 Merge branch 'nip07' into 'develop'
Implement NIP-07

See merge request soapbox-pub/soapbox!2513
2023-05-21 02:34:42 +00:00
Alex Gleason f318c35544
Simplify event signing 2023-05-20 21:15:53 -05:00
marcin mikołajczak 73ec6a92bb Merge branch 'search-hotkey' into 'develop'
Add `/` as a hotkey for search

See merge request soapbox-pub/soapbox!2517
2023-05-20 05:36:28 +00:00
Alex Gleason 4725eec11e Merge branch 'api_v1' into 'develop'
api/pleroma/admin --> api/v1/pleroma/admin

Closes #1427

See merge request soapbox-pub/soapbox!2518
2023-05-20 00:17:39 +00:00
NEETzsche 2709153c20 api/pleroma/admin --> api/v1/pleroma/admin 2023-05-19 16:18:26 -07:00
marcin mikołajczak 7efc5e2fbd Add '/' as a hotkey for search
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-05-20 00:22:10 +02:00
Alex Gleason 13c965f3ca Merge branch 'revoke' into 'develop'
Add missing import

See merge request soapbox-pub/soapbox!2516
2023-05-18 17:02:02 +00:00
oakes 98f5450a9e Add missing import 2023-05-18 12:53:32 -04:00
Alex Gleason 881c8083d2 Merge branch 'revoke' into 'develop'
Fix /oauth/revoke 404

See merge request soapbox-pub/soapbox!2515
2023-05-18 16:49:30 +00:00
oakes f4da2006ef Pass baseURL when revoking oauth token 2023-05-18 12:39:59 -04:00
marcin mikołajczak 6b39172122 Merge branch 'account-header-menu' into 'develop'
Slightly reorder account header menu items, add 'Copy link to profile'

See merge request soapbox-pub/soapbox!2514
2023-05-15 07:22:02 +00:00
marcin mikołajczak 9c5acc09f0 Slightly reorder account header menu items, add 'Copy link to profile'
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-05-14 22:35:53 +02:00
Alex Gleason e5837ebefb
nip07: catch signEvent error 2023-05-13 21:25:59 -05:00
Alex Gleason 85f526d1d4
Sign Nostr event with ditto 2023-05-13 21:07:36 -05:00
Alex Gleason a5c616312f
Merge remote-tracking branch 'origin/develop' into nostr-ws 2023-05-13 19:27:52 -05:00
Alex Gleason 857aded8c7 Merge branch 'fix-groups-test' into 'develop'
Fix type

See merge request soapbox-pub/soapbox!2512
2023-05-13 03:17:03 +00:00
Alex Gleason 829d207cea
Fix type 2023-05-12 21:46:36 -05:00
Alex Gleason 89ddc6a99e Merge branch 'fix-groups-test' into 'develop'
Fix groups test

See merge request soapbox-pub/soapbox!2511
2023-05-13 01:51:06 +00:00
Alex Gleason 275d456693
Fix groups test 2023-05-12 20:50:39 -05:00
Alex Gleason 0acbbc3445 Merge branch 'group-fixes' into 'develop'
Various Group fixes & improvements

See merge request soapbox-pub/soapbox!2510
2023-05-12 21:43:04 +00:00
Chewbacca a6519c5685 Merge branch 'group-hooks-tests' into 'develop'
Add tests for Group API hooks

See merge request soapbox-pub/soapbox!2508
2023-05-12 21:02:11 +00:00
Chewbacca cfaa3ea669 Invalidate group tags after updating Group 2023-05-12 12:50:32 -04:00
Chewbacca 682a86049e Linkify urls inside Group note 2023-05-12 11:51:44 -04:00
Chewbacca f27933965f Allow non-owners to see pinned tags 2023-05-12 11:51:00 -04:00
marcin mikołajczak 91bc40c732 Merge branch 'follow-hashtags' into 'develop'
Mastodon: Add ability to follow hashtags in web UI

Closes #1192

See merge request soapbox-pub/soapbox!2200
2023-05-11 22:11:35 +00:00
marcin mikołajczak 41e969616d Forgot to commit some files
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-05-11 22:10:58 +02:00
Chewbacca d2eca144fa Make sure GroupLinkPreview covers entire header 2023-05-11 15:13:36 -04:00
Chewbacca e84a4a6c45 Fix full-width of Group Header 2023-05-11 15:13:07 -04:00
Chewbacca 2c59933cd0 Handle API errors when failing to join group 2023-05-11 15:00:28 -04:00
Chewbacca 90f7c71256 Hide Group context in Compose button if not Group member 2023-05-11 14:41:31 -04:00
Chewbacca 93c67c863a Format tag input with # 2023-05-11 14:28:44 -04:00
Chewbacca 6ab41eb899 Add ability to share Group 2023-05-11 14:20:33 -04:00
marcin mikołajczak da6be7ba4c Merge remote-tracking branch 'soapbox/develop' into follow-hashtags 2023-05-11 19:31:25 +02:00
Chewbacca 8d05747537 Fix test 2023-05-11 08:30:13 -04:00
Chewbacca 2d087be65b Merge branch 'tombstone' into 'develop'
Support soft-deleted statuses via tombstones

See merge request soapbox-pub/soapbox!2509
2023-05-09 19:48:04 +00:00
Chewbacca 4a2b7faa59 Support soft-deleted statuses via tombstones 2023-05-09 15:16:13 -04:00
Chewbacca afec0edc1c Add tests for Group API hooks 2023-05-08 13:29:11 -04:00
Chewbacca e9fee8aad3 Merge branch 'search-ux' into 'develop'
Remove search term after navigating away from Search page

See merge request soapbox-pub/soapbox!2498
2023-05-08 16:11:15 +00:00
Chewbacca da10423020 Merge branch 'login-ux' into 'develop'
Prevent focus on 'Trouble logging in?' link

See merge request soapbox-pub/soapbox!2505
2023-05-08 16:11:03 +00:00
Alex Gleason f4c7ab5dd6 Merge branch 'thread-line' into 'develop'
Thread fixes

See merge request soapbox-pub/soapbox!2507
2023-05-08 16:09:16 +00:00
Alex Gleason c5c2378542 Merge branch 'zod-notification' into 'develop'
zod: Notification, Attachment, ChatMessage, Status

See merge request soapbox-pub/soapbox!2500
2023-05-08 15:49:08 +00:00
Alex Gleason f47b5f0a20
Thread: fix display of initial loading indicator 2023-05-08 10:44:07 -05:00
Alex Gleason f290ca85e3
Thread: scroll up a little more on focus so the thread connector is visible 2023-05-08 10:39:25 -05:00
Alex Gleason 0f65c7bd7e
Auth: fix otherAccounts throwing a fullscreen error in local dev 2023-05-08 10:35:12 -05:00
Alex Gleason 0f91282edc Merge branch 'reply-mentions-maxwidth' into 'develop'
StatusReplyMentions: enforce a 200px max width

See merge request soapbox-pub/soapbox!2506
2023-05-07 04:19:41 +00:00
Alex Gleason 185ef4e3c6
StatusReplyMentions: enforce a 200px max width 2023-05-06 22:55:36 -05:00
marcin mikołajczak 5e16d0875e Merge branch 'birthday-panel' into 'develop'
Hide relationship in BirthdayPanel

See merge request soapbox-pub/soapbox!2501
2023-05-06 06:29:41 +00:00
Chewbacca a491c6acb8 Prevent focus on 'Trouble logging in?' link 2023-05-05 15:15:59 -04:00
Chewbacca a35d95e9e3 Merge branch 'group-tests' into 'develop'
Group tests

See merge request soapbox-pub/soapbox!2502
2023-05-05 17:16:01 +00:00
Chewbacca 670b3cff02 Merge branch 'remove-groups-search' into 'develop'
Remove group search inside global search

See merge request soapbox-pub/soapbox!2499
2023-05-05 17:15:27 +00:00
Chewbacca 390855b6d9 Merge branch 'allow-owner-status-deletion' into 'develop'
Add ability for owners to delete statuses from Group

See merge request soapbox-pub/soapbox!2490
2023-05-05 17:15:08 +00:00
Alex Gleason fe3e53d527 Merge branch 'Bassam-Dev' into 'develop'
Enhance RTL detection by ignoring links in post

See merge request soapbox-pub/soapbox!2503
2023-05-05 16:31:18 +00:00
Alex Gleason 7a0ce1aab4 Sound better now! 2023-05-05 16:26:58 +00:00
Ahmad Dakhlallah 06d8370fe6 Enhance RTL detection by ignoring links in post 2023-05-05 17:51:33 +03:00
Chewbacca de3ff58f95 Merge branch 'group-improvements' into 'develop'
Improve Group UX

See merge request soapbox-pub/soapbox!2494
2023-05-05 13:13:37 +00:00
Chewbacca 2e7e6b3df6 I18n 2023-05-05 08:44:23 -04:00
Chewbacca 5b61aa39a7 Account for 409 response codes 2023-05-05 08:41:25 -04:00
Chewbacca 9b011275b8 Switch order of Group Page tabs 2023-05-05 08:35:21 -04:00
Chewbacca db91a00aca Add more Jest tests for various Group components 2023-05-05 08:35:11 -04:00
Chewbacca ad6f237a9d Add back 'uses' attribute for specific use-case 2023-05-05 08:34:23 -04:00
marcin mikołajczak f1b98e1602 Hide relationship in BirthdayPanel
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-05-05 13:18:39 +02:00
Alex Gleason 0e7ccd57ae
Export new schemas 2023-05-04 12:20:39 -05:00
Alex Gleason e024e92125
Add a real statusSchema 2023-05-04 12:13:39 -05:00
Alex Gleason 9a64375681
useGroupMedia: don't use statusSchema directly yet so we can change it 2023-05-04 11:51:50 -05:00
Alex Gleason 1dec42cd9f
Add contentSchema helper 2023-05-04 11:42:20 -05:00
Alex Gleason a7e1350a65
Add real chatMessageSchema 2023-05-04 11:31:58 -05:00
Alex Gleason 074c3c5b39
Add attachmentSchema 2023-05-04 11:26:31 -05:00
Alex Gleason 55ebc8c6ee
Add notificationSchema 2023-05-04 10:24:34 -05:00
Chewbacca f8d31aa505 Merge branch 'thread-connector-fix' into 'develop'
Fix alignment on ThreadConnector

See merge request soapbox-pub/soapbox!2493
2023-05-04 14:14:22 +00:00
Alex Gleason da69cf140b Merge branch 'zod-poll' into 'develop'
zod: Poll

See merge request soapbox-pub/soapbox!2495
2023-05-04 14:10:15 +00:00
Chewbacca 8ebaca0b44 Remove group search inside global search 2023-05-04 09:48:39 -04:00
Chewbacca 9e33dc80ae Remove search term after navigating away from Search page 2023-05-04 09:24:37 -04:00
Chewbacca 4f081abb7a d 2023-05-04 08:14:43 -04:00
Alex Gleason 4dbcf1c711 Merge branch 'detailed-status-colors' into 'develop'
Detailed status colors

See merge request soapbox-pub/soapbox!2497
2023-05-04 02:11:11 +00:00
Alex Gleason 32d7a8b509 Merge branch 'shorthand-timestamp' into 'develop'
DetailedStatus: remove timestamp from account

See merge request soapbox-pub/soapbox!2496
2023-05-03 19:53:20 +00:00
Alex Gleason 04811c4618
InteractionCounter: use neutral colors 2023-05-03 14:37:41 -05:00
Alex Gleason 08b2f0446d
DetailedStatus: remove timestamp from account 2023-05-03 14:29:57 -05:00
Alex Gleason f48edfba45
Add tagSchema 2023-05-03 13:40:30 -05:00
Chewbacca ebaff75e38 Improve Group UX 2023-05-03 14:03:13 -04:00
Alex Gleason d4ed442a7e
Normalize poll with zod 2023-05-03 12:52:36 -05:00
Chewbacca 2baabd3e86 i18n 2023-05-03 11:17:47 -04:00
Chewbacca 27cc002572 Fix alignment on ThreadConnector 2023-05-03 11:13:47 -04:00
Alex Gleason 211fdd52f5
Fix normalizeChatMessageEmojiReaction 2023-05-03 08:01:02 -05:00
Chewbacca 4bc92f3c27 Add ability for owners to delete statuses from Group 2023-05-03 08:31:43 -04:00
Alex Gleason ece5ba4764
Merge remote-tracking branch 'origin/develop' into zod-card 2023-05-02 19:36:00 -05:00
Alex Gleason b608095e84 Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2438
2023-05-03 00:35:39 +00:00
Liberal dev 99df477bfd
Translated using Weblate (Korean)
Currently translated at 72.6% (1140 of 1570 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ko/
2023-05-03 02:35:12 +02:00
Hosted Weblate d90d138b05
Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/
2023-05-03 02:35:12 +02:00
marcin mikołajczak dc25f69d8e
Translated using Weblate (Polish)
Currently translated at 84.2% (1324 of 1571 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/pl/
2023-05-03 02:35:12 +02:00
Poesty Li 075ea7852a
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1567 of 1567 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-05-03 02:35:12 +02:00
Poesty Li c067690b10
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1548 of 1548 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-05-03 02:35:12 +02:00
Poesty Li 3d68b1062d
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1548 of 1548 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-05-03 02:35:12 +02:00
Allan Nordhøy fa4a6b61e0
Translated using Weblate (Norwegian Bokmål)
Currently translated at 96.7% (1498 of 1548 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/nb_NO/
2023-05-03 02:35:12 +02:00
Hosted Weblate 947197c7d4
Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/
2023-05-03 02:35:12 +02:00
Poesty Li df3d0c237a
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1548 of 1548 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-05-03 02:35:12 +02:00
Alex Gleason c0c0dc1cc2 Merge branch 'long-name-fixes' into 'develop'
Fix overflow problems in various places

See merge request soapbox-pub/soapbox!2487
2023-05-03 00:35:06 +00:00
Alex Gleason ce32aacac7 Merge branch 'renovate/floating-ui-react-0.x' into 'develop'
fix(deps): update dependency @floating-ui/react to ^0.24.0

See merge request soapbox-pub/soapbox!2488
2023-05-03 00:34:28 +00:00
Alex Gleason fb0f20cb64
cardSchema: drop card.pleroma from transformed type 2023-05-02 19:22:59 -05:00
Alex Gleason e3fcff55f9
Convert EmojiReaction to zod 2023-05-02 19:11:17 -05:00
Alex Gleason 0016aeacec
Normalize Relationship with zod 2023-05-02 18:49:13 -05:00
Alex Gleason 489145ffb8
Remove normalizeCard() 2023-05-02 18:33:41 -05:00
Alex Gleason 54d8d12054
Remove normalizeAd 2023-05-02 18:30:21 -05:00
Alex Gleason 81de7c268e
Refactor ad providers to not use normalizeCard 2023-05-02 17:56:25 -05:00
Alex Gleason 741da92084
Card: normalize with zod 2023-05-02 17:47:19 -05:00
marcin mikołajczak 586f536329 Update changelog
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-05-03 00:26:29 +02:00
marcin mikołajczak 610864d5a9 Add followed tags list
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-05-03 00:21:53 +02:00
marcin mikołajczak 7e3ab33dc5 Follow hashtags: Support Akkoma
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-05-02 23:34:46 +02:00
marcin mikołajczak c61368821a Use ListItem for 'Follow hashtag' setting
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-05-02 23:33:53 +02:00
marcin mikołajczak 5aaf4d75af Merge remote-tracking branch 'soapbox/develop' into follow-hashtags
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-05-02 23:32:43 +02:00
Chewbacca 0351bda198 Merge branch 'remove-pencil' into 'develop'
Remove pencil from Compose button

See merge request soapbox-pub/soapbox!2486
2023-05-02 20:28:09 +00:00
Soapbox Bot 19b77db295 fix(deps): update dependency @floating-ui/react to ^0.24.0 2023-05-02 20:06:31 +00:00
Alex Gleason 7dc97d44a3 Merge branch 'renovate/node-20.x' into 'develop'
Update Node.js to v20

See merge request soapbox-pub/soapbox!2457
2023-05-02 19:45:22 +00:00
Alex Gleason 6b68388d64
Upgrade eslint-plugin-jsdoc for Node 20 support 2023-05-02 14:23:25 -05:00
Alex Gleason c1922900ab
asdf: nodejs 20.0.0 2023-05-02 14:23:04 -05:00
Chewbacca 00cdecd943 Merge branch 'improve-entity-organization' into 'develop'
Move Group hooks to api folder

See merge request soapbox-pub/soapbox!2484
2023-05-02 18:40:28 +00:00
Alex Gleason 7aac5ccc34
Add support for Ditto 2023-05-02 13:38:47 -05:00
Alex Gleason 61283a8179
CHANGELOG: overflow fixes 2023-05-02 13:33:55 -05:00
Alex Gleason a065df0941
ReplyIndicator: use Markup component, horizontal scrolling of code blocks, etc 2023-05-02 13:32:31 -05:00
Alex Gleason 626ddfda80
Truncate long usernames in modals 2023-05-02 13:28:42 -05:00
Chewbacca e4d3dae51c Merge branch 'fix-note-html' into 'develop'
Support HTML version of note in Group Creation modal

See merge request soapbox-pub/soapbox!2485
2023-05-02 18:22:08 +00:00
Alex Gleason 9f2540c5c3
Modal: truncate long title 2023-05-02 13:14:45 -05:00
Alex Gleason ac9653a89f
UserPanel: truncate long display name 2023-05-02 13:12:57 -05:00
Alex Gleason ca2dffd9c3
ProfileInfoPanel: truncate long username while loading 2023-05-02 13:09:58 -05:00
Alex Gleason be41c78030
UserPanel: truncate long acct 2023-05-02 13:08:11 -05:00
Alex Gleason a38bc912c7
EditProfile: prevent crash with account.source is not available 2023-05-02 12:51:12 -05:00
Alex Gleason 9776cc9623
Settings: truncate long usernames 2023-05-02 12:50:55 -05:00
Chewbacca 238c30acf8 Split out hooks from 'useGroups' 2023-05-02 13:48:55 -04:00
Alex Gleason 6aabad9df3
List: prevent long content overflow 2023-05-02 12:48:01 -05:00
Chewbacca 4dd4ba212d Remove pencil from Compose button 2023-05-02 13:33:42 -04:00
Chewbacca 0f1e7fb2a7 Support HTML version of note in Group Creation modal 2023-05-02 13:29:29 -04:00
Chewbacca e0af6c4b2e Move Group hooks to api folder 2023-05-02 13:26:30 -04:00
Alex Gleason bf7d7f93a5 Merge branch 'dismiss-memberships' into 'develop'
useGroupMembershipRequests: dismiss instead of decrement

See merge request soapbox-pub/soapbox!2481
2023-05-02 16:53:23 +00:00
Chewbacca 799b845467 Merge branch 'add-tests' into 'develop'
Add tests for Groups discover components

See merge request soapbox-pub/soapbox!2483
2023-05-01 17:11:02 +00:00
Alex Gleason 95364a46d9 Merge branch 'contextual-compose' into 'develop'
Contextual compose button

See merge request soapbox-pub/soapbox!2478
2023-05-01 16:06:13 +00:00
Chewbacca 4d609b57d6 Add tests for Groups discover components 2023-05-01 12:01:39 -04:00
Chewbacca 78621a696e Merge branch 'handle-deleted-groups' into 'develop'
Account for soft-deleted Groups in the profile

See merge request soapbox-pub/soapbox!2479
2023-05-01 15:58:06 +00:00
marcin mikołajczak 696e97bb19 Merge branch 'groups-note-plain' into 'develop'
Use note_plain on group edit page

See merge request soapbox-pub/soapbox!2482
2023-04-29 13:35:59 +00:00
marcin mikołajczak 97dd235de3 Use note_plain on group edit page
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-04-29 13:56:07 +02:00
Alex Gleason d8a3f51e4a
useGroupMembershipRequests: dismiss instead of decrement 2023-04-27 14:11:45 -05:00
Alex Gleason a1b9d8a682
Fix ComposeButton tests 2023-04-27 13:20:53 -05:00
Chewbacca fbb258c387 Merge branch 'fix-group-relationship-state-bug' into 'develop'
Update GroupRelationship state after join/leave group

See merge request soapbox-pub/soapbox!2477
2023-04-27 14:14:47 +00:00
marcin mikołajczak ac220cb642 Merge branch 'explanation-box-dismiss' into 'develop'
Use dismiss button instead of menu in fediverse explanation box

See merge request soapbox-pub/soapbox!2480
2023-04-27 06:06:18 +00:00
Alex Gleason 44300539d5
yarn i18n 2023-04-26 16:41:20 -05:00
marcin mikołajczak 21b6ad1cbd Add dismiss button instead of menu in fediverse explanation box
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-04-26 23:28:57 +02:00
Alex Gleason 8ee5727cd8
ComposeModal: add share to group toggle 2023-04-26 15:53:06 -05:00
Alex Gleason 506cad3b70
FloatingActionButton: contextual group support 2023-04-26 15:33:34 -05:00
Alex Gleason a193108ef8
ComposeModal: become group-aware 2023-04-26 15:14:54 -05:00
Alex Gleason f9b5954060
ComposeModal: allow passing a composeId 2023-04-26 15:07:19 -05:00
Chewbacca 27f632786f Account for soft-deleted Groups in the profile 2023-04-26 15:53:52 -04:00
Chewbacca 3a5f9f3c93 Update GroupRelationship state after join/leave group 2023-04-26 14:27:36 -04:00
Alex Gleason 4720922015
ComposeButton: style group compose button 2023-04-26 13:06:03 -05:00
Chewbacca 84641d053a Merge branch 'improve-group-popover' into 'develop'
Hide 'View group' button if already on Group

See merge request soapbox-pub/soapbox!2476
2023-04-26 17:06:16 +00:00
Chewbacca 1960eb000a Merge branch 'hide-status-info-on-threads' into 'develop'
Hide status info if Thread Status

See merge request soapbox-pub/soapbox!2475
2023-04-26 17:06:02 +00:00
Chewbacca c001a4ab76 Merge branch 'update-group-tag-schema' into 'develop'
Change 'uses' to 'groups' in Tag schema

See merge request soapbox-pub/soapbox!2474
2023-04-26 17:05:38 +00:00
Chewbacca f19e3b01c2 Merge branch 'fix-visibility-logic' into 'develop'
Fix logic with toggling Group Tag visibility

See merge request soapbox-pub/soapbox!2473
2023-04-26 17:05:29 +00:00
Chewbacca b0ac174f80 Merge branch 'handle-null-group' into 'develop'
Handle null group in confirmation step

See merge request soapbox-pub/soapbox!2472
2023-04-26 17:01:31 +00:00
Chewbacca 915c19c7eb Merge branch 'improve-group-avatar-fallback' into 'develop'
Improve fallback of Group Avatars not loading

See merge request soapbox-pub/soapbox!2471
2023-04-26 17:01:14 +00:00
Chewbacca 7548c26490 Hide 'View group' button if already on Group 2023-04-26 10:11:54 -04:00
Chewbacca b2848f52f9 Hide status info if Thread Status 2023-04-26 09:46:31 -04:00
Chewbacca 5d923842c5 Change 'uses' to 'groups' in Tag schema 2023-04-26 09:17:31 -04:00
Chewbacca 4f0cafabcf Fix logic with toggling Group Tag visibility 2023-04-26 09:08:00 -04:00
Chewbacca 6cda34fb69 Handle null group in confirmation step 2023-04-26 09:06:02 -04:00
Chewbacca 36be68cdcc Improve fallback of Group Avatars not loading 2023-04-26 09:04:25 -04:00
marcin mikołajczak e5cf1dfa85 Merge branch 'deafult-privacy' into 'develop'
Fix default privacy setting on Mastodon

See merge request soapbox-pub/soapbox!2470
2023-04-25 20:47:26 +00:00
marcin mikołajczak 929935fb19 Fix default privacy setting on Mastodon
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-04-25 19:14:02 +02:00
Alex Gleason 39d381ae4a Merge branch 'drop-zones' into 'develop'
Drop zones

See merge request soapbox-pub/soapbox!2464
2023-04-25 13:55:17 +00:00
Chewbacca 762b9946d0 Merge branch 'fix-import' into 'develop'
Fix export

See merge request soapbox-pub/soapbox!2469
2023-04-24 17:01:25 +00:00
Chewbacca 1144b863a2 Fix export 2023-04-24 13:01:01 -04:00
Chewbacca 533400bd66 Merge branch 'clear-pending-cache' into 'develop'
Clear pending groups cache

See merge request soapbox-pub/soapbox!2468
2023-04-24 16:32:27 +00:00
Chewbacca 3bbaa02054 Merge branch 'fix-tab-counter' into 'develop'
Fix counter in Group tabs

See merge request soapbox-pub/soapbox!2467
2023-04-24 16:32:14 +00:00
Chewbacca c5151417d1 Merge branch 'fallback-group-images' into 'develop'
Handle errors on Group Headers

See merge request soapbox-pub/soapbox!2465
2023-04-24 16:20:25 +00:00
Chewbacca dfae278741 Merge branch 'remove-warning-for-group-posts' into 'develop'
Remove hashtag warning for Group posts

See merge request soapbox-pub/soapbox!2460
2023-04-24 16:20:10 +00:00
Chewbacca 81bf8649b4 Merge branch 'fix-reporting-modal' into 'develop'
Fix reporting modal

See merge request soapbox-pub/soapbox!2466
2023-04-24 16:19:55 +00:00
Chewbacca 68d3775737 Clear pending groups cache 2023-04-24 12:15:56 -04:00
Chewbacca 50a005da54 Fix counter in Group tabs 2023-04-24 11:46:31 -04:00
Chewbacca 9b90289e7c Fix confirmation step in Group report 2023-04-24 11:34:09 -04:00
Chewbacca 11cb90bb15 Allow admins to report Groups 2023-04-24 11:33:42 -04:00
Alex Gleason 5834be838b Merge branch 'group-tags-x' into 'develop'
GroupTagsField: hide "x" until there's more than one tag

See merge request soapbox-pub/soapbox!2461
2023-04-24 15:00:30 +00:00
Chewbacca b6a5c56859 Merge branch 'tag-improvements' into 'develop'
Tag improvements

See merge request soapbox-pub/soapbox!2458
2023-04-24 12:59:13 +00:00
Chewbacca 8530471ddb Handle errors on Group Headers 2023-04-24 08:17:51 -04:00
Chewbacca 9602382d39 Merge branch 'group-grid-list-item-fixes' into 'tag-improvements'
Group grid list item fixes

See merge request soapbox-pub/soapbox!2459
2023-04-24 12:01:09 +00:00
marcin mikołajczak abfad1a4a7 Merge branch 'gallery-empty-column' into 'develop'
Make empty-column-indicator fullwidth on Gallery pages

See merge request soapbox-pub/soapbox!2463
2023-04-22 21:35:28 +00:00
Alex Gleason 94b84438b0
yarn i18n 2023-04-21 19:27:26 -05:00
Alex Gleason cce0d639d8
CHANGELOG: drop zones 2023-04-21 17:34:21 -05:00
Alex Gleason 01b99d875b
Remove UploadArea component 2023-04-21 17:33:20 -05:00
Alex Gleason 0904b6a2a0
Fix drag-and-drop interaction with ComposeModal 2023-04-21 17:13:40 -05:00
marcin mikołajczak 4de4af6074 Merge branch 'filters-v2' into 'develop'
Fix v2 filters

See merge request soapbox-pub/soapbox!2462
2023-04-21 22:10:47 +00:00
Alex Gleason c9037f6661
GroupTimeline: add drop zone to composer 2023-04-21 16:54:23 -05:00
Alex Gleason d0722934a9
ComposeForm: expand when dragged 2023-04-21 16:54:08 -05:00
marcin mikołajczak 78ce8a4894 Make empty-column-indicator fullwidth on Gallery pages
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-04-21 23:50:08 +02:00
marcin mikołajczak 1e18f78756 Fix v2 filters
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-04-21 23:41:55 +02:00
Alex Gleason ed0206c379
Improve drag-and-drop of Home feed composer 2023-04-21 16:31:10 -05:00
Alex Gleason aad7309470
useDraggedFiles: control dragged state of node 2023-04-21 16:28:54 -05:00
Alex Gleason 28c8f1dbd6
Add useDraggedFiles hook 2023-04-21 16:03:44 -05:00
Alex Gleason 7ea9f0ad86
UploadArea: update deprecated e.keyCode --> e.key 2023-04-21 12:28:44 -05:00
Alex Gleason ede31e4e5a
GroupTagsField: hide "x" until there's more than one tag 2023-04-21 11:31:59 -05:00
Chewbacca 620e0cb606 Remove hashtag warning for Group posts 2023-04-21 10:19:37 -04:00
Chewbacca e5f7fe244c Grid spacing improvements 2023-04-21 10:11:34 -04:00
Chewbacca 63ca6554d1 Improve spacing between GroupGridItem 2023-04-21 09:46:19 -04:00
Chewbacca f61202c6e0 Fix z-index positioning of Group Grid item 2023-04-21 09:41:28 -04:00
Chewbacca ed4b86c5fa Add page to show statuses per tag 2023-04-21 09:36:37 -04:00
Chewbacca 6977d305bf Fix route to tag path 2023-04-21 09:36:26 -04:00
Chewbacca 7842f8e7dc Only owners can edit tags 2023-04-21 09:36:08 -04:00
Soapbox Bot 65bab5e786 Update Node.js to v20 2023-04-20 21:04:44 +00:00
Chewbacca fc6eba91ac Merge branch 'improve-group-creation' into 'develop'
Improve group creation

See merge request soapbox-pub/soapbox!2456
2023-04-20 14:28:25 +00:00
Chewbacca 67a5240e43 Add locale 2023-04-20 09:51:40 -04:00
Chewbacca 584b3bb539 Merge branch 'my-groups-pagination' into 'develop'
Support pagination in My Groups

See merge request soapbox-pub/soapbox!2455
2023-04-20 13:49:20 +00:00
marcin mikołajczak e72e39b5ef Merge branch 'schedule-form-order' into 'develop'
Move ScheduleForm below SpoilerInput in ComposeForm

See merge request soapbox-pub/soapbox!2452
2023-04-19 21:13:19 +00:00
Chewbacca c87589be4e Build group URI and handle successful copying 2023-04-19 16:51:07 -04:00
Chewbacca 2813b02329 Coerce group 'id' into String 2023-04-19 16:45:26 -04:00
Chewbacca 68be77fa54 Use 'copy' function for copying group uri 2023-04-19 16:44:22 -04:00
Chewbacca e43a9164b7 Update modal title in Group creation 2023-04-19 16:44:00 -04:00
Chewbacca 2516fd36e0 Update 'Create Group' modal title dynamically 2023-04-19 16:28:15 -04:00
Chewbacca bc72b1822e Support pagination in My Groups 2023-04-19 16:22:34 -04:00
Chewbacca 7675b18e52 Merge branch 'group-quote-fix' into 'develop'
Groups: set composer visibilty when quoting a group post

See merge request soapbox-pub/soapbox!2454
2023-04-19 15:54:44 +00:00
Alex Gleason 666c95e0b5
Groups: set composer visibilty when quoting a group post 2023-04-19 10:55:00 -04:00
Chewbacca 1074b003b0 Merge branch 'improve-status-info' into 'develop'
Improve StatusInfo for reposting from groups

See merge request soapbox-pub/soapbox!2453
2023-04-19 14:48:13 +00:00
Chewbacca 5dbaba3c41 Add locale 2023-04-19 10:20:23 -04:00
Chewbacca 2cce0435b4 Improve StatusInfo for reposting from groups 2023-04-19 10:09:03 -04:00
Chewbacca 5d58a3e18f Merge branch 'fix-request-to-media' into 'develop'
Fix 403 toast on Group Media endpoint

See merge request soapbox-pub/soapbox!2451
2023-04-19 13:24:25 +00:00
marcin mikołajczak 776cc1e5bb Move ScheduleForm below SpoilerInput in ComposeForm
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-04-19 15:20:19 +02:00
Alex Gleason ec903a984d Merge branch 'thread-scrolltop' into 'develop'
Thread: scroll into view accounting for sticky column header

See merge request soapbox-pub/soapbox!2449
2023-04-19 13:13:03 +00:00
Alex Gleason 2b74250981 Merge branch 'ads-spacing' into 'develop'
Improve spacing of ads

See merge request soapbox-pub/soapbox!2448
2023-04-19 13:12:38 +00:00
Chewbacca fcf6d258ef Prevent request to endpoint if not member 2023-04-18 16:51:55 -04:00
Chewbacca b1859ebfbb Merge branch 'fix-media-spacing' into 'develop'
Fix media spacing

See merge request soapbox-pub/soapbox!2450
2023-04-18 18:26:15 +00:00
Chewbacca e88be5fada Fix spacing 2023-04-18 12:03:52 -04:00
Chewbacca 0f29c5673c Fix bug with slug in Group Media 2023-04-18 12:03:42 -04:00
Alex Gleason 768fa1c4eb Merge branch 'profile-popup-corners' into 'develop'
ProfileHoverCard: fix rounded corners

See merge request soapbox-pub/soapbox!2447
2023-04-18 15:29:35 +00:00
Alex Gleason de9e7b3c90
Thread: scroll into view accounting for sticky column header 2023-04-18 11:00:36 -04:00
Alex Gleason 6ad99d10dc
Improve spacing of ads 2023-04-18 10:56:03 -04:00
Chewbacca 992e75f28e Merge branch 'group-lookup' into 'develop'
Add useEntityLookup hook

See merge request soapbox-pub/soapbox!2439
2023-04-18 14:48:05 +00:00
Alex Gleason 2216dc4d4c
ProfileHoverCard: fix rounded corners 2023-04-18 10:40:45 -04:00
Alex Gleason 70c2c5c438
GroupLinkPreview: link to slug URL 2023-04-18 10:00:18 -04:00
Alex Gleason bf8efeee9e
Merge remote-tracking branch 'origin/develop' into group-lookup 2023-04-18 09:59:53 -04:00
Alex Gleason 1dea7b47c8 Merge branch 'group-link-preview' into 'develop'
Group Link Preview

See merge request soapbox-pub/soapbox!2445
2023-04-18 13:59:16 +00:00
Alex Gleason 19dfda4ca2
GroupLinkPreview: dark mode 2023-04-18 09:39:09 -04:00
Alex Gleason 3f44e6cdcb
GroupLinkPreview: fix cursor 2023-04-18 09:31:08 -04:00
Chewbacca 3709b2caa6 Merge branch 'fix-endpoint' into 'develop'
Fix endpoint

See merge request soapbox-pub/soapbox!2446
2023-04-17 20:56:14 +00:00
Chewbacca a461ef9f51 Fix endpoint 2023-04-17 16:55:45 -04:00
Alex Gleason 7b544d2427
Group Link Preview 2023-04-17 16:36:05 -04:00
Alex Gleason c343cce5ea
Merge remote-tracking branch 'origin/develop' into group-lookup 2023-04-17 15:55:05 -04:00
Alex Gleason dea9979b39
GroupLookup: improve column loading 2023-04-17 15:45:16 -04:00
Alex Gleason f2d5b2eaef
Update group URLs to use slugs 2023-04-17 15:42:08 -04:00
Alex Gleason 1bce61182c
Make components use groupId param 2023-04-17 15:28:20 -04:00
Alex Gleason ccde5f8823
Make GroupLookup HOC kind of work 2023-04-17 14:56:31 -04:00
Chewbacca bf2f767c8f Merge branch 'manage-group-topics' into 'develop'
Manage group topics

See merge request soapbox-pub/soapbox!2378
2023-04-17 15:32:29 +00:00
Chewbacca ddee915d39 Lint + Tests 2023-04-17 10:22:00 -04:00
Chewbacca c5c5bd0d62 Add ability to update Group tags 2023-04-17 10:21:59 -04:00
Chewbacca 2d52c8c3e4 Add support for Group tags 2023-04-17 10:21:23 -04:00
Chewbacca 8ec8d4a2ca Use FloatingUI with Tooltip 2023-04-17 10:19:57 -04:00
Chewbacca 6da45c3ef7 Add ability to search my Groups 2023-04-17 10:19:57 -04:00
Chewbacca 5a6a6f63d2 Merge branch 'trending-topics' into 'develop'
Support Trending Topics

See merge request soapbox-pub/soapbox!2442
2023-04-17 14:19:31 +00:00
Chewbacca cc393e2425 Merge branch 'update-details' into 'develop'
Add group context to details screen

See merge request soapbox-pub/soapbox!2433
2023-04-17 14:12:58 +00:00
marcin mikołajczak ec63120d20 Merge branch 'username-or-email' into 'develop'
Only use 'username or e-mail' if can log in with username

See merge request soapbox-pub/soapbox!2444
2023-04-16 13:27:44 +00:00
marcin mikołajczak 6b4076ce10 lint
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-04-16 15:10:41 +02:00
Alex Gleason 324c427a72 Add truthsocial to loginWithUsername feature 2023-04-16 06:12:01 +00:00
marcin mikołajczak ba69f5ba62 update en.json
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-04-16 00:06:47 +02:00
marcin mikołajczak 8d832856b1 Only use 'username or e-mail' if can log in with username
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-04-16 00:03:06 +02:00
Chewbacca decc709b34 Merge branch 'repost-group-post' into 'develop'
Repost group post

See merge request soapbox-pub/soapbox!2443
2023-04-14 17:57:56 +00:00
Chewbacca 4cb628d5a4 Allow reposting Group posts 2023-04-14 08:07:49 -04:00
Alex Gleason 4cd43c340b
Fix group types :( 2023-04-13 10:43:24 -05:00
Chewbacca bb70c1ea3c Add topic pages 2023-04-13 09:28:40 -04:00
Chewbacca 8702c16998 Update GroupTag schema 2023-04-13 07:34:37 -04:00
Chewbacca 5d29666b41 Add support for trending tags 2023-04-13 07:33:52 -04:00
Chewbacca 5bcd150c4b Merge branch 'fix-z-index' into 'develop'
Resolve bug with toast during modal

See merge request soapbox-pub/soapbox!2436
2023-04-13 11:21:43 +00:00
Chewbacca cbb569b731 Merge branch 'fix-outline' into 'develop'
Fix outline of StatusActionButton

See merge request soapbox-pub/soapbox!2437
2023-04-13 11:21:34 +00:00
Chewbacca 18127b7cdb Merge branch 'handle-api-errors' into 'develop'
Handle error from API on Group Save

See merge request soapbox-pub/soapbox!2440
2023-04-13 11:21:23 +00:00
Chewbacca cd890c8641 Handle error from API on Group Save 2023-04-12 16:56:56 -04:00
Alex Gleason 4e822a80dd
Add useGroupLookup hook 2023-04-12 15:51:30 -05:00
Alex Gleason 17757ea326
Add useEntityLookup hook 2023-04-12 15:45:24 -05:00
Chewbacca 3f4bbe6f55 Merge branch 'add-toast' into 'develop'
Update toast after saving Groups

See merge request soapbox-pub/soapbox!2421
2023-04-12 20:42:37 +00:00
Chewbacca f55943a79b Fix outline of StatusActionButton 2023-04-12 16:09:18 -04:00
Chewbacca d165651800 Merge branch 'add-share-ability' into 'develop'
Add share ability to Group statuses

See merge request soapbox-pub/soapbox!2405
2023-04-12 20:09:13 +00:00
marcin mikołajczak 23fe4e5ce6 Merge branch 'datepicker-overflow' into 'develop'
Fix: scheduled poast box datepicker cut off again

Closes #1411

See merge request soapbox-pub/soapbox!2434
2023-04-12 19:43:14 +00:00
Chewbacca dc761f9416 Update i18n 2023-04-12 15:37:20 -04:00
Chewbacca dd94dbad8e Update toast after saving Groups 2023-04-12 15:32:29 -04:00
Chewbacca 575382b226 Add ability to share Group statuses 2023-04-12 15:18:00 -04:00
Chewbacca 5612cb6fdf Merge branch 'fix-reply-status-group' into 'develop'
Fix replying to status from Group

See merge request soapbox-pub/soapbox!2426
2023-04-12 19:05:42 +00:00
Chewbacca bb8dde1d64 Merge branch 'autofocus-streamfield' into 'develop'
Support autoFocus in Streamfield

See merge request soapbox-pub/soapbox!2432
2023-04-12 19:05:32 +00:00
Chewbacca 5f3250b175 Resolve bug with toast during modal 2023-04-12 15:04:42 -04:00
marcin mikołajczak c54adc7948 Merge branch 'event-location-fix' into 'develop'
Fix renderLocation in ComposeEventModal

Closes #1402

See merge request soapbox-pub/soapbox!2435
2023-04-12 18:27:29 +00:00
marcin mikołajczak d4c9d086d5 Fix renderLocation in ComposeEventModal
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-04-12 19:53:24 +02:00
marcin mikołajczak 3a9e4de5cc Fix: scheduled poast box datepicker cut off again
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-04-12 19:45:48 +02:00
Chewbacca 21419f23d4 Add group context to details screen 2023-04-12 09:44:33 -04:00
Chewbacca c8d9197065 Support autoFocus in Streamfield 2023-04-12 09:17:26 -04:00
Alex Gleason f23538c46a Merge branch 'home-link-headers' into 'develop'
Use Link header for home timeline pagination

See merge request soapbox-pub/soapbox!2395
2023-04-12 13:05:46 +00:00
Alex Gleason 08f8bd9264 Merge branch 'renovate/floating-ui-react-0.x' into 'develop'
Update dependency @floating-ui/react to ^0.23.0

See merge request soapbox-pub/soapbox!2424
2023-04-11 18:15:09 +00:00
Alex Gleason 8ea099aca8 Merge branch 'group-gallery' into 'develop'
Groups: add group gallery

See merge request soapbox-pub/soapbox!2427
2023-04-11 17:00:45 +00:00
Alex Gleason 7720df2ebe
Merge remote-tracking branch 'origin/develop' into group-gallery 2023-04-11 11:01:37 -05:00
Alex Gleason 75045a5eff Merge branch 'entity-pos' into 'develop'
EntityStore: allow customizing import position

See merge request soapbox-pub/soapbox!2430
2023-04-11 15:51:16 +00:00
Chewbacca b7c7b9cc71 Merge branch 'update-aside-for-manage-groups' into 'develop'
Update aside for Manage Group pages

See merge request soapbox-pub/soapbox!2422
2023-04-11 15:38:46 +00:00
Chewbacca c388ff2896 Merge branch 'fix-composer-button' into 'develop'
Improve spacing inside timelines

See merge request soapbox-pub/soapbox!2429
2023-04-11 15:38:22 +00:00
Alex Gleason 3d7cccd984
EntityStore: allow customizing import position 2023-04-11 10:04:31 -05:00
Alex Gleason b83309670d Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2402
2023-04-11 15:03:33 +00:00
Alex Gleason b2b1f5ece3
yarn i18n 2023-04-11 09:01:59 -05:00
Furkan Kalkan 406513391b
Translated using Weblate (Turkish)
Currently translated at 98.1% (1519 of 1547 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/tr/
2023-04-11 15:51:28 +02:00
Temuri Doghonadze 79b571e26c
Translated using Weblate (Georgian)
Currently translated at 24.9% (386 of 1547 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ka/
2023-04-11 15:51:28 +02:00
Poesty Li d8184f5d20
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1547 of 1547 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-04-11 15:51:28 +02:00
Furkan Kalkan 83db42cd98
Translated using Weblate (Turkish)
Currently translated at 98.1% (1519 of 1547 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/tr/
2023-04-11 15:51:28 +02:00
Furkan Kalkan 330002a4dc
Translated using Weblate (Turkish)
Currently translated at 99.1% (1533 of 1546 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/tr/
2023-04-11 15:51:28 +02:00
Poesty Li 51629861e7
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1544 of 1544 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-04-11 15:51:28 +02:00
Furkan Kalkan 784fce48c5
Translated using Weblate (Turkish)
Currently translated at 99.2% (1533 of 1544 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/tr/
2023-04-11 15:51:28 +02:00
Furkan Kalkan 790d2e0716
Translated using Weblate (Turkish)
Currently translated at 99.2% (1533 of 1544 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/tr/
2023-04-11 15:51:28 +02:00
Furkan Kalkan 840449b797
Translated using Weblate (Turkish)
Currently translated at 92.6% (1431 of 1544 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/tr/
2023-04-11 15:51:28 +02:00
Allan Nordhøy 66d1c681bc
Translated using Weblate (Norwegian Bokmål)
Currently translated at 97.0% (1499 of 1544 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/nb_NO/
2023-04-11 15:51:28 +02:00
Poesty Li 5783676b49
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1540 of 1540 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-04-11 15:51:28 +02:00
jonnysemon ac8e6b9bde
Translated using Weblate (Arabic)
Currently translated at 98.8% (1523 of 1540 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ar/
2023-04-11 15:51:28 +02:00
Hosted Weblate 2ad79f28de
Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/
2023-04-11 15:51:28 +02:00
Poesty Li 9071bf0b70
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1541 of 1541 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-04-11 15:51:28 +02:00
Poesty Li fad828cd3e
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1540 of 1540 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-04-11 15:51:28 +02:00
Hosted Weblate f7da07e69d
Update translation files
Updated by "Remove blank strings" hook in Weblate.

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/
2023-04-11 15:51:28 +02:00
Allan Nordhøy b006356ebe
Translated using Weblate (Norwegian Bokmål)
Currently translated at 97.3% (1499 of 1540 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/nb_NO/
2023-04-11 15:51:28 +02:00
jonnysemon 4ad5a6b8cd
Translated using Weblate (Arabic)
Currently translated at 99.2% (1529 of 1540 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ar/
2023-04-11 15:51:27 +02:00
Alex Gleason 0652b2cf57 Merge branch 'toggle-submit-fix' into 'develop'
Toggle: fix toggle acting as a submit button in forms

See merge request soapbox-pub/soapbox!2428
2023-04-11 13:51:21 +00:00
Chewbacca e82ecdc05c Improve alignment/spacing 2023-04-11 08:55:17 -04:00
Alex Gleason 0e1da7512c
Toggle: fix toggle acting as a submit button in forms 2023-04-10 15:25:42 -05:00
Alex Gleason ce0557546a
Groups: add group gallery 2023-04-10 15:22:08 -05:00
Chewbacca dc8468adc2 Set button type to Toggle 2023-04-10 16:03:27 -04:00
Chewbacca 39f2734bd4 Fix replying to status from Group 2023-04-10 15:59:36 -04:00
Alex Gleason 901ff57e13
Add `toSchema` function, to convert any legacy normalizer into a zod schema 2023-04-10 12:02:50 -05:00
Soapbox Bot 3a60bfcc35 Update dependency @floating-ui/react to ^0.23.0 2023-04-10 16:05:18 +00:00
Alex Gleason c2348a6249
Merge remote-tracking branch 'origin/develop' into home-link-headers 2023-04-10 10:13:19 -05:00
Alex Gleason 2315dbdae5 Merge branch 'thread' into 'develop'
Add sticky column header, improve design of threads

See merge request soapbox-pub/soapbox!2423
2023-04-10 15:10:08 +00:00
Alex Gleason 8476d69e7b
Threads: add a bit of space between the top post and column header 2023-04-10 09:53:51 -05:00
Alex Gleason 09a65a7500
ProfileInfoPanel: fix long usernames x-overflow'ing the page 2023-04-10 09:33:24 -05:00
Chewbacca ad5d5b1826 Merge branch 'group-notifications' into 'develop'
Support group notifications for favourites/reblogs

See merge request soapbox-pub/soapbox!2420
2023-04-10 13:49:33 +00:00
Alex Gleason 9b5acf9b17
Merge remote-tracking branch 'origin/develop' into thread 2023-04-05 19:30:42 -05:00
Alex Gleason 27d103f79f
yarn i18n 2023-04-05 19:30:26 -05:00
Alex Gleason 532013b34f Merge branch 'add-topics' into 'develop'
Groups: allow managing topics

See merge request soapbox-pub/soapbox!2416
2023-04-05 21:37:55 +00:00
Alex Gleason 749d6f0889
Streamfield: add space between inputs 2023-04-05 15:58:13 -05:00
Alex Gleason 7a3f98ca64
EditGroup: remove toast 2023-04-05 15:57:33 -05:00
Alex Gleason a875163ed9
Streamfield: remove "Add" button when maxItems is reached 2023-04-05 15:56:42 -05:00
Alex Gleason 088f7e0b0e
GroupTagsField: i18n 2023-04-05 15:55:29 -05:00
Alex Gleason a5d7841987
Thread: use a different title for Group posts 2023-04-05 15:21:53 -05:00
Alex Gleason 8831648af7
CHANGELOG: threads 2023-04-05 15:18:36 -05:00
Alex Gleason 4481d9227f
Drop thread back to a medium sized card 2023-04-05 15:17:11 -05:00
Alex Gleason c2f5ac82b8
Remove extraneous shadow from detailed-status.scss 2023-04-05 14:45:07 -05:00
Alex Gleason d0e7ccb8c8
Column: fix border-radius of sticky header when scrolled 2023-04-05 13:54:43 -05:00
Alex Gleason 1c45d575d4
Fix status placeholder 2023-04-05 13:18:53 -05:00
Alex Gleason 9e62226bd1
Make floating column header pretty much work 2023-04-05 13:16:18 -05:00
Alex Gleason 96cece3d2e
ColumnHeader: increase margin-bottom for size lg columns 2023-04-05 11:36:43 -05:00
Alex Gleason 0c15c336ea
Thread: increase spacing around thread, change title to "Post Details" 2023-04-05 11:02:23 -05:00
Chewbacca a94d2d036e Update aside for Manage Group pages 2023-04-05 10:29:57 -04:00
Alex Gleason 6ff1caa2fb Merge branch 'drop-invalid-count' into 'develop'
useEntities: drop X-Total-Count if it's less than the number of entities in the response

See merge request soapbox-pub/soapbox!2419
2023-04-05 14:26:47 +00:00
Chewbacca 23c466656b Merge branch 'fix-scroll-bug' into 'develop'
Fix infinite scroll bug with Group Search

See merge request soapbox-pub/soapbox!2414
2023-04-05 14:22:23 +00:00
Chewbacca 5fb4b498da Support group notifications for favourites/reblogs 2023-04-05 10:03:26 -04:00
Chewbacca 535579676b Merge branch 'max-admins' into 'develop'
Cap Group Admins at 5

See merge request soapbox-pub/soapbox!2415
2023-04-05 13:19:19 +00:00
Alex Gleason 9e5bd27cfb Merge branch 'invalidate-members' into 'develop'
GroupMembershipRequests: invalidate list on unmount

See merge request soapbox-pub/soapbox!2418
2023-04-04 21:32:11 +00:00
Alex Gleason 0c45889206
useEntities: drop X-Total-Count if it's less than the number of entities in the response (that doesn't make sense) 2023-04-04 16:02:44 -05:00
Alex Gleason 739062106b Merge branch 'group-permission-checks' into 'develop'
useGroupMembershipRequests: disable for non-staff roles

See merge request soapbox-pub/soapbox!2417
2023-04-04 20:57:03 +00:00
Alex Gleason 1049968fd6
GroupMembershipRequests: invalidate list on unmount 2023-04-04 15:35:28 -05:00
Chewbacca 4ac8c34a8c i18n 2023-04-04 16:26:32 -04:00
Alex Gleason f08d23c055
useGroupMembershipRequests: disable for non-staff roles 2023-04-04 15:14:06 -05:00
Alex Gleason 456ed852c4
yarn i18n 2023-04-04 14:59:52 -05:00
Alex Gleason ae4430b9eb
EditGroup: allow managing topics 2023-04-04 14:54:32 -05:00
Alex Gleason 914ed6fe9c
CreateGroupModal: allow adding topics 2023-04-04 14:10:20 -05:00
Alex Gleason 880e63f2ec
Streamfield: remove plus icon from button, adjust X icon color 2023-04-04 13:42:15 -05:00
Chewbacca 87fd56ffee Merge branch 'fix-search-groups' into 'develop'
Add 'path' to dep list

See merge request soapbox-pub/soapbox!2400
2023-04-04 18:23:12 +00:00
Chewbacca 2211c6ec67 Use medium weight if summary is present 2023-04-04 14:06:54 -04:00
Chewbacca 5fa8a21403 Cap Group Admins at 5 2023-04-04 14:05:08 -04:00
Alex Gleason 21af38c13d Merge branch 'group-modal' into 'develop'
Group modal

See merge request soapbox-pub/soapbox!2408
2023-04-04 17:54:24 +00:00
Alex Gleason 8cca3c4e6e
Merge remote-tracking branch 'origin/develop' into group-modal 2023-04-04 12:29:51 -05:00
Alex Gleason 2c3006df93
CreateGroupModal: toast on error 2023-04-04 11:50:37 -05:00
Chewbacca b704e476eb Merge branch 'update-group-header' into 'develop'
Allow Admins to manage/leave Group

See merge request soapbox-pub/soapbox!2410
2023-04-04 16:35:52 +00:00
Alex Gleason 3d1c0fa813
Fix groups index being updated when a new group is created 2023-04-04 11:16:26 -05:00
Chewbacca f20dade50b Update entity in store after canceling request 2023-04-04 12:08:29 -04:00
Chewbacca e78bbf4e19 Allow Admins to manage/leave Group 2023-04-04 12:08:26 -04:00
Chewbacca 909f294165 Add 'path' to dep list 2023-04-04 11:58:34 -04:00
Chewbacca 8cb0540361 Fix infinite scroll bug with Group Search 2023-04-04 11:45:27 -04:00
Chewbacca 17800fa56f Merge branch 'fix-icon-color' into 'develop'
Update icon color for Group Statuses

See merge request soapbox-pub/soapbox!2409
2023-04-04 14:42:41 +00:00
Chewbacca 5fe7ffd2cb Merge branch 'fix-member-bug' into 'develop'
Fetch account and relationship with entity store

See merge request soapbox-pub/soapbox!2413
2023-04-04 14:42:25 +00:00
Chewbacca 7ef2220405 Revert change to key 2023-04-04 08:13:23 -04:00
Chewbacca a486b317d4 Fetch account and relationship with entity store 2023-04-04 08:11:03 -04:00
Chewbacca 4c9b2c3a00 Merge branch 'fix-theme-selector' into 'develop'
Fix theme selector icon placement

Closes #1406

See merge request soapbox-pub/soapbox!2412
2023-04-04 11:36:59 +00:00
Chewbacca bdea044220 Merge branch 'fix-animation' into 'develop'
Fix dark mode animation

See merge request soapbox-pub/soapbox!2411
2023-04-04 11:36:03 +00:00
Chewbacca 11b86ecad6 Fix theme selector icon placement
Closes https://gitlab.com/soapbox-pub/soapbox/-/issues/1406
2023-04-04 06:57:39 -04:00
Chewbacca c2902b16ec Fix dark mode animation 2023-04-04 06:55:33 -04:00
Alex Gleason 8d67556bdf
yarn 118n 2023-04-03 16:46:02 -05:00
Chewbacca c045a6630d Merge branch 'remove-pending-requests' into 'develop'
Remove 'Pending requests' from Group Manage

See merge request soapbox-pub/soapbox!2406
2023-04-03 21:26:42 +00:00
Chewbacca b959b14746 Update icon color in Group timeline 2023-04-03 17:17:03 -04:00
Chewbacca fd9fc8bb59 Update icon color for Group statuses 2023-04-03 17:02:13 -04:00
Alex Gleason 9aac68fee8
Merge remote-tracking branch 'origin/develop' into group-modal 2023-04-03 15:23:31 -05:00
Chewbacca 316a224c08 Merge branch 'fix-icon' into 'develop'
Fix icon in Group recent searches

See merge request soapbox-pub/soapbox!2407
2023-04-03 20:19:57 +00:00
Chewbacca 6dc962f6aa Fix icon 2023-04-03 16:19:19 -04:00
Alex Gleason a4992eec4d
isLoading --> isSubmitting for action hooks 2023-04-03 15:19:10 -05:00
Alex Gleason c9a724525e
ManageGroupModal --> CreateGroupModal 2023-04-03 15:12:50 -05:00
Alex Gleason 9d0ff2b8a4
Remove group-editor code 2023-04-03 15:10:33 -05:00
Alex Gleason 659c186394
ManageGroupModal: use internal state instead of Redux 2023-04-03 15:06:20 -05:00
Chewbacca aed41989f5 Remove 'Pending requests' from Group Manage 2023-04-03 15:57:12 -04:00
Chewbacca d2224c0359 Merge branch 'udpate-toast-copy' into 'develop'
Update copy after requesting to join group

See merge request soapbox-pub/soapbox!2404
2023-04-03 19:47:47 +00:00
Chewbacca c2f5671de1 Update copy after requesting to join group 2023-04-03 15:38:41 -04:00
Alex Gleason 1b9c070a20
EditGroup: move AvatarPicker and HeaderPicker into their own components 2023-04-03 14:26:31 -05:00
Alex Gleason 51fa0c27ca Merge branch 'tw-line-clamp' into 'develop'
Remove deprecated Tailwind line-clamp plugin (now bundled with v3.3)

See merge request soapbox-pub/soapbox!2403
2023-04-03 18:15:03 +00:00
Chewbacca 29f8ee234f Merge branch 'refactor-group-layout-selector' into 'develop'
Refactor Group Layout selection

See merge request soapbox-pub/soapbox!2399
2023-04-03 18:07:44 +00:00
Chewbacca bb70568bac Merge branch 'fix-list-item-weight' into 'develop'
Fix weight of List Item text

See merge request soapbox-pub/soapbox!2398
2023-04-03 18:07:20 +00:00
Chewbacca f5ec14e9ba Merge branch 'add-animation-to-auth-rej-buttons' into 'develop'
Add animation to AuthorizeRejectButton comp

See merge request soapbox-pub/soapbox!2396
2023-04-03 18:07:06 +00:00
Chewbacca b5a657172a Merge branch 'update-banned-members' into 'develop'
Update banned members design

See merge request soapbox-pub/soapbox!2397
2023-04-03 18:06:58 +00:00
Alex Gleason d844ee4e54
Remove deprecated Tailwind line-clamp plugin (now bundled with v3.3) 2023-04-03 12:03:59 -05:00
Chewbacca 607e91e8cf Refactor Group Layout selection 2023-04-03 12:56:29 -04:00
Chewbacca c67d5712ba Fix weight of List Item text 2023-04-03 12:17:29 -04:00
Chewbacca 485213972e Update banned members design 2023-04-03 12:13:41 -04:00
Chewbacca 2240952b8f Add animation to AuthorizeRejectButton comp 2023-04-03 09:51:22 -04:00
Alex Gleason f3251d146e Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2358
2023-04-03 04:37:08 +00:00
Alex Gleason 86a5753d10
Sign nostr event from websocket 2023-04-02 20:50:48 -05:00
Alex Gleason 2bc6ff3fa3
Use Link header for home timeline pagination 2023-04-02 18:32:50 -05:00
Tassoman 43ffceabac
Translated using Weblate (Italian)
Currently translated at 94.4% (1454 of 1540 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/it/
2023-04-02 20:17:14 +02:00
jonnysemon d558fb9f61
Translated using Weblate (Arabic)
Currently translated at 99.1% (1527 of 1540 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ar/
2023-04-02 12:01:14 +02:00
Poesty Li 6c2887e8b3
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1540 of 1540 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-04-02 12:01:14 +02:00
Isabell De Inschnitzel 7dde47f5a1
Translated using Weblate (German)
Currently translated at 90.9% (1400 of 1540 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/de/
2023-04-02 12:01:14 +02:00
Poesty Li 2a3586ba24
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1539 of 1539 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-04-02 12:01:14 +02:00
Hosted Weblate 828e9a881c
Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/
2023-04-02 12:01:14 +02:00
Allan Nordhøy d7e76743d7
Translated using Weblate (Norwegian Bokmål)
Currently translated at 95.8% (1474 of 1538 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/nb_NO/
2023-04-02 12:01:14 +02:00
Ahmad Dakhlallah 4134557e0d
Translated using Weblate (Arabic)
Currently translated at 94.2% (1450 of 1538 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ar/
2023-04-02 12:01:14 +02:00
Hosted Weblate 8eba32a20c
Update translation files
Updated by "Remove blank strings" hook in Weblate.

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/
2023-04-02 12:01:14 +02:00
Allan Nordhøy 0cc1b8af09
Translated using Weblate (Norwegian Bokmål)
Currently translated at 95.2% (1465 of 1538 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/nb_NO/
2023-04-02 12:01:14 +02:00
Poesty Li 83b80dc48c
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1538 of 1538 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-04-02 12:01:14 +02:00
Poesty Li 721c85f108
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1532 of 1532 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-04-02 12:01:13 +02:00
Poesty Li 5e6d054f65
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1531 of 1531 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-04-02 12:01:13 +02:00
Poesty Li 8300559eba
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1531 of 1531 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-04-02 12:01:13 +02:00
Poesty Li 291d2e62c5
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1525 of 1525 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-04-02 12:01:13 +02:00
Hosted Weblate 88b0b617db
Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/
2023-04-02 12:01:13 +02:00
Poesty Li 54035073aa
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1526 of 1526 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-04-02 12:01:13 +02:00
gallegonovato 1e76c42ad2
Translated using Weblate (Spanish)
Currently translated at 100.0% (1523 of 1523 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/es/
2023-04-02 12:01:13 +02:00
Hosted Weblate 461a006d02
Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/
2023-04-02 12:01:13 +02:00
Poesty Li 614b0494e7
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1523 of 1523 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-04-02 12:01:13 +02:00
Hosted Weblate 7d3e960d8f
Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/
2023-04-02 12:01:13 +02:00
Poesty Li 1974655a52
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1522 of 1522 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-04-02 12:01:13 +02:00
gallegonovato a685065f1b
Translated using Weblate (Spanish)
Currently translated at 100.0% (1522 of 1522 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/es/
2023-04-02 12:01:12 +02:00
Hosted Weblate 7b10065e73
Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/
2023-04-02 12:01:12 +02:00
Hosted Weblate ffd11b0aa3
Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/
2023-04-02 12:01:12 +02:00
Poesty Li 21a7fbab9d
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1524 of 1524 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-04-02 12:01:12 +02:00
Isabell De Inschnitzel 4c7d8029c0
Translated using Weblate (German)
Currently translated at 93.1% (1419 of 1524 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/de/
2023-04-02 12:01:12 +02:00
gallegonovato f67f23274c
Translated using Weblate (Spanish)
Currently translated at 100.0% (1524 of 1524 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/es/
2023-04-02 12:01:12 +02:00
marcin mikołajczak 9c3af7a0c9 Merge branch 'media-panel-aspect-ratio' into 'develop'
Update TailwindCSS, fix aspect ratio in ProfileMediaPanel

See merge request soapbox-pub/soapbox!2393
2023-04-02 10:00:55 +00:00
marcin mikołajczak a1cf627bfd Lint
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-04-01 20:37:34 +02:00
marcin mikołajczak 817459536d Update TailwindCSS, fix aspect ratio in ProfileMediaPanel
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-04-01 15:46:21 +02:00
Alex Gleason 72b57d93da Merge branch 'groups-toggle' into 'develop'
Groups toggle

See merge request soapbox-pub/soapbox!2391
2023-03-31 19:06:10 +00:00
Alex Gleason 839a639f1e
Only show toggle for public groups 2023-03-31 13:46:09 -05:00
Alex Gleason 59860b405a
GroupTimeline: use FormattedMessage 2023-03-31 12:17:20 -05:00
Alex Gleason 1c71cf3da4
Toggle: prevent clicking label getting it stuck 2023-03-31 12:04:52 -05:00
Alex Gleason 406e6f3f40
GroupTimeline: make label clickable 2023-03-31 12:00:15 -05:00
Alex Gleason 94f67e166e
GroupTimeline: use size sm Toggle 2023-03-31 11:58:23 -05:00
Alex Gleason 2b5a3f720d
Toggle: fix size sm track 2023-03-31 11:58:10 -05:00
Alex Gleason d0fbc881e7
Remove react-toggle 2023-03-31 11:52:19 -05:00
Alex Gleason d7cb52c40c
Toggle: add "name" prop 2023-03-31 11:50:32 -05:00
Alex Gleason 6f48d6500d
Toggle: add disabled state 2023-03-31 11:47:41 -05:00
Alex Gleason 91f92050dc
Toggle: fix JSDoc comment 2023-03-31 11:18:45 -05:00
Alex Gleason 79a8cd6b13
Toggle: use bg-primary-600 when checked 2023-03-31 11:17:06 -05:00
Alex Gleason e38b5fbfd3
Toggle: add size prop 2023-03-31 11:15:48 -05:00
Alex Gleason 541d48c5ab
Replace Toggle with a custom component 2023-03-31 11:06:43 -05:00
Chewbacca b277143e3a Merge branch 'chunk' into 'develop'
Change discover chunk to groups

See merge request soapbox-pub/soapbox!2392
2023-03-31 12:01:37 +00:00
Chewbacca eeafb3073e Change discover chunk to groups 2023-03-31 08:00:21 -04:00
Chewbacca ccd97e1405 Merge branch 'group-dark-mode' into 'develop'
Improve Dark mode support for Groups + Tests

See merge request soapbox-pub/soapbox!2390
2023-03-31 11:44:28 +00:00
Alex Gleason 5720d396fc
Groups: make "share with followers" button work 2023-03-30 20:47:08 -05:00
Chewbacca a994d1c33e i18n 2023-03-30 20:46:18 -04:00
Chewbacca 681eacf827 Improve dark mode support of Groups + bug fixes 2023-03-30 15:19:14 -04:00
Chewbacca 4b3b601659 Add tests for GroupOptionsButton 2023-03-30 12:57:42 -04:00
Chewbacca 697791fc5d Add tests for GroupRelationship 2023-03-30 12:57:23 -04:00
Alex Gleason a976b542e1 Merge branch 'edit-group-page' into 'develop'
Edit group page

See merge request soapbox-pub/soapbox!2389
2023-03-30 13:57:57 +00:00
Chewbacca e32ea32f15 Merge branch 'group-name-validation' into 'develop'
Group name validation

See merge request soapbox-pub/soapbox!2388
2023-03-30 13:28:03 +00:00
Chewbacca ff3c0c5cd7 i18n 2023-03-30 09:25:15 -04:00
Chewbacca 01458c3003 Merge branch 'reply-popover' into 'develop'
Add popover when trying to reply to Group status

See merge request soapbox-pub/soapbox!2386
2023-03-30 13:23:47 +00:00
Alex Gleason 453420796b
yarn i18n 2023-03-29 20:49:04 -05:00
Alex Gleason e47b9300f0
EditGroup: add "cannot change" hint 2023-03-29 20:45:40 -05:00
Alex Gleason ddf433a5c9
FormGroup: move hintText above input 2023-03-29 20:42:57 -05:00
Alex Gleason 79a33d0f1d
Input: improve disabled style 2023-03-29 20:37:22 -05:00
Alex Gleason 9e60d90812
We do a little refactoring 2023-03-29 20:30:05 -05:00
Alex Gleason f3727440ff
Move form hooks into their own files 2023-03-29 20:14:41 -05:00
Alex Gleason eb055339d8
react-hook-form SUX 2023-03-29 20:00:04 -05:00
Alex Gleason 9c78a37844
Merge remote-tracking branch 'origin/develop' into edit-group-page 2023-03-29 19:31:01 -05:00
Alex Gleason 8e6dfe6395 Merge branch 'textarea-counter' into 'develop'
Textarea: add a character counter

See merge request soapbox-pub/soapbox!2373
2023-03-30 00:30:39 +00:00
Alex Gleason 7ec51778f8 Apply 1 suggestion(s) to 1 file(s) 2023-03-30 00:30:27 +00:00
Alex Gleason eb6c82a867
Make EditGroup page work, pretty much 2023-03-29 19:18:20 -05:00
Alex Gleason bfd40fa373
Boilerplate Edit Group page by copying code from the modal 2023-03-29 14:51:29 -05:00
Chewbacca 455030ef5b Add validation support to features 2023-03-29 15:44:00 -04:00
Chewbacca 4886548889 Add validation support to Group names 2023-03-29 15:42:20 -04:00
Chewbacca 85e5780645 Deprecate old Icon component 2023-03-29 15:42:05 -04:00
Chewbacca 20960d7238 Improve UI of List component 2023-03-29 15:41:49 -04:00
Alex Gleason 319d47b36f Merge branch 'pending-memberships-dot' into 'develop'
Groups: add dot to group with pending membership requests

See merge request soapbox-pub/soapbox!2387
2023-03-29 19:13:54 +00:00
Alex Gleason 609a25fd8d
Groups: add dot to group with pending membership requests 2023-03-29 12:21:43 -05:00
marcin mikołajczak 55c0f8d6a1 Merge branch 'friendica' into 'develop'
Friendica dislikes

See merge request soapbox-pub/soapbox!2381
2023-03-28 22:13:24 +00:00
Chewbacca 1e69812078 Add popover when trying to reply to Group status 2023-03-28 15:39:41 -04:00
Chewbacca 89ab02224f Merge branch 'group-improvements' into 'develop'
Group improvements

See merge request soapbox-pub/soapbox!2385
2023-03-28 17:21:10 +00:00
Chewbacca af9439f1d3 Use entity store for Group Search 2023-03-28 12:57:44 -04:00
Chewbacca a916056367 Re-use GroupActionButton component 2023-03-28 11:53:13 -04:00
Chewbacca 9fe2d4f92c Remove unused query 2023-03-28 11:53:13 -04:00
Chewbacca ca0987dec2 Update variables to use proper naming 2023-03-28 11:53:13 -04:00
Chewbacca 6458ebbb11 Ensure button text stays centered 2023-03-28 11:53:13 -04:00
Chewbacca 966fcc617a Merge branch 'fix-loading-state' into 'develop'
Fix loading animation for Carousel

See merge request soapbox-pub/soapbox!2383
2023-03-28 15:52:56 +00:00
Chewbacca e12450ee5d Merge branch 'group-improvements' into 'develop'
Remove mock data for Group Discovery

See merge request soapbox-pub/soapbox!2384
2023-03-28 14:33:49 +00:00
Chewbacca 29c913859e Remove mock data for Group Discovery 2023-03-28 10:32:56 -04:00
Chewbacca be4a7e45e9 Fix loading animation for Carousel 2023-03-28 10:30:34 -04:00
Chewbacca 1abcc95a0a Merge branch 'search-my-groups' into 'develop'
Add ability to search my Groups

See merge request soapbox-pub/soapbox!2377
2023-03-28 14:02:25 +00:00
Chewbacca e6252070a6 Fix test 2023-03-28 09:46:55 -04:00
Alex Gleason f2744cdf98 Merge branch 'pending-timer' into 'develop'
AuthorizeRejectButtons: add a countdown timer, remove rejectUserModal

See merge request soapbox-pub/soapbox!2382
2023-03-28 13:35:38 +00:00
Chewbacca 3a2b4c6efb Add ability to search my Groups 2023-03-28 09:09:09 -04:00
Alex Gleason 232e387a50
yarn i18n 2023-03-27 17:24:24 -05:00
Alex Gleason d39e2cc7e0
UnapprovedAccount: use countdown, remove rejectUserModal 2023-03-27 17:14:22 -05:00
Alex Gleason 0522f333c3
Make follow requests use AuthorizeRejectButtons countdown 2023-03-27 17:13:44 -05:00
Alex Gleason 22474e3ca9
MembershipRequest: add 3s countdown on authorize/reject actions 2023-03-27 17:09:10 -05:00
Alex Gleason f216b52b36
AuthorizeRejectButtons: skip animations if countdown is undefined 2023-03-27 17:08:24 -05:00
Alex Gleason 09ed0bccab
AuthorizeRejectButtons: refactor ActionEmblem into a separate component 2023-03-27 17:03:19 -05:00
Alex Gleason 63394bb1b4
AuthorizeRejectButtons: refactor button into a separate component 2023-03-27 16:59:55 -05:00
Alex Gleason d08a2e215b
AuthorizeRejectButtons: add a loading animation 2023-03-27 16:45:41 -05:00
Alex Gleason 3b8f43f02d
AuthorizeRejectButtons: fix onReject never being called 2023-03-27 15:36:55 -05:00
Alex Gleason 9367b16200
AuthorizeRejectButtons: swap out icon during action countdown 2023-03-27 15:34:02 -05:00
Alex Gleason 6f705a827e
AuthorizeRejectButtons: add countdown functionality 2023-03-27 15:31:13 -05:00
Chewbacca ff5eb736fc Merge branch 'report-group' into 'develop'
Add ability to report a Group

See merge request soapbox-pub/soapbox!2375
2023-03-27 18:06:35 +00:00
marcin mikołajczak f6cee79c0e lint
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-03-26 21:58:46 +02:00
marcin mikołajczak bf8c454c23 Update en.json
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-03-25 23:18:38 +01:00
marcin mikołajczak 12f3b4fbc3 Support Friendica dislikes, quotes
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-03-25 23:16:40 +01:00
marcin mikołajczak 4bee42f86d Update changelog
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-03-25 12:15:56 +01:00
marcin mikołajczak 96a8bcdf82 Friendica dislikes
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-03-25 12:14:53 +01:00
marcin mikołajczak a45be78b97 Merge branch 'friendica' into 'develop'
Update features.ts for Friendica

See merge request soapbox-pub/soapbox!2380
2023-03-25 10:59:06 +00:00
marcin mikołajczak 4990e1eaa7 Check version for Friendica features
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-03-25 10:02:21 +01:00
marcin mikołajczak 52172c923f Actually fix version parsing for Friendica
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-03-25 09:43:27 +01:00
marcin mikołajczak 01359ca592 Update features.ts for Friendica
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-03-25 09:01:58 +01:00
Alex Gleason 7c1182bfb3 Merge branch 'entity-request' into 'develop'
EntityStore: refactor all hooks to use callbacks

See merge request soapbox-pub/soapbox!2379
2023-03-24 14:44:47 +00:00
Alex Gleason 818b10efc3
Remove stray whitespace 2023-03-23 19:24:20 -05:00
Alex Gleason a530ec0202
EntityStore: switch all hooks to use a callback function 2023-03-23 19:22:26 -05:00
Alex Gleason 9d12173b87
Add useLoading hook 2023-03-23 18:44:44 -05:00
Alex Gleason aa7e2f6965
Refactor hooks with useEntityRequest 2023-03-23 16:22:15 -05:00
Alex Gleason 45c12e9b65
Make EntityCallbacks a generic function 2023-03-23 16:09:04 -05:00
Alex Gleason 7248331742
Add useEntityRequest hook 2023-03-23 16:04:42 -05:00
Alex Gleason ac9718e6ed
Return isLoading from useCreateEntity and useDeleteEntity 2023-03-23 15:30:45 -05:00
Alex Gleason 1b569b6c82
useEntity: accept an EntityRequest object 2023-03-23 15:15:04 -05:00
Alex Gleason b4c3248791
useEntityActions: fix isLoading 2023-03-23 15:09:00 -05:00
Alex Gleason 1c5a6d8b41
useDeleteEntity: refactor with EntityRequest 2023-03-23 15:05:34 -05:00
Alex Gleason 50f65bc7c9
useCreateEntity: pass an EntityRequest, refactor 2023-03-23 14:52:38 -05:00
Chewbacca 30ef70440f Add ability to report a Group 2023-03-23 15:17:44 -04:00
Alex Gleason ad3f8acbe5
EntityStore: allow passing an EntityRequest object to useEntities 2023-03-23 14:14:53 -05:00
Alex Gleason 948d66bcab Merge branch 'group-requests' into 'develop'
Groups: improve pending memberships, standardize "authorize/reject" buttons throughout the UI

See merge request soapbox-pub/soapbox!2370
2023-03-23 17:05:14 +00:00
Alex Gleason 4783a41b78
useDeleteEntity: support onSuccess callback 2023-03-23 10:45:49 -05:00
Alex Gleason 1949651b9a
Merge remote-tracking branch 'origin/develop' into group-requests 2023-03-23 10:23:06 -05:00
Alex Gleason 75b0262f9a
Move pendingCount logic to useEntities 2023-03-22 21:28:48 -05:00
Alex Gleason 2674c060ad
GroupMembers: showLoading if pending members are being fetched 2023-03-22 20:26:53 -05:00
Alex Gleason 6929975aaa
useIncrementEntity: fix optimistic counter 2023-03-22 19:58:40 -05:00
Alex Gleason 402daec9c3
Add useIncrementEntity hook 2023-03-22 19:45:34 -05:00
Alex Gleason c5b1f23bda
GroupMembers: use X-Total-Count if available 2023-03-22 19:22:12 -05:00
Alex Gleason c4d0dd568e
EntityStore: let totalCount be undefined, don't try to set it from the local count 2023-03-22 19:11:11 -05:00
Alex Gleason f016ac1e6d
GroupMembershipRequests: invalidate query upon authorize/reject 2023-03-22 18:48:24 -05:00
Alex Gleason cb8363d179
EntityStore: make fetching the first page override the old list 2023-03-22 18:47:10 -05:00
Alex Gleason e2510489c5
EntityStore: support query invalidation 2023-03-22 18:17:28 -05:00
Alex Gleason a256665aad
EntityStore: add support for X-Total-Count from the API 2023-03-22 17:39:58 -05:00
Alex Gleason 1eed61c386
GroupMembershipRequests: don't clear dismissed entries until new content is fetched 2023-03-22 16:42:08 -05:00
Alex Gleason b47cdb368f
useGroupMembershipRequests: use useDismissEntity hooks 2023-03-22 16:31:49 -05:00
Alex Gleason 61fb434a54
Improve API of parseEntitiesPath 2023-03-22 16:12:05 -05:00
Alex Gleason 8f67d2c76f
EntityStore: consolidate types, fix type of "path" 2023-03-22 16:06:10 -05:00
Alex Gleason d2fd9e0387
Export new entity hooks 2023-03-22 15:32:56 -05:00
Alex Gleason b127025167
Move useCreateEntity into its own hook as well, because why not 2023-03-22 15:31:58 -05:00
Alex Gleason b76559f24a
Add useDismissEntity hook, update useDeleteEntity to match 2023-03-22 14:40:18 -05:00
Alex Gleason 3d72e6305f
EntityStory: add dismissEntities action for deleting ids from a list 2023-03-22 14:34:10 -05:00
Alex Gleason 4049de50aa
Add separate useDeleteEntity hook accepting a callback 2023-03-22 14:08:08 -05:00
Alex Gleason ee1b1b4397
GroupMembers: fix pending row borders and dark mode 2023-03-22 13:47:18 -05:00
Alex Gleason 1954848c65
Tabs: vertically center the counter 2023-03-22 13:23:45 -05:00
Alex Gleason 71c7c4adc7 Merge branch 'group-widgets' into 'develop'
Add MyGroupsPanel, improve layout on various group pages

See merge request soapbox-pub/soapbox!2374
2023-03-22 16:03:02 +00:00
Alex Gleason cc2fbc0208 Merge branch 'redirect-group-posts' into 'develop'
Redirect group statuses to a custom path

See merge request soapbox-pub/soapbox!2371
2023-03-22 16:02:58 +00:00
Chewbacca f7a964e6ee Merge branch 'delete-group' into 'develop'
Add hook to delete Group

See merge request soapbox-pub/soapbox!2369
2023-03-22 15:58:27 +00:00
Chewbacca 32ca5f09ee I18n 2023-03-22 11:23:35 -04:00
Chewbacca ad98bf45cc Add hook to delete Group 2023-03-22 11:20:03 -04:00
Alex Gleason 65070f6519
Add MyGroupsPanel, improve layout on various group pages 2023-03-21 16:34:15 -05:00
Alex Gleason ec72ac0db8
yarn i18n 2023-03-21 16:09:40 -05:00
Alex Gleason be32a0c1a0
Textarea: add a character counter 2023-03-21 15:39:08 -05:00
Alex Gleason 69d667d6c6
"Authorized" --> "Approved" 2023-03-21 11:56:48 -05:00
Alex Gleason be7a462fc4 Merge branch 'edit-group-fixes' into 'develop'
Edit group fixes

See merge request soapbox-pub/soapbox!2372
2023-03-21 03:16:08 +00:00
Alex Gleason f61e0d889a
"Blocked members" --> "Banned members" 2023-03-20 21:56:15 -05:00
Alex Gleason cc3585f319
Manage group: add headers 2023-03-20 21:52:44 -05:00
Alex Gleason f369a7c765
Use "danger" text for deleting account and group 2023-03-20 21:42:54 -05:00
Alex Gleason a8be701ea0
Fix PendingGroupsRow test 2023-03-20 21:31:07 -05:00
Alex Gleason 2196d9e3e5
yarn i18n 2023-03-20 21:23:10 -05:00
Alex Gleason fb8d543f7c
Redirect group statuses to a custom path 2023-03-20 20:57:49 -05:00
Alex Gleason b87af6a71c
AuthorizeRejectButtons: fix styles, make less fragile 2023-03-20 20:11:21 -05:00
Alex Gleason 3a12b316d9
GroupPage: add pending members counter 2023-03-20 20:02:58 -05:00
Alex Gleason 9ca384dcd7
Card: fix back button not having a rounded border 2023-03-20 19:37:46 -05:00
Alex Gleason 4f5866d43f
CHANGELOG: authorize/reject buttons 2023-03-20 19:33:29 -05:00
Alex Gleason 5774516ea0
Reorganize GroupMembershipRequests a little 2023-03-20 19:32:24 -05:00
Alex Gleason d4e9fddd02
Update usage of AuthorizeRejectButtons in group membership requests 2023-03-20 19:24:06 -05:00
Alex Gleason 7a06c7f92c
Use AuthorizeReject buttons for follow requests 2023-03-20 19:23:11 -05:00
Alex Gleason 28f5a88848
Use AuthorizeReject buttons for account approval 2023-03-20 19:22:55 -05:00
Alex Gleason 4de8926445
IAuthorizeRejectButtons: simplify component 2023-03-20 19:22:00 -05:00
Alex Gleason f9ab9a45c2
AuthorizeRejectButtons: improve style of result message 2023-03-20 18:49:41 -05:00
Alex Gleason fe64f9f84b
AuthorizeRejectButtons: improve button styles 2023-03-20 18:35:31 -05:00
Alex Gleason 7c7855e7a1
Groups: make authorize/reject use component state, update designs 2023-03-20 17:46:10 -05:00
Alex Gleason 1d9ed41fec
Add AuthorizeRejectButtons component 2023-03-20 17:45:52 -05:00
marcin mikołajczak 282afaa47f Merge branch 'use-groups-condition' into 'develop'
Do not make requests to api/v1/groups if feature not available

See merge request soapbox-pub/soapbox!2363
2023-03-20 21:57:35 +00:00
marcin mikołajczak 7329c0bf25 Do not make requests to api/v1/groups if fffeature not available
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-03-20 22:42:27 +01:00
Alex Gleason ca9a41f102
Use EntityStore for pending group requests 2023-03-20 16:41:12 -05:00
Chewbacca babaa979f5 Merge branch 'move-mutations-to-entities' into 'develop'
Move Group mutations to entities

See merge request soapbox-pub/soapbox!2368
2023-03-20 21:35:37 +00:00
Alex Gleason 143a9eda44
Use PendingItemsRow for pending members, pass a prop to control its size 2023-03-20 16:26:40 -05:00
Alex Gleason f6b28dd9c3
Abstract PendingItemsRow into its own component 2023-03-20 16:09:19 -05:00
Alex Gleason 3c06ba734b
Display pending counter in group member list 2023-03-20 16:03:41 -05:00
Alex Gleason d08178f5fc
Groups: use entity store for pending requests 2023-03-20 15:54:06 -05:00
Alex Gleason 28a69ad88b
Ensure group_visibility param is passed when creating group 2023-03-20 15:30:13 -05:00
Chewbacca e46a7e8f4a Merge branch 'promote-to-admin' into 'develop'
Move Promote/Demote admin into entity store

See merge request soapbox-pub/soapbox!2359
2023-03-20 20:08:51 +00:00
Chewbacca 8b478c939a Revert change 2023-03-20 16:08:29 -04:00
Alex Gleason 396f6ada1a Merge branch 'emoji-floating-ui' into 'develop'
Emoji floating ui

Closes #1390 and #1398

See merge request soapbox-pub/soapbox!2367
2023-03-20 20:03:41 +00:00
Chewbacca e42e0577f4 Move Group mutations to entities 2023-03-20 15:41:18 -04:00
Chewbacca 4a6433433f Update translations 2023-03-20 15:41:12 -04:00
Chewbacca 4985db7dea Update group roles to owner/admin/user 2023-03-20 15:41:12 -04:00
Chewbacca 89bdc9b4a1 Move Promote/Demote admin into entity store 2023-03-20 15:41:12 -04:00
Alex Gleason ea4f707413
Fix offset of chat reaction wrapper 2023-03-20 13:57:29 -05:00
Alex Gleason bc457b61d1 Merge branch 'edit-group' into 'develop'
Edit group

See merge request soapbox-pub/soapbox!2357
2023-03-20 18:41:52 +00:00
Alex Gleason f8b20858a3
Chats: fix crash in emoji autosuggest 2023-03-19 19:59:46 -05:00
Alex Gleason 67ffe9609f
ChatTextarea: pass ref to child
Fixes https://gitlab.com/soapbox-pub/soapbox/-/issues/1390
2023-03-19 18:03:44 -05:00
Alex Gleason 47561e5c01
Enable custom emoji reacts on custom Pleroma forks 2023-03-19 17:53:14 -05:00
Alex Gleason 5c7c0ea1dd
EmojiSelector: switch to floating-ui 2023-03-19 17:52:45 -05:00
Alex Gleason 2b75dcacd2
EmojiPickerDropdownContainer: switch to floating-ui 2023-03-19 17:24:39 -05:00
Alex Gleason 9dc12f0994 Merge branch 'changelog' into 'develop'
Update CHANGELOG

See merge request soapbox-pub/soapbox!2365
2023-03-19 20:48:02 +00:00
Alex Gleason f7c7b6ce6c
Update CHANGELOG 2023-03-19 15:47:40 -05:00
Alex Gleason da7284212e Merge branch 'group-svg' into 'develop'
Delete proprietary groups image

See merge request soapbox-pub/soapbox!2364
2023-03-19 20:40:34 +00:00
Alex Gleason 813fd7f8ee
Delete proprietary groups image 2023-03-19 15:39:58 -05:00
marcin mikołajczak b62db891fe Merge branch 'mkljczk-develop-patch-27878' into 'develop'
Update CHANGELOG.md

See merge request soapbox-pub/soapbox!2362
2023-03-19 20:15:28 +00:00
marcin mikołajczak 9c80a50b95 Merge branch 'pending-status-gap' into 'develop'
Add missing gap to PendingStatus

See merge request soapbox-pub/soapbox!2361
2023-03-19 19:50:27 +00:00
marcin mikołajczak 8634c5f91e Update CHANGELOG.md 2023-03-19 19:26:17 +00:00
marcin mikołajczak 049554db84 Add missing gap to PendingStatus
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-03-19 20:23:36 +01:00
marcin mikołajczak 4124b85ede Merge branch 'custom-emoji-reacts' into 'develop'
Support custom emoji reacts

See merge request soapbox-pub/soapbox!2360
2023-03-19 19:03:53 +00:00
marcin mikołajczak 38c99dbc48 Add tests from custom reacts
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-03-19 19:22:05 +01:00
marcin mikołajczak 09a0a36935 Update tests
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-03-18 13:27:27 +01:00
marcin mikołajczak 179eb7fc99 Fix preview in reactions modal
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-03-18 11:55:00 +01:00
marcin mikołajczak 8b81838f2f Support custom emoji reacts
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-03-18 00:07:18 +01:00
Alex Gleason c0a22205f7
Fix GroupActionButton test 2023-03-17 16:14:23 -05:00
Alex Gleason 3a94736285 Merge branch 'store-optimistic-delete' into 'develop'
EntityStore: optimistic deletion

See merge request soapbox-pub/soapbox!2356
2023-03-17 20:40:55 +00:00
Alex Gleason e6621a802b
Make popular and suggested groups share the Group store 2023-03-16 13:18:36 -05:00
Alex Gleason 181bf23c34
Importer: use EntityStore enums 2023-03-16 13:15:00 -05:00
Alex Gleason c51870af6e
Update some more groups stuff to use entities 2023-03-15 19:26:37 -05:00
Alex Gleason 1518e88904
Retrofit old Group actions to EntityStore 2023-03-15 18:37:50 -05:00
Alex Gleason 5871abd786
Make "Manage Group" use the EntityStore 2023-03-15 17:59:37 -05:00
Alex Gleason 7fffe59fb9
Allow "owner" permissions on group pages 2023-03-15 17:26:07 -05:00
Alex Gleason 1ab9b1d75c
EntityStore: optimistic deletion 2023-03-15 16:52:09 -05:00
Chewbacca 709edaefad Merge branch 'block-group-members' into 'develop'
Use Entity Hooks for Blocking Group members

See merge request soapbox-pub/soapbox!2353
2023-03-15 20:42:40 +00:00
Chewbacca 41ab40485e Merge branch 'renovate/floating-ui-react-0.x' into 'develop'
fix(deps): update dependency @floating-ui/react to ^0.21.0

See merge request soapbox-pub/soapbox!2348
2023-03-15 20:42:27 +00:00
Alex Gleason a83cfe7ddd Merge branch 'entity-actions-delete' into 'develop'
useEntityActions: ensure the delete gets dispatched

See merge request soapbox-pub/soapbox!2354
2023-03-15 20:08:51 +00:00
Chewbacca 0fe48840e1 Merge branch 'popovers' into 'develop'
Add Popovers component

See merge request soapbox-pub/soapbox!2352
2023-03-15 20:06:50 +00:00
Alex Gleason 74ebd560e6
Revert useEntity array changes, do that in the schema parser 2023-03-15 14:19:13 -05:00
Alex Gleason 602a670b2e
useEntityActions: ensure the delete gets dispatched 2023-03-15 14:04:29 -05:00
Alex Gleason 79aa8e210f Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2350
2023-03-15 19:02:36 +00:00
Chewbacca 6b30671875 Add Account entity and improve Block/Ban support for Groups 2023-03-15 14:55:43 -04:00
Chewbacca a99a7b2af5 Improve focus design for Danger buttons 2023-03-15 14:55:43 -04:00
Chewbacca 9dde71716f Improve DropdownMenu API 2023-03-15 14:55:43 -04:00
Chewbacca 20ccd26a6e Update Entity Store with bug fixes 2023-03-15 14:55:43 -04:00
Chewbacca 283935e837 Add popover component 2023-03-15 14:55:26 -04:00
gallegonovato bbda49a31c
Translated using Weblate (Spanish)
Currently translated at 100.0% (1520 of 1520 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/es/
2023-03-15 19:55:03 +01:00
Poesty Li 471f275dcb
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1520 of 1520 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-03-15 19:55:03 +01:00
Hosted Weblate c5a548fa83
Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/
2023-03-15 19:55:03 +01:00
Poesty Li e28e12cd60
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1520 of 1520 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-03-15 19:55:03 +01:00
gallegonovato c9bd4291bb
Translated using Weblate (Spanish)
Currently translated at 100.0% (1520 of 1520 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/es/
2023-03-15 19:55:03 +01:00
Chewbacca af69c7564e Merge branch 'group-avatar-ring' into 'develop'
Add GroupAvatar component

See merge request soapbox-pub/soapbox!2349
2023-03-15 18:54:47 +00:00
Alex Gleason 822ab987a1 Merge branch 'create-group-hook' into 'develop'
Add useEntityActions hooks

See merge request soapbox-pub/soapbox!2351
2023-03-15 18:54:28 +00:00
Alex Gleason 463dcd2c1e
Merge remote-tracking branch 'origin/develop' into create-group-hook 2023-03-14 14:56:46 -05:00
Chewbacca c6c12fa60f Merge branch 'group-composer' into 'develop'
Update Group Members to use Entity Store

See merge request soapbox-pub/soapbox!2342
2023-03-14 19:31:52 +00:00
Alex Gleason ac76af41b2
Add preliminary useEntityActions hook 2023-03-14 14:24:11 -05:00
Chewbacca c8a4d63fc8 Add GroupAvatar component 2023-03-14 15:17:05 -04:00
Chewbacca 7070630eaf useVersion -> useBackend 2023-03-14 15:16:01 -04:00
Chewbacca 821b90c372 Add pages for Popular / Suggested Groups 2023-03-14 15:16:01 -04:00
Chewbacca 1b542c3ed7 Use Entities enum 2023-03-14 15:16:01 -04:00
Chewbacca f4d2f42c01 Use new schema arg 2023-03-14 15:16:01 -04:00
Chewbacca 7be8218f0c Convert popular/suggested Groups to use Entities 2023-03-14 15:16:01 -04:00
Alex Gleason 50dadeb1b8 useEntities: support multiple list keys 2023-03-14 15:16:01 -04:00
Chewbacca 99b7a1bdd7 Fix i18n 2023-03-14 15:16:01 -04:00
Chewbacca 1d53f48904 Fix parser 2023-03-14 15:16:01 -04:00
Chewbacca 9d1c2df1a2 Use ZOD for group-members 2023-03-14 15:16:00 -04:00
Chewbacca 08f97a133e Update blankslate for Group Timeline 2023-03-14 15:15:26 -04:00
Chewbacca 8a36561ec8 Use entities with Group Members 2023-03-14 15:15:26 -04:00
Alex Gleason 11d06e6b6e useEntities: support multiple list keys 2023-03-14 15:15:26 -04:00
Alex Gleason 8f8807eb76
EntityStore: allow deleting entities 2023-03-14 14:14:48 -05:00
Soapbox Bot 3b1f1cf789 Update dependency @floating-ui/react to ^0.21.0 2023-03-14 18:09:10 +00:00
Chewbacca 7e74e215cc Merge branch 'fix-export' into 'develop'
Fix exporting of types

See merge request soapbox-pub/soapbox!2347
2023-03-14 17:50:06 +00:00
Alex Gleason fafd27d79a Merge branch 'renovate/fork-ts-checker-webpack-plugin-8.x' into 'develop'
Update dependency fork-ts-checker-webpack-plugin to v8

See merge request soapbox-pub/soapbox!2335
2023-03-14 17:33:32 +00:00
Chewbacca 3ca168dc8c Fix exporting of types 2023-03-14 13:10:00 -04:00
Alex Gleason 6ac57910bf Merge branch 'groupschema-tests' into 'develop'
Add group factory functions for tests, add a groupSchema test

See merge request soapbox-pub/soapbox!2344
2023-03-14 14:16:05 +00:00
Chewbacca e173418041 Merge branch 'update-group-comps' into 'develop'
Update Group component with Join buttons

See merge request soapbox-pub/soapbox!2330
2023-03-14 14:13:46 +00:00
Chewbacca 39d61eabda Merge branch 'entity-store-refactoring' into 'develop'
Entity store refactoring (improve performance, etc)

See merge request soapbox-pub/soapbox!2346
2023-03-14 14:12:14 +00:00
Alex Gleason 9df2bb4a86
EntityStore: add tests for reducer, improve types, ensure error gets added to state 2023-03-13 18:42:46 -05:00
Alex Gleason b93a299009
useEntities(): refactor into smaller performant selectors and hooks 2023-03-13 17:53:54 -05:00
Alex Gleason 8547aeb517
Add useGetState hook 2023-03-13 17:45:35 -05:00
marcin mikołajczak 8c6ce74c46 Merge branch 'fix-locale-parser' into 'develop'
Fix locale parser

Closes #1393

See merge request soapbox-pub/soapbox!2343
2023-03-13 22:27:22 +00:00
Alex Gleason a19b1e83a9
EntityStore: parse entities after fetch, not during render (performance) 2023-03-13 16:39:23 -05:00
Alex Gleason e9ae8d2c45
Fix filteredArray logic 2023-03-13 16:37:40 -05:00
Alex Gleason d0ceac9987
Pass zodSchema directly to entity hooks for safeParse validation 2023-03-13 16:23:11 -05:00
Alex Gleason d12078a687
Use group factory functions in tests instead of normalizers 2023-03-13 14:55:59 -05:00
marcin mikołajczak 61ece4d271 Merge remote-tracking branch 'takver/fix-locale-parser' into fix-locale-parser
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-03-13 20:44:09 +01:00
Chewbacca bced3d6632 Merge branch 'pending-groups' into 'develop'
Add support for pending Group Requests

See merge request soapbox-pub/soapbox!2327
2023-03-13 19:20:16 +00:00
Chewbacca 879ac883aa Merge branch 'my-groups-blankslate' into 'develop'
Update blankslate to allow Group Creation

See merge request soapbox-pub/soapbox!2326
2023-03-13 19:10:14 +00:00
Soapbox Bot fadceaac45 fix(deps): update dependency fork-ts-checker-webpack-plugin to v8 2023-03-13 19:08:19 +00:00
Alex Gleason d747e323c6
Add basic groupSchema test 2023-03-13 14:03:50 -05:00
Alex Gleason c3728dbddd Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2336
2023-03-13 18:29:09 +00:00
Alex Gleason 1922e889f7 Merge branch 'create-group' into 'develop'
Create group

See merge request soapbox-pub/soapbox!2325
2023-03-13 18:28:43 +00:00
Chewbacca 58527b0656 Update Group component with Join buttons 2023-03-13 14:27:35 -04:00
Chewbacca 737c43d847 Fix i18n 2023-03-13 14:27:21 -04:00
Chewbacca f21f72461a Add support for pending Group Requests 2023-03-13 14:27:21 -04:00
Chewbacca 83532aedba Update blankslate to allow Group Creation 2023-03-13 14:27:21 -04:00
Chewbacca cced90a780 Update blankslate to allow Group Creation 2023-03-13 14:26:42 -04:00
Poesty Li 466cf91b31
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1508 of 1508 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-03-13 19:08:29 +01:00
Hosted Weblate c3dd9515bf
Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/
2023-03-13 19:08:29 +01:00
Poesty Li bd7710677f
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1502 of 1502 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-03-13 19:08:28 +01:00
gallegonovato 8baecde992
Translated using Weblate (Spanish)
Currently translated at 100.0% (1502 of 1502 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/es/
2023-03-13 19:08:28 +01:00
Hosted Weblate 43a204db50
Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/
2023-03-13 19:08:28 +01:00
Alex Gleason a40222c2de Merge branch 'groups-zod' into 'develop'
Groups zod

See merge request soapbox-pub/soapbox!2338
2023-03-13 18:08:16 +00:00
Alex Gleason 607e6b1808
groupsSchema: refine --> transform 2023-03-13 12:05:56 -05:00
Chewbacca a9b79f72b4 Revert "Fix useGroupsPath test"
This reverts commit 487604b15a.
2023-03-13 13:02:41 -04:00
Chewbacca a0c67c9b6f Fix Zod parsing error 2023-03-13 13:02:37 -04:00
Alex Gleason 487604b15a
Fix useGroupsPath test 2023-03-13 11:54:22 -05:00
Alex Gleason 5278c8eb0f
Merge remote-tracking branch 'origin/develop' into groups-zod 2023-03-13 11:05:21 -05:00
Chewbacca 55bacbbf05 Merge branch 'group-actions' into 'develop'
Group actions

See merge request soapbox-pub/soapbox!2324
2023-03-13 16:01:34 +00:00
Chewbacca a71aaca719 Fix translations 2023-03-13 11:36:08 -04:00
Chewbacca bd4c99b697 Fix tests 2023-03-13 11:36:08 -04:00
Chewbacca 7ad2696f85 Move Join / Leave / Cancel group/request to mutations 2023-03-13 11:36:08 -04:00
Chewbacca 287fda6d6c Improve error handling for Groups Discover page 2023-03-13 11:36:08 -04:00
Chewbacca e7b3af5260 Merge branch 'fix-tests' into 'develop'
Fix mock in tests

See merge request soapbox-pub/soapbox!2341
2023-03-13 15:35:40 +00:00
Chewbacca 82da9ceeeb Fix mock in tests 2023-03-13 10:07:23 -04:00
marcin mikołajczak 5148d913a7 Merge branch 'follow-requests-styles' into 'develop'
Fix: Long handles don't get truncated in Follow Requests menu

Closes #1389

See merge request soapbox-pub/soapbox!2340
2023-03-13 11:10:27 +00:00
marcin mikołajczak ea6be269bb Fix: Long handles don't get truncated in Follow Requests menu
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-03-13 00:00:07 +01:00
Alex Gleason ef10e2a699 Merge branch 'test-fixes' into 'develop'
Upgrade testing-library deps for sanity, fix DurationSelector time logic, comment out 2 failing tests

See merge request soapbox-pub/soapbox!2339
2023-03-10 23:00:11 +00:00
Alex Gleason ccec7f43e5
DurationSelector: actually, don't even do weird date stuff at all, LOL 2023-03-10 15:07:25 -06:00
Alex Gleason bd49417210
Also, fix the variable names in DurationSelector 2023-03-10 15:04:44 -06:00
Alex Gleason 2b137c12cf
Comment out failing tests ¯\_(ツ)_/¯ 2023-03-10 15:00:53 -06:00
Alex Gleason de89a438cc
Make DurationSelector test work locally 2023-03-10 15:00:29 -06:00
Alex Gleason 4031e4624c
Upgrade testing-library deps for sanity 2023-03-10 15:00:21 -06:00
Alex Gleason 1af67c3a25
members_count will never be null 2023-03-10 13:46:20 -06:00
Alex Gleason 6a2c64ae45
groupSchema: catch emojis 2023-03-10 13:41:47 -06:00
Alex Gleason 3d2331d20b
Make useGroups hooks use zod parser, update group types 2023-03-10 13:36:00 -06:00
Alex Gleason 5e8c92ed4d
groupSchema: refine --> transform, fix type of members_count 2023-03-10 13:13:54 -06:00
Alex Gleason 6be8d4d46e
Add groups schemas with zod 2023-03-10 12:42:49 -06:00
Alex Gleason 37f5b35aab
Add zod 2023-03-10 11:35:18 -06:00
Alex Gleason a0c1bd84c9 Merge branch 'group-entities' into 'develop'
EntityStore: Groups

See merge request soapbox-pub/soapbox!2333
2023-03-10 17:22:55 +00:00
Alex Gleason cf541e83b3
Fix useGroupsPath test 2023-03-10 10:56:00 -06:00
marcin mikołajczak b1471be142 Merge branch 'filters-v2' into 'develop'
filters v2

See merge request soapbox-pub/soapbox!2321
2023-03-10 11:03:46 +00:00
marcin mikołajczak 51524118d4 Merge branch 'gallery-load-more' into 'develop'
Fix load more button height on account gallery page

See merge request soapbox-pub/soapbox!2318
2023-03-10 10:52:00 +00:00
Alex Gleason c55154daaf Merge branch 'renovate/testing-library-react-14.x' into 'develop'
Update dependency @testing-library/react to v14

See merge request soapbox-pub/soapbox!2332
2023-03-10 01:46:02 +00:00
Alex Gleason 00c00b31fc Merge branch 'compareDate' into 'develop'
Sort conversations by last status date rather than id

See merge request soapbox-pub/soapbox!2319
2023-03-10 01:45:18 +00:00
Alex Gleason 074c3429cd Merge branch 'develop-patch-51d8' into 'develop'
Dictate Pleroma Chat and Quote Post compatibility by advertised features in the api

See merge request soapbox-pub/soapbox!2334
2023-03-10 01:41:46 +00:00
rurai10 29b75a29f0 Update file features.ts 2023-03-10 00:15:45 +00:00
Alex Gleason be9d922047
Actually, do put relationships in their own list. And fix parsers not doing the right thing. 2023-03-09 15:35:50 -06:00
Alex Gleason 14a84e557c
Update useGroups queries with EntityStore improvements 2023-03-09 15:05:54 -06:00
Alex Gleason fa2884c11b
EntityStore: fetch with useEntity automatically, accept refetch opt 2023-03-09 15:05:27 -06:00
marcin mikołajczak 1d64f934d9 Merge remote-tracking branch 'soapbox/develop' into filters-v2 2023-03-09 21:49:57 +01:00
Alex Gleason ad583c89f8
EntityStore: allow passing an undefined endpoint (to skip fetch), prevent race conditions in isFetching 2023-03-09 14:44:54 -06:00
marcin mikołajczak 94d248fb79 Update README.md
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-03-09 21:39:31 +01:00
Alex Gleason a3b1f541bc
EntityStore: support staleTime option (automatically fetch) 2023-03-09 14:20:04 -06:00
Alex Gleason d883f2f5bd
Group hooks: use new parser opt 2023-03-09 12:36:20 -06:00
Alex Gleason 250b009635
EntityStore: allow passing a parser function to parse the entities 2023-03-09 12:32:50 -06:00
Alex Gleason 9964491da5
First draft of GroupRelationship entity hooks 2023-03-09 11:47:24 -06:00
Alex Gleason 8923e7b5d0
Combine group hooks into one useGroups file 2023-03-09 11:24:53 -06:00
Alex Gleason 4c6d13e4ef
Use EntityStore for Groups 2023-03-09 11:21:27 -06:00
Soapbox Bot 31351700e0 Update dependency @testing-library/react to v14 2023-03-09 17:09:36 +00:00
Alex Gleason f2983b96fb Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2329
2023-03-09 17:08:09 +00:00
Alex Gleason c492af7042
Merge remote-tracking branch 'origin/develop' into entity-store 2023-03-09 10:43:58 -06:00
Tassoman ae1287ae82
Translated using Weblate (Italian)
Currently translated at 99.8% (1486 of 1488 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/it/
2023-03-09 17:37:54 +01:00
Alex Gleason 68144e4f82 Merge branch 'renovate/eslint-plugin-jsdoc-40.x' into 'develop'
Update dependency eslint-plugin-jsdoc to v40

See merge request soapbox-pub/soapbox!2323
2023-03-09 16:37:48 +00:00
Alex Gleason bed26727c1
yarn i18n 2023-03-09 10:16:04 -06:00
oakes 332be25784 Sort conversations by last status date rather than id 2023-03-09 10:49:59 -05:00
Alex Gleason a8b0dc93f2 Merge branch 'nostr' into 'develop'
Truncate Nostr pubkeys in reply mentions

See merge request soapbox-pub/soapbox!2328
2023-03-09 02:16:05 +00:00
Alex Gleason d1531b832d
Truncate Nostr pubkeys in reply mentions 2023-03-08 19:56:24 -06:00
Alex Gleason c75ce58792
Fix instance test 2023-03-08 14:50:15 -06:00
Alex Gleason 01343bbe0a
Add copy and share links to group confirmation step 2023-03-08 14:46:24 -06:00
Alex Gleason 2a9f05a765
Create Group: add info items to confirmation step 2023-03-08 14:10:09 -06:00
Alex Gleason d7f5e210d8
Groups: scaffold the confirmation step 2023-03-08 13:43:16 -06:00
Alex Gleason 925509a985
Fix groups modal bailing too soon 2023-03-08 12:20:20 -06:00
Alex Gleason 63df638630
Create Group: enforce max limit on description and name 2023-03-08 12:00:28 -06:00
Alex Gleason 08014a678d Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2293
2023-03-08 04:33:30 +00:00
gallegonovato b9ac2084c2
Translated using Weblate (Spanish)
Currently translated at 100.0% (1488 of 1488 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/es/
2023-03-08 00:38:28 +01:00
marcin mikołajczak d969c91c76 Update filter preview
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-03-08 00:02:17 +01:00
Poesty Li 334f93f2b1
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1488 of 1488 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-03-06 19:46:15 +01:00
Poesty Li 1d94d2ec9f
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1488 of 1488 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-03-06 19:46:15 +01:00
Poesty Li 57da9102cf
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1488 of 1488 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-03-06 19:46:15 +01:00
Hosted Weblate f9523d7afd
Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/
2023-03-06 19:46:15 +01:00
Poesty Li 050f4130bb
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1479 of 1479 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-03-06 19:46:15 +01:00
Isabell De Inschnitzel 3ef34b1695
Translated using Weblate (German)
Currently translated at 97.3% (1440 of 1479 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/de/
2023-03-06 19:46:15 +01:00
Poesty Li aca7bb63a5
Translated using Weblate (Chinese (Simplified))
Currently translated at 99.7% (1476 of 1479 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-03-06 19:46:14 +01:00
Hosted Weblate 41a1923ca5
Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/
2023-03-06 19:46:14 +01:00
marcin mikołajczak d2ca2da10a
Translated using Weblate (Polish)
Currently translated at 92.3% (1357 of 1470 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/pl/
2023-03-06 19:46:14 +01:00
Tassoman e7e3ef86a3
Translated using Weblate (Italian)
Currently translated at 100.0% (1470 of 1470 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/it/
2023-03-06 19:46:14 +01:00
Simen f2eaccf0f2
Translated using Weblate (Norwegian Bokmål)
Currently translated at 100.0% (1470 of 1470 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/nb_NO/
2023-03-06 19:46:14 +01:00
Simen e87bb3d0ae
Translated using Weblate (Norwegian Bokmål)
Currently translated at 79.5% (1169 of 1470 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/nb_NO/
2023-03-06 19:46:14 +01:00
ruine 4e9e85a60b
Translated using Weblate (Japanese)
Currently translated at 82.7% (1217 of 1470 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ja/
2023-03-06 19:46:14 +01:00
ruine 905c1a47ac
Translated using Weblate (Japanese)
Currently translated at 82.7% (1217 of 1470 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ja/
2023-03-06 19:46:14 +01:00
marcin mikołajczak 4e779742fc
Translated using Weblate (Polish)
Currently translated at 92.3% (1357 of 1470 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/pl/
2023-03-06 19:46:14 +01:00
Tassoman 3b3a7653b1
Translated using Weblate (Italian)
Currently translated at 100.0% (1470 of 1470 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/it/
2023-03-06 19:46:14 +01:00
Oukiki Saleh 1e6be8fa0f
Translated using Weblate (Arabic)
Currently translated at 99.3% (1460 of 1470 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ar/
2023-03-06 19:46:14 +01:00
Oukiki Saleh d6d7398576
Translated using Weblate (Arabic)
Currently translated at 99.1% (1458 of 1470 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ar/
2023-03-06 19:46:14 +01:00
Oukiki Saleh edf3b093af
Translated using Weblate (Arabic)
Currently translated at 93.3% (1372 of 1470 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ar/
2023-03-06 19:46:14 +01:00
gallegonovato 95f4aee356
Translated using Weblate (Spanish)
Currently translated at 100.0% (1470 of 1470 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/es/
2023-03-06 19:46:14 +01:00
Mr.Narsus f8e05013fd
Translated using Weblate (Arabic)
Currently translated at 91.9% (1351 of 1470 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ar/
2023-03-06 19:46:14 +01:00
Oukiki Saleh 08b59ea58f
Translated using Weblate (Arabic)
Currently translated at 91.9% (1351 of 1470 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ar/
2023-03-06 19:46:14 +01:00
Mr.Narsus 483aa96b33
Translated using Weblate (Arabic)
Currently translated at 89.3% (1313 of 1470 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ar/
2023-03-06 19:46:14 +01:00
Oukiki Saleh fce046df8f
Translated using Weblate (Arabic)
Currently translated at 89.3% (1313 of 1470 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ar/
2023-03-06 19:46:14 +01:00
Oukiki Saleh 5ab98da220
Translated using Weblate (Arabic)
Currently translated at 89.3% (1313 of 1470 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ar/
2023-03-06 19:46:13 +01:00
Mr.Narsus 4e8130667a
Translated using Weblate (Arabic)
Currently translated at 89.3% (1313 of 1470 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ar/
2023-03-06 19:46:13 +01:00
Mr.Narsus 725750ca7d
Translated using Weblate (Arabic)
Currently translated at 89.3% (1313 of 1470 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ar/
2023-03-06 19:46:13 +01:00
Oukiki Saleh 3f13f8e370
Translated using Weblate (Arabic)
Currently translated at 89.3% (1313 of 1470 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ar/
2023-03-06 19:46:13 +01:00
Tassoman 605ea95ee4
Translated using Weblate (Italian)
Currently translated at 98.2% (1445 of 1470 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/it/
2023-03-06 19:46:13 +01:00
Oukiki Saleh f9541b5c52
Translated using Weblate (Arabic)
Currently translated at 88.2% (1297 of 1470 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ar/
2023-03-06 19:46:13 +01:00
Poesty Li 63a42aac67
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1470 of 1470 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-03-06 19:46:13 +01:00
Poesty Li fb1c36b1c8
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1470 of 1470 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-03-06 19:46:13 +01:00
Alex Gleason ca9e59b56b Merge branch 'chat-multi-upload' into 'develop'
Chats: allow uploading multiple attachments at once (if the backend supports it)

See merge request soapbox-pub/soapbox!2313
2023-03-06 18:46:01 +00:00
Alex Gleason 65d1c66aad
Add group icon to create screen 2023-03-06 12:42:13 -06:00
Alex Gleason d16bce0ecc
Merge remote-tracking branch 'origin/develop' into create-group 2023-03-06 12:10:06 -06:00
Chewbacca 4e2213aba8 Merge branch 'my-groups' into 'develop'
Add Trending and Suggested Groups to discovery

See merge request soapbox-pub/soapbox!2312
2023-03-06 16:44:11 +00:00
Chewbacca 721b5dafcd Merge branch 'group-search' into 'my-groups'
Add support for Group search

See merge request soapbox-pub/soapbox!2314
2023-03-06 16:25:07 +00:00
Chewbacca 31653a5a54 Merge branch 'default-group-tabs' into 'group-search'
Use Groups Discovery if user has no groups

See merge request soapbox-pub/soapbox!2317
2023-03-06 16:04:44 +00:00
Chewbacca bdaf6e4cd6 Merge branch 'group-profile-header' into 'default-group-tabs'
Improve Group Header with latest designs

See merge request soapbox-pub/soapbox!2320
2023-03-06 15:45:42 +00:00
Soapbox Bot 266dd3d110 Update dependency eslint-plugin-jsdoc to v40 2023-03-06 05:10:38 +00:00
Alex Gleason a8c4be01ec Merge branch 'renovate/floating-ui-react-0.x' into 'develop'
Update dependency @floating-ui/react to ^0.20.0

See merge request soapbox-pub/soapbox!2322
2023-03-06 04:38:17 +00:00
marcin mikołajczak 1d4d9c2732 Filters expiration, restyle filters list, fix keywords deletion
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-03-05 19:49:40 +01:00
Soapbox Bot 3c336cbeb4 Update dependency @floating-ui/react to ^0.20.0 2023-03-05 11:05:00 +00:00
marcin mikołajczak b54a466bfd Merge branch 'update-emoji-mart-2' into 'develop'
Update emoji mart

See merge request soapbox-pub/soapbox!2309
2023-03-05 10:05:08 +00:00
marcin mikołajczak af314ee55d Allow editing filters
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-03-04 21:22:59 +01:00
marcin mikołajczak ebe4f9373b Remove console.log
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-03-04 12:44:04 +01:00
marcin mikołajczak 4c92f581c4 Allow creating v2 filters
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-03-04 12:43:27 +01:00
marcin mikołajczak 4200fa2df4 filters v2
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-03-03 22:40:39 +01:00
marcin mikołajczak c9f2cc0ae2 Hide emoji-mart preview footer
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-03-02 23:38:17 +01:00
marcin mikołajczak 1f6328c9c6 Fix emoji picker button color
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-03-02 23:35:56 +01:00
Chewbacca 3cc4f8b64b Improve Group Header with latest designs 2023-03-02 14:42:45 -05:00
Alex Gleason 55c8887a08
Small design tweaks for create group modal 2023-03-02 12:17:25 -06:00
Alex Gleason d3d363e12f
Allow all permissions if unset 2023-03-02 10:28:31 -06:00
marcin mikołajczak 2ce98055d8 Fix load more button height on account gallery page
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-03-01 21:02:04 +01:00
marcin mikołajczak eb93cb39fd Fix emoji selector on touchscreen
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-03-01 20:27:16 +01:00
Chewbacca 8fd3b99887 Use Groups Discovery if user has no groups 2023-03-01 14:16:09 -05:00
Chewbacca 01dfbad7bc Add i18n keys to en.json 2023-03-01 11:18:35 -05:00
Chewbacca 0b7a2ac19b Add support for i18n in Group Search 2023-03-01 10:40:07 -05:00
Chewbacca d6d7807807 Add tests for RecentSearches 2023-03-01 09:43:30 -05:00
Alex Gleason aad7df89a5 Merge branch 'pagination' into 'develop'
Fix conversation list pagination

See merge request soapbox-pub/soapbox!2316
2023-02-28 20:42:26 +00:00
oakes f1a14efc58 Remove unnecessary equality test 2023-02-28 15:30:01 -05:00
oakes 1b00de14a6 Fix conversation list pagination 2023-02-28 15:24:04 -05:00
Chewbacca 5acc231cda Add tests for Search component 2023-02-28 15:03:03 -05:00
marcin mikołajczak 277045c7a1 Remove custom emojis from reaction picker
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-28 20:52:15 +01:00
marcin mikołajczak d6732955de Merge remote-tracking branch 'soapbox/develop' into update-emoji-mart-2 2023-02-28 20:48:21 +01:00
marcin mikołajczak 9aef41eab1 Cleanup
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-28 19:13:34 +01:00
marcin mikołajczak e6d6ac6d44 Update en.json
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-28 18:59:32 +01:00
Alex Gleason f450c42048 Merge branch 'i18n-fix' into 'develop'
Add `yarn i18n` command to fix translation files

See merge request soapbox-pub/soapbox!2315
2023-02-28 17:13:56 +00:00
marcin mikołajczak dfa5d3ec8e Restore icon picker
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-28 18:04:24 +01:00
Alex Gleason 18bcd1c084
Add `yarn i18n` command to fix translation files 2023-02-28 10:13:53 -06:00
Alex Gleason a6c5d468f4
Enable groups for v.build === UNRELEASED 2023-02-28 10:05:23 -06:00
Chewbacca e7897228c6 Add support for Group search 2023-02-28 10:26:27 -05:00
Alex Gleason 83dab22371
Chats: allow uploading multiple attachments at once (if the backend supports it) 2023-02-27 09:59:00 -06:00
Chewbacca 0414c36a1e Add Trending and Suggested Groups to discovery 2023-02-27 08:26:59 -05:00
marcin mikołajczak 01a4e7370f Types, update styles
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-26 20:34:57 +01:00
marcin mikołajczak 2bbbcd625e WIP
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-26 19:29:37 +01:00
Alex Gleason b7c1d7d44a Merge branch 'media-rounded' into 'develop'
Improve rounded courners in MediaGallery and Chats

See merge request soapbox-pub/soapbox!2310
2023-02-24 16:06:40 +00:00
Alex Gleason 1b020b2a9b
Improve rounded courners in MediaGallery and Chats 2023-02-23 16:05:24 -06:00
marcin mikołajczak 528acb8ac5 Merge remote-tracking branch 'soapbox/develop' into update-emoji-mart
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-23 17:42:31 +01:00
marcin mikołajczak 5a90bb4456 Merge branch 'mkljczk-develop-patch-61732' into 'develop'
Compose: Only send group_id when not null

Closes rebased#184

See merge request soapbox-pub/soapbox!2307
2023-02-22 19:09:23 +00:00
marcin mikołajczak 28d84dedff Compose: Only send group_id when not null 2023-02-22 17:35:48 +00:00
Alex Gleason 6a3618da9a Merge branch 'docker-release-only' into 'develop'
GitLab CI: only run Docker job when a tag is pushed

See merge request soapbox-pub/soapbox!2299
2023-02-21 17:10:07 +00:00
Alex Gleason 02cf175e1f Merge branch 'empty-p' into 'develop'
Replace `<p></p>` with empty string in chats and statuses

See merge request soapbox-pub/soapbox!2306
2023-02-21 16:38:14 +00:00
Alex Gleason dc8952ad18
Replace `<p></p>` with empty string in chats and statuses 2023-02-21 09:00:16 -06:00
Alex Gleason 6413bed23f Merge branch 'renovate/tabler-icons-2.x' into 'develop'
Update dependency @tabler/icons to v2

See merge request soapbox-pub/soapbox!2218
2023-02-20 18:05:26 +00:00
Alex Gleason 93f873fce9
Tabler: ballon.svg --> balloon.svg 2023-02-20 11:37:06 -06:00
marcin mikołajczak eaa060c4bd Merge branch 'audio-styles' into 'develop'
Fix: audio player track position opacity missing

Closes #1381

See merge request soapbox-pub/soapbox!2302
2023-02-19 21:01:28 +00:00
marcin mikołajczak 9d6c698d31 Fix: audio player track position opacity missing
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-19 20:23:20 +01:00
Alex Gleason d7c9c035a2 Merge branch 'alexgleason-develop-patch-82538' into 'develop'
Remove groups from changelog

See merge request soapbox-pub/soapbox!2301
2023-02-17 12:58:50 +00:00
Alex Gleason c6d89fae38 Remove groups from changelog 2023-02-17 12:58:13 +00:00
Alex Gleason 52b24bb013 Merge branch 'alexgleason-develop-patch-02881' into 'develop'
Update CHANGELOG.md

See merge request soapbox-pub/soapbox!2300
2023-02-16 04:37:42 +00:00
Alex Gleason c9285c7abe Update CHANGELOG.md 2023-02-16 04:37:11 +00:00
Alex Gleason 09baa262f9
GitLab CI: only run Docker job when a tag is pushed 2023-02-15 19:57:40 -06:00
Alex Gleason 10c24f01d9 Merge branch 'fix-react-icons' into 'develop'
Fix Emoji Icon Positioning

Closes #1363

See merge request soapbox-pub/soapbox!2297
2023-02-16 01:52:51 +00:00
marcin mikołajczak b3585bb348 Merge branch 'eslint-rules' into 'develop'
Change ESLint rules, lint

See merge request soapbox-pub/soapbox!2298
2023-02-16 00:06:57 +00:00
marcin mikołajczak 81de0014d3 Change ESLint rules, lint
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-16 00:12:02 +01:00
Alex Gleason 2e27886230 Alex's suggestion (brap) 2023-02-15 21:34:26 +00:00
matty 4b99ab7d35 fixes the stuff 2023-02-15 16:14:03 -05:00
Soapbox Bot a6b96c88aa Update dependency @tabler/icons to v2 2023-02-15 19:09:14 +00:00
Alex Gleason ad07305417 Merge branch 'changelog-unreleased' into 'develop'
Prep CHANGELOG for next release

See merge request soapbox-pub/soapbox!2296
2023-02-15 19:01:18 +00:00
Alex Gleason 445379f180
Prep CHANGELOG for next release 2023-02-15 13:00:59 -06:00
marcin mikołajczak d4bcdf428f wip
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-04 11:44:12 +01:00
marcin mikołajczak 0ec5ec7129 Update CHANGELOG.md
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-20 22:32:51 +01:00
marcin mikołajczak d891024cb5 Update en.json
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-20 14:20:50 +01:00
marcin mikołajczak 93b09d8206 Add ability to follow hashtags in web UI
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-19 15:06:17 +01:00
Alex Gleason 27500193d8
EntityStore: incorporate Notifications, go back to using POJOs instead of Maps 2022-12-04 18:54:54 -06:00
Alex Gleason f7bfc40b70
EntityStore: proper pagination support 2022-12-04 17:53:56 -06:00
Alex Gleason 52059f6f37
EntityStore: add request/success/fail actions 2022-12-04 17:26:28 -06:00
Alex Gleason 3b067c6fab
Scaffold entity store library 2022-12-04 17:05:01 -06:00
Alex Gleason 8534cabc0a
Fix ComposeForm collapsing when clicking within emoji picker 2022-07-13 20:41:39 -05:00
Alex Gleason a8ebbc15c8
EmojiPickerDropdown: shrink emoji size, cleanup 2022-07-13 20:37:28 -05:00
Alex Gleason 26b5ca8b6e
Fix linter errors 2022-07-11 15:19:37 -05:00
Alex Gleason 00802b01e9
EmojiPicker: fix asset paths 2022-07-11 15:09:41 -05:00
ewwwwwwww 3879dad039 scroll fix 2022-07-10 04:42:22 -07:00
ewwwwwwww a1f0f75f60 abstracted dropdown so it can be reused 2022-07-10 02:06:37 -07:00
ewwwwwwww b8a335a166 add comments and fix index 2022-07-09 16:32:34 -07:00
ewwwwwwww 63ee482982 oops 2022-07-09 15:37:13 -07:00
ewwwwwwww 3725db9789 oops 2022-07-09 15:36:24 -07:00
ewwwwwwww 540b28364b oops 2022-07-09 15:35:50 -07:00
ewwwwwwww 317672e6ec initial changes for fixing image locations 2022-07-09 15:31:14 -07:00
Alex Gleason b7b0ad06dc
Merge remote-tracking branch 'origin/develop' into update-emoji-mart 2022-07-09 15:21:17 -05:00
ewwwwwwww 34d77df8d7 fix lint 2022-07-09 12:16:42 -07:00
ewwwwwwww d5ca6b58fb i18n support 2022-07-09 11:58:09 -07:00
ewwwwwwww 403db1d46e mobile fixes 2022-07-09 10:52:08 -07:00
ewwwwwwww 9770209f00 lint fixes 2022-07-09 10:02:21 -07:00
ewwwwwwww 2f579839d8 rebased 2022-07-09 09:03:22 -07:00
ewwwwwwww 1249b24ba4 fix all tests 2022-07-09 08:33:14 -07:00
ewwwwwwww f3c350aeef fix some texts 2022-07-09 08:33:14 -07:00
ewwwwwwww 8ef60cdf0b add angry note about twemoji breaking spec 2022-07-09 08:33:14 -07:00
ewwwwwwww 13e76b8022 unqualified fixes 2022-07-09 08:33:14 -07:00
ewwwwwwww b1f5902397 added tests 2022-07-09 08:33:14 -07:00
ewwwwwwww a6e56b131c unicode fixes 2022-07-09 08:33:14 -07:00
ewwwwwwww 4a73412142 small fix 2022-07-09 08:33:14 -07:00
ewwwwwwww 16f06cd554 small fix 2022-07-09 08:33:14 -07:00
ewwwwwwww 1962c6544e emoji-picker fixes 2022-07-09 08:33:14 -07:00
ewwwwwwww 84267d3ffe fix emoji-picker key input 2022-07-09 08:33:14 -07:00
ewwwwwwww 41eebfdbda remove dead code 2022-07-09 08:33:14 -07:00
ewwwwwwww 891ce09443 small fixes 2022-07-09 08:33:14 -07:00
ewwwwwwww 0de246fcae remove old todo 2022-07-09 08:33:14 -07:00
ewwwwwwww c183ab0f06 fix some tests 2022-07-09 08:33:14 -07:00
ewwwwwwww f10001fbfd fix some tests 2022-07-09 08:33:13 -07:00
ewwwwwwww 9d0a3b7a69 remove cheerio and add custom html parser 2022-07-09 08:31:31 -07:00
ewwwwwwww a2fab1285d fix types 2022-07-09 08:31:31 -07:00
ewwwwwwww bd9a33201a convert type to union 2022-07-09 08:31:31 -07:00
ewwwwwwww 8d8cf53ac4 remove console log 2022-07-09 08:31:31 -07:00
ewwwwwwww f08d43ecb3 small fixes 2022-07-09 08:31:31 -07:00
ewwwwwwww e2d6a5d41d remove useless file 2022-07-09 08:31:31 -07:00
ewwwwwwww 485095e502 fixed types 2022-07-09 08:31:31 -07:00
ewwwwwwww bfa8331f96 new emoji search 2022-07-09 08:31:31 -07:00
ewwwwwwww 36d6275107 type fixes 2022-07-09 08:31:31 -07:00
ewwwwwwww d98371bf6a migrate emoji types 2022-07-09 08:31:27 -07:00
ewwwwwwww 6ded0afc1e remove files 2022-07-09 08:30:44 -07:00
ewwwwwwww ad523574e2 small fixes 2022-07-09 08:30:44 -07:00
ewwwwwwww d86b7ba333 new emojifier 2022-07-09 08:30:44 -07:00
ewwwwwwww 88f5739769 new emojifier 2022-07-09 08:30:44 -07:00
ewwwwwwww a8e7e10f61 new emojifier 2022-07-09 08:30:44 -07:00
ewwwwwwww 89bba0e2e3 lint fixes 2022-07-09 08:30:44 -07:00
ewwwwwwww f8bd30a5f7 remove consolelog 2022-07-09 08:30:44 -07:00
ewwwwwwww eeb30b5492 migrated emoji picker to typescript 2022-07-09 08:30:44 -07:00
ewwwwwwww 4b7876f1a6 enabled async component 2022-07-09 08:30:44 -07:00
ewwwwwwww 170d3f748e more emoji fixes 2022-07-09 08:30:44 -07:00
ewwwwwwww 2727fb8f20 lint fixes 2022-07-09 08:30:44 -07:00
Shevek 6a3e66bc7e properly fallback on locale 2021-11-08 21:24:07 -05:00
974 zmienionych plików z 31758 dodań i 28333 usunięć

Wyświetl plik

@ -19,8 +19,6 @@ module.exports = {
ATTACHMENT_HOST: false,
},
parser: '@babel/eslint-parser',
plugins: [
'react',
'jsdoc',
@ -56,6 +54,7 @@ module.exports = {
},
polyfills: [
'es:all', // core-js
'fetch', // not polyfilled, but ignore it
'IntersectionObserver', // npm:intersection-observer
'Promise', // core-js
'ResizeObserver', // npm:resize-observer-polyfill
@ -78,6 +77,7 @@ module.exports = {
},
],
'comma-style': ['warn', 'last'],
'import/no-duplicates': 'error',
'space-before-function-paren': ['error', 'never'],
'space-infix-ops': 'error',
'space-in-parens': ['error', 'never'],
@ -259,13 +259,29 @@ module.exports = {
alphabetize: { order: 'asc' },
},
],
'@typescript-eslint/no-duplicate-imports': 'error',
'@typescript-eslint/member-delimiter-style': [
'error',
{
multiline: {
delimiter: 'none',
},
singleline: {
delimiter: 'comma',
},
},
],
'promise/catch-or-return': 'error',
'react-hooks/rules-of-hooks': 'error',
'tailwindcss/classnames-order': 'error',
'tailwindcss/classnames-order': [
'error',
{
classRegex: '^(base|container|icon|item|list|outer|wrapper)?[c|C]lass(Name)?$',
config: 'tailwind.config.cjs',
},
],
'tailwindcss/migration-from-tailwind-2': 'error',
},
overrides: [

1
.gitignore vendored
Wyświetl plik

@ -9,6 +9,7 @@
/.vs/
yarn-error.log*
/junit.xml
*.timestamp-*
/static/
/static-test/

Wyświetl plik

@ -1,7 +1,8 @@
image: node:18
image: node:20
variables:
NODE_ENV: test
DS_EXCLUDED_ANALYZERS: gemnasium-python
default:
interruptible: true
@ -64,27 +65,27 @@ lint-sass:
- "**/*.css"
- ".stylelintrc.json"
jest:
stage: test
script: yarn test:coverage --runInBand
only:
changes:
- "**/*.js"
- "**/*.json"
- "app/soapbox/**/*"
- "webpack/**/*"
- "custom/**/*"
- "jest.config.cjs"
- "package.json"
- "yarn.lock"
- ".gitlab-ci.yml"
coverage: /All files[^|]*\|[^|]*\s+([\d\.]+)/
artifacts:
reports:
junit: junit.xml
coverage_report:
coverage_format: cobertura
path: .coverage/cobertura-coverage.xml
# jest:
# stage: test
# script: yarn test:coverage --runInBand
# only:
# changes:
# - "**/*.js"
# - "**/*.json"
# - "app/soapbox/**/*"
# - "webpack/**/*"
# - "custom/**/*"
# - "jest.config.cjs"
# - "package.json"
# - "yarn.lock"
# - ".gitlab-ci.yml"
# coverage: /All files[^|]*\|[^|]*\s+([\d\.]+)/
# artifacts:
# reports:
# junit: junit.xml
# coverage_report:
# coverage_format: cobertura
# path: .coverage/cobertura-coverage.xml
nginx-test:
stage: test
@ -100,10 +101,11 @@ build-production:
stage: test
script:
- yarn build
- yarn manage:translations en
# Fail if files got changed.
# https://stackoverflow.com/a/9066385
- git diff --quiet
# - yarn manage:translations en
# # Fail if files got changed.
# # https://stackoverflow.com/a/9066385
# - git diff --quiet
- cp static/index.html static/404.html
variables:
NODE_ENV: production
artifacts:
@ -149,19 +151,19 @@ pages:
docker:
stage: deploy
image: docker:23.0.0
image: docker:24.0.6
services:
- docker:23.0.0-dind
- docker:24.0.6-dind
tags:
- dind
# https://medium.com/devops-with-valentine/how-to-build-a-docker-image-and-push-it-to-the-gitlab-container-registry-from-a-gitlab-ci-pipeline-acac0d1f26df
script:
- echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER $CI_REGISTRY --password-stdin
- docker build -t $CI_REGISTRY_IMAGE .
- docker push $CI_REGISTRY_IMAGE
only:
variables:
- $CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG
rules:
- if: $CI_COMMIT_TAG
interruptible: false
release:
stage: release
@ -173,4 +175,3 @@ release:
include:
- template: Jobs/Dependency-Scanning.gitlab-ci.yml
- template: Security/License-Scanning.gitlab-ci.yml

Wyświetl plik

@ -1,43 +0,0 @@
import sharedConfig from '../webpack/shared';
import type { StorybookConfig } from '@storybook/core-common';
const config: StorybookConfig = {
stories: [
'../stories/**/*.stories.mdx',
'../stories/**/*.stories.@(js|jsx|ts|tsx)'
],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/addon-interactions',
'storybook-react-intl',
{
name: '@storybook/addon-postcss',
options: {
postcssLoaderOptions: {
implementation: require('postcss'),
},
},
},
],
framework: '@storybook/react',
core: {
builder: '@storybook/builder-webpack5',
},
webpackFinal: async (config) => {
config.resolve!.alias = {
...sharedConfig.resolve!.alias,
...config.resolve!.alias,
};
config.resolve!.modules = [
...sharedConfig.resolve!.modules!,
...config.resolve!.modules!,
];
return config;
},
};
export default config;

Wyświetl plik

@ -1,22 +0,0 @@
import '../app/styles/tailwind.css';
import '../stories/theme.css';
import { addDecorator, Story } from '@storybook/react';
import { IntlProvider } from 'react-intl';
import React from 'react';
const withProvider = (Story: Story) => (
<IntlProvider locale='en'><Story /></IntlProvider>
);
addDecorator(withProvider);
export const parameters = {
actions: { argTypesRegex: '^on[A-Z].*' },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
};

Wyświetl plik

@ -16,7 +16,6 @@
"no-invalid-position-at-import-rule": null,
"scss/at-rule-no-unknown": [true, { "ignoreAtRules": ["tailwind", "apply", "layer", "config"]}],
"scss/operator-no-unspaced": null,
"selector-class-pattern": null,
"string-quotes": "single"
"selector-class-pattern": null
}
}

Wyświetl plik

@ -1 +1 @@
nodejs 18.14.0
nodejs 20.0.0

Wyświetl plik

@ -4,6 +4,45 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
- Hashtags: let users follow hashtags (Mastodon, Akkoma).
- Posts: Support posts filtering on recent Mastodon versions
- Reactions: Support custom emoji reactions
- Compatbility: Support Mastodon v2 timeline filters.
- Compatbility: Preliminary support for Ditto backend.
- Compatibility: Support Firefish.
- Posts: Support dislikes on Friendica.
- UI: added a character counter to some textareas.
- UI: added new experience for viewing Media
- Hotkeys: Added `/` as a hotkey for search field.
### Changed
- Posts: truncate Nostr pubkeys in reply mentions.
- Posts: upgraded emoji picker component.
- Posts: improved design of threads.
- UI: unified design of "approve" and "reject" buttons in follow requests and waitlist.
- UI: added sticky column header.
- UI: add specific zones the user can drag-and-drop files.
- UI: disable toast notifications for API errors.
- Chats: Display year for older messages creation date.
### Fixed
- Posts: fixed emojis being cut off in reactions modal.
- Posts: fix audio player progress bar visibility.
- Posts: fix audio player avatar aspect ratio for non-square avatars.
- Posts: added missing gap in pending status.
- Compatibility: fixed quote posting compatibility with custom Pleroma forks.
- Profile: fix "load more" button height on account gallery page.
- 18n: fixed Chinese language being detected from the browser.
- Conversations: fixed pagination (Mastodon).
- Compatibility: fix version parsing for Friendica.
- UI: fixed various overflow issues related to long usernames.
- UI: fixed display of Markdown code blocks in the reply indicator.
- Auth: fixed too many API requests when the server has an error.
- Auth: Don't display "username or e-mail" if username is not allowed.
## [3.2.0] - 2023-02-15
### Added
@ -12,12 +51,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Posts: bot badge on statuses from bot accounts.
- Compatibility: improved browser support for older browsers.
- Events: allow to repost events in event menu.
- Groups: Initial support for groups.
- Profile: Add RSS link to user profiles.
- Reactions: adds support for reacting to chat messages.
- Groups: initial support for groups.
- Profile: add RSS link to user profiles.
- Posts: fix posts filtering.
- Chats: reset chat message field height after sending a message.
- Admin: allow to manage announcements.
@ -38,6 +75,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- index.html: remove `referrer` meta tag so it doesn't conflict with backend's `Referrer-Policy` header.
- Modals: fix media modal automatically switching to video.
- Navigation: profile dropdown erratic behavior.
- Posts: fix posts filtering.
### Removed
- Admin: single user mode. Now the homepage can be redirected to any URL.

Wyświetl plik

@ -1,4 +1,4 @@
FROM node:18 as build
FROM node:20 as build
WORKDIR /app
COPY package.json .
COPY yarn.lock .

Wyświetl plik

@ -1,4 +1,4 @@
FROM node:18
FROM node:20
RUN apt-get update &&\
apt-get install -y inotify-tools &&\

Wyświetl plik

@ -75,7 +75,7 @@ One disadvantage of this approach is that it does not help the software spread.
© Alex Gleason & other Soapbox contributors
© Eugen Rochko & other Mastodon contributors
© Trump Media & Technology Group
© Gab AI, Inc.
© Gab AI, Inc.
Soapbox is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by

Wyświetl plik

@ -2,4 +2,4 @@
- verified.svg - Created by Alex Gleason. CC0
Fediverse logo: https://en.wikipedia.org/wiki/Fediverse#/media/File:Fediverse_logo_proposal.svg
Fediverse logo: https://en.wikipedia.org/wiki/Fediverse#/media/File:Fediverse_logo_proposal.svg

24
app/index.html 100644
Wyświetl plik

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover, user-scalable=no">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<link href="/manifest.json" rel="manifest">
<!--server-generated-meta-->
<script type="module" src="./soapbox/main.tsx"></script>
</head>
<body class="theme-mode-light no-reduce-motion">
<div id="soapbox" class="h-full">
<div class="loading-indicator-wrapper">
<div class="loading-indicator">
<div class="loading-indicator__container">
<div class="loading-indicator__figure"></div>
</div>
</div>
</div>
</div>
<noscript>To use this website, please enable JavaScript.</noscript>
</body>
</html>

Wyświetl plik

@ -0,0 +1,19 @@
{
"avatar": "https://media.covfefe.social/groups/avatars/109/989/480/368/015/378/original/50b0d899bc5aae13.jpg",
"avatar_static": "https://media.covfefe.social/groups/avatars/109/989/480/368/015/378/original/50b0d899bc5aae13.jpg",
"created_at": "2023-03-08T00:00:00.000Z",
"discoverable": true,
"display_name": "PATRIOT PATRIOTS",
"domain": null,
"group_visibility": "everyone",
"header": "https://media.covfefe.social/groups/headers/109/989/480/368/015/378/original/c5063b59f919cd4a.png",
"header_static": "https://media.covfefe.social/groups/headers/109/989/480/368/015/378/original/c5063b59f919cd4a.png",
"id": "109989480368015378",
"members_count": 1,
"membership_required": true,
"note": "patriots 900000001",
"owner": {
"id": "424023483294040"
},
"tags": []
}

Wyświetl plik

@ -1,5 +1,5 @@
import { render } from '@testing-library/react';
import { AxiosError } from 'axios';
import { AxiosError, AxiosHeaders } from 'axios';
import React from 'react';
import { IntlProvider } from 'react-intl';
@ -20,7 +20,7 @@ function renderApp() {
}
beforeAll(() => {
jest.spyOn(console, 'error').mockImplementation(() => {});
vi.spyOn(console, 'error').mockImplementation(() => {});
});
afterEach(() => {
@ -73,7 +73,9 @@ describe('toasts', () =>{
statusText: String(status),
status,
headers: {},
config: {},
config: {
headers: new AxiosHeaders(),
},
});
describe('with a 502 status code', () => {

Wyświetl plik

@ -1,21 +1,13 @@
import { Map as ImmutableMap } from 'immutable';
import { __stub } from 'soapbox/api';
import { mockStore, rootState } from 'soapbox/jest/test-helpers';
import { ReducerRecord, EditRecord } from 'soapbox/reducers/account-notes';
import { normalizeAccount, normalizeRelationship } from '../../normalizers';
import { changeAccountNoteComment, initAccountNoteModal, submitAccountNote } from '../account-notes';
import type { Account } from 'soapbox/types/entities';
import { submitAccountNote } from '../account-notes';
describe('submitAccountNote()', () => {
let store: ReturnType<typeof mockStore>;
beforeEach(() => {
const state = rootState
.set('account_notes', ReducerRecord({ edit: EditRecord({ account: '1', comment: 'hello' }) }));
store = mockStore(state);
store = mockStore(rootState);
});
describe('with a successful API request', () => {
@ -28,10 +20,9 @@ describe('submitAccountNote()', () => {
it('post the note to the API', async() => {
const expectedActions = [
{ type: 'ACCOUNT_NOTE_SUBMIT_REQUEST' },
{ type: 'MODAL_CLOSE', modalType: undefined },
{ type: 'ACCOUNT_NOTE_SUBMIT_SUCCESS', relationship: {} },
];
await store.dispatch(submitAccountNote());
await store.dispatch(submitAccountNote('1', 'hello'));
const actions = store.getActions();
expect(actions).toEqual(expectedActions);
@ -53,58 +44,10 @@ describe('submitAccountNote()', () => {
error: new Error('Network Error'),
},
];
await store.dispatch(submitAccountNote());
await store.dispatch(submitAccountNote('1', 'hello'));
const actions = store.getActions();
expect(actions).toEqual(expectedActions);
});
});
});
describe('initAccountNoteModal()', () => {
let store: ReturnType<typeof mockStore>;
beforeEach(() => {
const state = rootState
.set('relationships', ImmutableMap({ '1': normalizeRelationship({ note: 'hello' }) }));
store = mockStore(state);
});
it('dispatches the proper actions', async() => {
const account = normalizeAccount({
id: '1',
acct: 'justin-username',
display_name: 'Justin L',
avatar: 'test.jpg',
verified: true,
}) as Account;
const expectedActions = [
{ type: 'ACCOUNT_NOTE_INIT_MODAL', account, comment: 'hello' },
{ type: 'MODAL_OPEN', modalType: 'ACCOUNT_NOTE' },
];
await store.dispatch(initAccountNoteModal(account));
const actions = store.getActions();
expect(actions).toEqual(expectedActions);
});
});
describe('changeAccountNoteComment()', () => {
let store: ReturnType<typeof mockStore>;
beforeEach(() => {
const state = rootState;
store = mockStore(state);
});
it('dispatches the proper actions', async() => {
const comment = 'hello world';
const expectedActions = [
{ type: 'ACCOUNT_NOTE_CHANGE_COMMENT', comment },
];
await store.dispatch(changeAccountNoteComment(comment));
const actions = store.getActions();
expect(actions).toEqual(expectedActions);
});
});

Wyświetl plik

@ -1,10 +1,11 @@
import { Map as ImmutableMap } from 'immutable';
import { __stub } from 'soapbox/api';
import { buildRelationship } from 'soapbox/jest/factory';
import { mockStore, rootState } from 'soapbox/jest/test-helpers';
import { ListRecord, ReducerRecord } from 'soapbox/reducers/user-lists';
import { normalizeAccount, normalizeInstance, normalizeRelationship } from '../../normalizers';
import { normalizeAccount, normalizeInstance } from '../../normalizers';
import {
authorizeFollowRequest,
blockAccount,
@ -18,12 +19,10 @@ import {
fetchFollowing,
fetchFollowRequests,
fetchRelationships,
followAccount,
muteAccount,
removeFromFollowers,
subscribeAccount,
unblockAccount,
unfollowAccount,
unmuteAccount,
unsubscribeAccount,
} from '../accounts';
@ -75,9 +74,14 @@ describe('fetchAccount()', () => {
});
const state = rootState
.set('accounts', ImmutableMap({
[id]: account,
}) as any);
.set('entities', {
'ACCOUNTS': {
store: {
[id]: account,
},
lists: {},
},
});
store = mockStore(state);
@ -167,9 +171,14 @@ describe('fetchAccountByUsername()', () => {
});
state = rootState
.set('accounts', ImmutableMap({
[id]: account,
}));
.set('entities', {
'ACCOUNTS': {
store: {
[id]: account,
},
lists: {},
},
});
store = mockStore(state);
@ -370,169 +379,6 @@ describe('fetchAccountByUsername()', () => {
});
});
describe('followAccount()', () => {
describe('when logged out', () => {
beforeEach(() => {
const state = rootState.set('me', null);
store = mockStore(state);
});
it('should do nothing', async() => {
await store.dispatch(followAccount('1'));
const actions = store.getActions();
expect(actions).toEqual([]);
});
});
describe('when logged in', () => {
const id = '1';
beforeEach(() => {
const state = rootState.set('me', '123');
store = mockStore(state);
});
describe('with a successful API request', () => {
beforeEach(() => {
__stub((mock) => {
mock.onPost(`/api/v1/accounts/${id}/follow`).reply(200, { success: true });
});
});
it('should dispatch the correct actions', async() => {
const expectedActions = [
{
type: 'ACCOUNT_FOLLOW_REQUEST',
id,
locked: false,
skipLoading: true,
},
{
type: 'ACCOUNT_FOLLOW_SUCCESS',
relationship: { success: true },
alreadyFollowing: undefined,
skipLoading: true,
},
];
await store.dispatch(followAccount(id));
const actions = store.getActions();
expect(actions).toEqual(expectedActions);
});
});
describe('with an unsuccessful API request', () => {
beforeEach(() => {
__stub((mock) => {
mock.onPost(`/api/v1/accounts/${id}/follow`).networkError();
});
});
it('should dispatch the correct actions', async() => {
const expectedActions = [
{
type: 'ACCOUNT_FOLLOW_REQUEST',
id,
locked: false,
skipLoading: true,
},
{
type: 'ACCOUNT_FOLLOW_FAIL',
error: new Error('Network Error'),
locked: false,
skipLoading: true,
},
];
try {
await store.dispatch(followAccount(id));
} catch (e) {
const actions = store.getActions();
expect(actions).toEqual(expectedActions);
expect(e).toEqual(new Error('Network Error'));
}
});
});
});
});
describe('unfollowAccount()', () => {
describe('when logged out', () => {
beforeEach(() => {
const state = rootState.set('me', null);
store = mockStore(state);
});
it('should do nothing', async() => {
await store.dispatch(unfollowAccount('1'));
const actions = store.getActions();
expect(actions).toEqual([]);
});
});
describe('when logged in', () => {
const id = '1';
beforeEach(() => {
const state = rootState.set('me', '123');
store = mockStore(state);
});
describe('with a successful API request', () => {
beforeEach(() => {
__stub((mock) => {
mock.onPost(`/api/v1/accounts/${id}/unfollow`).reply(200, { success: true });
});
});
it('should dispatch the correct actions', async() => {
const expectedActions = [
{ type: 'ACCOUNT_UNFOLLOW_REQUEST', id: '1', skipLoading: true },
{
type: 'ACCOUNT_UNFOLLOW_SUCCESS',
relationship: { success: true },
statuses: ImmutableMap({}),
skipLoading: true,
},
];
await store.dispatch(unfollowAccount(id));
const actions = store.getActions();
expect(actions).toEqual(expectedActions);
});
});
describe('with an unsuccessful API request', () => {
beforeEach(() => {
__stub((mock) => {
mock.onPost(`/api/v1/accounts/${id}/unfollow`).networkError();
});
});
it('should dispatch the correct actions', async() => {
const expectedActions = [
{
type: 'ACCOUNT_UNFOLLOW_REQUEST',
id,
skipLoading: true,
},
{
type: 'ACCOUNT_UNFOLLOW_FAIL',
error: new Error('Network Error'),
skipLoading: true,
},
];
await store.dispatch(unfollowAccount(id));
const actions = store.getActions();
expect(actions).toEqual(expectedActions);
});
});
});
});
describe('blockAccount()', () => {
const id = '1';
@ -1340,7 +1186,7 @@ describe('fetchRelationships()', () => {
describe('without newAccountIds', () => {
beforeEach(() => {
const state = rootState
.set('relationships', ImmutableMap({ [id]: normalizeRelationship({}) }))
.set('relationships', ImmutableMap({ [id]: buildRelationship() }))
.set('me', '123');
store = mockStore(state);
});

Wyświetl plik

@ -41,7 +41,7 @@ describe('uploadCompose()', () => {
it('creates an alert if exceeds max size', async() => {
const mockIntl = {
formatMessage: jest.fn().mockReturnValue('Image exceeds the current file size limit (10 Bytes)'),
formatMessage: vi.fn().mockReturnValue('Image exceeds the current file size limit (10 Bytes)'),
} as unknown as IntlShape;
const expectedActions = [
@ -87,7 +87,7 @@ describe('uploadCompose()', () => {
it('creates an alert if exceeds max size', async() => {
const mockIntl = {
formatMessage: jest.fn().mockReturnValue('Video exceeds the current file size limit (10 Bytes)'),
formatMessage: vi.fn().mockReturnValue('Video exceeds the current file size limit (10 Bytes)'),
} as unknown as IntlShape;
const expectedActions = [

Wyświetl plik

@ -1,18 +1,16 @@
import { Map as ImmutableMap } from 'immutable';
import { __stub } from 'soapbox/api';
import { buildAccount } from 'soapbox/jest/factory';
import { mockStore, rootState } from 'soapbox/jest/test-helpers';
import { AccountRecord } from 'soapbox/normalizers';
import { AuthUserRecord, ReducerRecord } from 'soapbox/reducers/auth';
import { AuthUserRecord, ReducerRecord } from '../../reducers/auth';
import {
fetchMe, patchMe,
} from '../me';
import { fetchMe, patchMe } from '../me';
jest.mock('../../storage/kv-store', () => ({
vi.mock('../../storage/kv-store', () => ({
__esModule: true,
default: {
getItemOrError: jest.fn().mockReturnValue(Promise.resolve({})),
getItemOrError: vi.fn().mockReturnValue(Promise.resolve({})),
},
}));
@ -48,11 +46,15 @@ describe('fetchMe()', () => {
}),
}),
}))
.set('accounts', ImmutableMap({
[accountUrl]: AccountRecord({
url: accountUrl,
}),
}) as any);
.set('entities', {
'ACCOUNTS': {
store: {
[accountUrl]: buildAccount({ url: accountUrl }),
},
lists: {},
},
});
store = mockStore(state);
});

Wyświetl plik

@ -10,11 +10,11 @@ describe('checkOnboarding()', () => {
});
beforeEach(() => {
mockGetItem = jest.fn().mockReturnValue(null);
mockGetItem = vi.fn().mockReturnValue(null);
});
it('does nothing if localStorage item is not set', async() => {
mockGetItem = jest.fn().mockReturnValue(null);
mockGetItem = vi.fn().mockReturnValue(null);
const state = rootState.setIn(['onboarding', 'needsOnboarding'], false);
const store = mockStore(state);
@ -27,7 +27,7 @@ describe('checkOnboarding()', () => {
});
it('does nothing if localStorage item is invalid', async() => {
mockGetItem = jest.fn().mockReturnValue('invalid');
mockGetItem = vi.fn().mockReturnValue('invalid');
const state = rootState.setIn(['onboarding', 'needsOnboarding'], false);
const store = mockStore(state);
@ -40,7 +40,7 @@ describe('checkOnboarding()', () => {
});
it('dispatches the correct action', async() => {
mockGetItem = jest.fn().mockReturnValue('1');
mockGetItem = vi.fn().mockReturnValue('1');
const state = rootState.setIn(['onboarding', 'needsOnboarding'], false);
const store = mockStore(state);
@ -61,7 +61,7 @@ describe('startOnboarding()', () => {
});
beforeEach(() => {
mockSetItem = jest.fn();
mockSetItem = vi.fn();
});
it('dispatches the correct action', async() => {
@ -84,7 +84,7 @@ describe('endOnboarding()', () => {
});
beforeEach(() => {
mockRemoveItem = jest.fn();
mockRemoveItem = vi.fn();
});
it('dispatches the correct action', async() => {

Wyświetl plik

@ -1,4 +1,6 @@
import { rootState } from '../../jest/test-helpers';
import { rootState } from 'soapbox/jest/test-helpers';
import { RootState } from 'soapbox/store';
import { getSoapboxConfig } from '../soapbox';
const ASCII_HEART = '❤'; // '\u2764\uFE0F'
@ -6,13 +8,13 @@ const RED_HEART_RGI = '❤️'; // '\u2764'
describe('getSoapboxConfig()', () => {
it('returns RGI heart on Pleroma > 2.3', () => {
const state = rootState.setIn(['instance', 'version'], '2.7.2 (compatible; Pleroma 2.3.0)');
const state = rootState.setIn(['instance', 'version'], '2.7.2 (compatible; Pleroma 2.3.0)') as RootState;
expect(getSoapboxConfig(state).allowedEmoji.includes(RED_HEART_RGI)).toBe(true);
expect(getSoapboxConfig(state).allowedEmoji.includes(ASCII_HEART)).toBe(false);
});
it('returns an ASCII heart on Pleroma < 2.3', () => {
const state = rootState.setIn(['instance', 'version'], '2.7.2 (compatible; Pleroma 2.0.0)');
const state = rootState.setIn(['instance', 'version'], '2.7.2 (compatible; Pleroma 2.0.0)') as RootState;
expect(getSoapboxConfig(state).allowedEmoji.includes(ASCII_HEART)).toBe(true);
expect(getSoapboxConfig(state).allowedEmoji.includes(RED_HEART_RGI)).toBe(false);
});

Wyświetl plik

@ -123,6 +123,7 @@ describe('deleteStatus()', () => {
withRedraft: true,
id: 'compose-modal',
},
{ type: 'MODAL_CLOSE', modalType: 'COMPOSE', modalProps: undefined },
{ type: 'MODAL_OPEN', modalType: 'COMPOSE', modalProps: undefined },
];
await store.dispatch(deleteStatus(statusId, true));

Wyświetl plik

@ -1,82 +1,44 @@
import api from '../api';
import { openModal, closeModal } from './modals';
import type { AxiosError } from 'axios';
import type { AnyAction } from 'redux';
import type { RootState } from 'soapbox/store';
import type { Account } from 'soapbox/types/entities';
const ACCOUNT_NOTE_SUBMIT_REQUEST = 'ACCOUNT_NOTE_SUBMIT_REQUEST';
const ACCOUNT_NOTE_SUBMIT_SUCCESS = 'ACCOUNT_NOTE_SUBMIT_SUCCESS';
const ACCOUNT_NOTE_SUBMIT_FAIL = 'ACCOUNT_NOTE_SUBMIT_FAIL';
const ACCOUNT_NOTE_INIT_MODAL = 'ACCOUNT_NOTE_INIT_MODAL';
const submitAccountNote = (id: string, value: string) =>
(dispatch: React.Dispatch<AnyAction>, getState: () => RootState) => {
dispatch(submitAccountNoteRequest());
const ACCOUNT_NOTE_CHANGE_COMMENT = 'ACCOUNT_NOTE_CHANGE_COMMENT';
const submitAccountNote = () => (dispatch: React.Dispatch<AnyAction>, getState: () => RootState) => {
dispatch(submitAccountNoteRequest());
const id = getState().account_notes.edit.account;
return api(getState)
.post(`/api/v1/accounts/${id}/note`, {
comment: getState().account_notes.edit.comment,
})
.then(response => {
dispatch(closeModal());
dispatch(submitAccountNoteSuccess(response.data));
})
.catch(error => dispatch(submitAccountNoteFail(error)));
};
function submitAccountNoteRequest() {
return {
type: ACCOUNT_NOTE_SUBMIT_REQUEST,
return api(getState)
.post(`/api/v1/accounts/${id}/note`, {
comment: value,
})
.then(response => {
dispatch(submitAccountNoteSuccess(response.data));
})
.catch(error => dispatch(submitAccountNoteFail(error)));
};
}
function submitAccountNoteSuccess(relationship: any) {
return {
type: ACCOUNT_NOTE_SUBMIT_SUCCESS,
relationship,
};
}
const submitAccountNoteRequest = () => ({
type: ACCOUNT_NOTE_SUBMIT_REQUEST,
});
function submitAccountNoteFail(error: AxiosError) {
return {
type: ACCOUNT_NOTE_SUBMIT_FAIL,
error,
};
}
const submitAccountNoteSuccess = (relationship: any) => ({
type: ACCOUNT_NOTE_SUBMIT_SUCCESS,
relationship,
});
const initAccountNoteModal = (account: Account) => (dispatch: React.Dispatch<AnyAction>, getState: () => RootState) => {
const comment = getState().relationships.get(account.id)!.note;
dispatch({
type: ACCOUNT_NOTE_INIT_MODAL,
account,
comment,
});
dispatch(openModal('ACCOUNT_NOTE'));
};
function changeAccountNoteComment(comment: string) {
return {
type: ACCOUNT_NOTE_CHANGE_COMMENT,
comment,
};
}
const submitAccountNoteFail = (error: AxiosError) => ({
type: ACCOUNT_NOTE_SUBMIT_FAIL,
error,
});
export {
submitAccountNote,
initAccountNoteModal,
changeAccountNoteComment,
ACCOUNT_NOTE_SUBMIT_REQUEST,
ACCOUNT_NOTE_SUBMIT_SUCCESS,
ACCOUNT_NOTE_SUBMIT_FAIL,
ACCOUNT_NOTE_INIT_MODAL,
ACCOUNT_NOTE_CHANGE_COMMENT,
};

Wyświetl plik

@ -1,3 +1,6 @@
import { importEntities } from 'soapbox/entity-store/actions';
import { Entities } from 'soapbox/entity-store/entities';
import { selectAccount } from 'soapbox/selectors';
import { isLoggedIn } from 'soapbox/utils/auth';
import { getFeatures, parseVersion, PLEROMA } from 'soapbox/utils/features';
@ -23,14 +26,6 @@ const ACCOUNT_FETCH_REQUEST = 'ACCOUNT_FETCH_REQUEST';
const ACCOUNT_FETCH_SUCCESS = 'ACCOUNT_FETCH_SUCCESS';
const ACCOUNT_FETCH_FAIL = 'ACCOUNT_FETCH_FAIL';
const ACCOUNT_FOLLOW_REQUEST = 'ACCOUNT_FOLLOW_REQUEST';
const ACCOUNT_FOLLOW_SUCCESS = 'ACCOUNT_FOLLOW_SUCCESS';
const ACCOUNT_FOLLOW_FAIL = 'ACCOUNT_FOLLOW_FAIL';
const ACCOUNT_UNFOLLOW_REQUEST = 'ACCOUNT_UNFOLLOW_REQUEST';
const ACCOUNT_UNFOLLOW_SUCCESS = 'ACCOUNT_UNFOLLOW_SUCCESS';
const ACCOUNT_UNFOLLOW_FAIL = 'ACCOUNT_UNFOLLOW_FAIL';
const ACCOUNT_BLOCK_REQUEST = 'ACCOUNT_BLOCK_REQUEST';
const ACCOUNT_BLOCK_SUCCESS = 'ACCOUNT_BLOCK_SUCCESS';
const ACCOUNT_BLOCK_FAIL = 'ACCOUNT_BLOCK_FAIL';
@ -147,9 +142,9 @@ const fetchAccount = (id: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch(fetchRelationships([id]));
const account = getState().accounts.get(id);
const account = selectAccount(getState(), id);
if (account && !account.get('should_refetch')) {
if (account) {
return null;
}
@ -227,81 +222,6 @@ const fetchAccountFail = (id: string | null, error: AxiosError) => ({
skipAlert: true,
});
type FollowAccountOpts = {
reblogs?: boolean,
notify?: boolean
};
const followAccount = (id: string, options?: FollowAccountOpts) =>
(dispatch: AppDispatch, getState: () => RootState) => {
if (!isLoggedIn(getState)) return null;
const alreadyFollowing = getState().relationships.get(id)?.following || undefined;
const locked = getState().accounts.get(id)?.locked || false;
dispatch(followAccountRequest(id, locked));
return api(getState)
.post(`/api/v1/accounts/${id}/follow`, options)
.then(response => dispatch(followAccountSuccess(response.data, alreadyFollowing)))
.catch(error => {
dispatch(followAccountFail(error, locked));
throw error;
});
};
const unfollowAccount = (id: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
if (!isLoggedIn(getState)) return null;
dispatch(unfollowAccountRequest(id));
return api(getState)
.post(`/api/v1/accounts/${id}/unfollow`)
.then(response => dispatch(unfollowAccountSuccess(response.data, getState().statuses)))
.catch(error => dispatch(unfollowAccountFail(error)));
};
const followAccountRequest = (id: string, locked: boolean) => ({
type: ACCOUNT_FOLLOW_REQUEST,
id,
locked,
skipLoading: true,
});
const followAccountSuccess = (relationship: APIEntity, alreadyFollowing?: boolean) => ({
type: ACCOUNT_FOLLOW_SUCCESS,
relationship,
alreadyFollowing,
skipLoading: true,
});
const followAccountFail = (error: AxiosError, locked: boolean) => ({
type: ACCOUNT_FOLLOW_FAIL,
error,
locked,
skipLoading: true,
});
const unfollowAccountRequest = (id: string) => ({
type: ACCOUNT_UNFOLLOW_REQUEST,
id,
skipLoading: true,
});
const unfollowAccountSuccess = (relationship: APIEntity, statuses: ImmutableMap<string, Status>) => ({
type: ACCOUNT_UNFOLLOW_SUCCESS,
relationship,
statuses,
skipLoading: true,
});
const unfollowAccountFail = (error: AxiosError) => ({
type: ACCOUNT_UNFOLLOW_FAIL,
error,
skipLoading: true,
});
const blockAccount = (id: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
if (!isLoggedIn(getState)) return null;
@ -311,6 +231,7 @@ const blockAccount = (id: string) =>
return api(getState)
.post(`/api/v1/accounts/${id}/block`)
.then(response => {
dispatch(importEntities([response.data], Entities.RELATIONSHIPS));
// Pass in entire statuses map so we can use it to filter stuff in different parts of the reducers
return dispatch(blockAccountSuccess(response.data, getState().statuses));
}).catch(error => dispatch(blockAccountFail(error)));
@ -324,7 +245,10 @@ const unblockAccount = (id: string) =>
return api(getState)
.post(`/api/v1/accounts/${id}/unblock`)
.then(response => dispatch(unblockAccountSuccess(response.data)))
.then(response => {
dispatch(importEntities([response.data], Entities.RELATIONSHIPS));
return dispatch(unblockAccountSuccess(response.data));
})
.catch(error => dispatch(unblockAccountFail(error)));
};
@ -384,6 +308,7 @@ const muteAccount = (id: string, notifications?: boolean, duration = 0) =>
return api(getState)
.post(`/api/v1/accounts/${id}/mute`, params)
.then(response => {
dispatch(importEntities([response.data], Entities.RELATIONSHIPS));
// Pass in entire statuses map so we can use it to filter stuff in different parts of the reducers
return dispatch(muteAccountSuccess(response.data, getState().statuses));
})
@ -398,7 +323,10 @@ const unmuteAccount = (id: string) =>
return api(getState)
.post(`/api/v1/accounts/${id}/unmute`)
.then(response => dispatch(unmuteAccountSuccess(response.data)))
.then(response => {
dispatch(importEntities([response.data], Entities.RELATIONSHIPS));
return dispatch(unmuteAccountSuccess(response.data));
})
.catch(error => dispatch(unmuteAccountFail(error)));
};
@ -690,7 +618,10 @@ const fetchRelationships = (accountIds: string[]) =>
return api(getState)
.get(`/api/v1/accounts/relationships?${newAccountIds.map(id => `id[]=${id}`).join('&')}`)
.then(response => dispatch(fetchRelationshipsSuccess(response.data)))
.then(response => {
dispatch(importEntities(response.data, Entities.RELATIONSHIPS));
dispatch(fetchRelationshipsSuccess(response.data));
})
.catch(error => dispatch(fetchRelationshipsFail(error)));
};
@ -988,12 +919,6 @@ export {
ACCOUNT_FETCH_REQUEST,
ACCOUNT_FETCH_SUCCESS,
ACCOUNT_FETCH_FAIL,
ACCOUNT_FOLLOW_REQUEST,
ACCOUNT_FOLLOW_SUCCESS,
ACCOUNT_FOLLOW_FAIL,
ACCOUNT_UNFOLLOW_REQUEST,
ACCOUNT_UNFOLLOW_SUCCESS,
ACCOUNT_UNFOLLOW_FAIL,
ACCOUNT_BLOCK_REQUEST,
ACCOUNT_BLOCK_SUCCESS,
ACCOUNT_BLOCK_FAIL,
@ -1069,14 +994,6 @@ export {
fetchAccountRequest,
fetchAccountSuccess,
fetchAccountFail,
followAccount,
unfollowAccount,
followAccountRequest,
followAccountSuccess,
followAccountFail,
unfollowAccountRequest,
unfollowAccountSuccess,
unfollowAccountFail,
blockAccount,
unblockAccount,
blockAccountRequest,

Wyświetl plik

@ -2,6 +2,7 @@ import { defineMessages } from 'react-intl';
import { fetchRelationships } from 'soapbox/actions/accounts';
import { importFetchedAccount, importFetchedAccounts, importFetchedStatuses } from 'soapbox/actions/importer';
import { accountIdsToAccts } from 'soapbox/selectors';
import toast from 'soapbox/toast';
import { filterBadges, getTagDiff } from 'soapbox/utils/badges';
import { getFeatures } from 'soapbox/utils/features';
@ -74,14 +75,6 @@ const ADMIN_REMOVE_PERMISSION_GROUP_REQUEST = 'ADMIN_REMOVE_PERMISSION_GROUP_REQ
const ADMIN_REMOVE_PERMISSION_GROUP_SUCCESS = 'ADMIN_REMOVE_PERMISSION_GROUP_SUCCESS';
const ADMIN_REMOVE_PERMISSION_GROUP_FAIL = 'ADMIN_REMOVE_PERMISSION_GROUP_FAIL';
const ADMIN_USERS_SUGGEST_REQUEST = 'ADMIN_USERS_SUGGEST_REQUEST';
const ADMIN_USERS_SUGGEST_SUCCESS = 'ADMIN_USERS_SUGGEST_SUCCESS';
const ADMIN_USERS_SUGGEST_FAIL = 'ADMIN_USERS_SUGGEST_FAIL';
const ADMIN_USERS_UNSUGGEST_REQUEST = 'ADMIN_USERS_UNSUGGEST_REQUEST';
const ADMIN_USERS_UNSUGGEST_SUCCESS = 'ADMIN_USERS_UNSUGGEST_SUCCESS';
const ADMIN_USERS_UNSUGGEST_FAIL = 'ADMIN_USERS_UNSUGGEST_FAIL';
const ADMIN_USER_INDEX_EXPAND_FAIL = 'ADMIN_USER_INDEX_EXPAND_FAIL';
const ADMIN_USER_INDEX_EXPAND_REQUEST = 'ADMIN_USER_INDEX_EXPAND_REQUEST';
const ADMIN_USER_INDEX_EXPAND_SUCCESS = 'ADMIN_USER_INDEX_EXPAND_SUCCESS';
@ -121,13 +114,11 @@ const messages = defineMessages({
announcementUpdateSuccess: { id: 'admin.edit_announcement.updated', defaultMessage: 'Announcement edited' },
});
const nicknamesFromIds = (getState: () => RootState, ids: string[]) => ids.map(id => getState().accounts.get(id)!.acct);
const fetchConfig = () =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch({ type: ADMIN_CONFIG_FETCH_REQUEST });
return api(getState)
.get('/api/pleroma/admin/config')
.get('/api/v1/pleroma/admin/config')
.then(({ data }) => {
dispatch({ type: ADMIN_CONFIG_FETCH_SUCCESS, configs: data.configs, needsReboot: data.need_reboot });
}).catch(error => {
@ -139,7 +130,7 @@ const updateConfig = (configs: Record<string, any>[]) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch({ type: ADMIN_CONFIG_UPDATE_REQUEST, configs });
return api(getState)
.post('/api/pleroma/admin/config', { configs })
.post('/api/v1/pleroma/admin/config', { configs })
.then(({ data }) => {
dispatch({ type: ADMIN_CONFIG_UPDATE_SUCCESS, configs: data.configs, needsReboot: data.need_reboot });
}).catch(error => {
@ -178,7 +169,7 @@ const fetchMastodonReports = (params: Record<string, any>) =>
const fetchPleromaReports = (params: Record<string, any>) =>
(dispatch: AppDispatch, getState: () => RootState) =>
api(getState)
.get('/api/pleroma/admin/reports', { params })
.get('/api/v1/pleroma/admin/reports', { params })
.then(({ data: { reports } }) => {
reports.forEach((report: APIEntity) => {
dispatch(importFetchedAccount(report.account));
@ -224,7 +215,7 @@ const patchMastodonReports = (reports: { id: string, state: string }[]) =>
const patchPleromaReports = (reports: { id: string, state: string }[]) =>
(dispatch: AppDispatch, getState: () => RootState) =>
api(getState)
.patch('/api/pleroma/admin/reports', { reports })
.patch('/api/v1/pleroma/admin/reports', { reports })
.then(() => {
dispatch({ type: ADMIN_REPORTS_PATCH_SUCCESS, reports });
}).catch(error => {
@ -286,7 +277,7 @@ const fetchPleromaUsers = (filters: string[], page: number, query?: string | nul
if (query) params.query = query;
return api(getState)
.get('/api/pleroma/admin/users', { params })
.get('/api/v1/pleroma/admin/users', { params })
.then(({ data: { users, count, page_size: pageSize } }) => {
dispatch(fetchRelationships(users.map((user: APIEntity) => user.id)));
dispatch({ type: ADMIN_USERS_FETCH_SUCCESS, users, count, pageSize, filters, page });
@ -329,9 +320,9 @@ const deactivateMastodonUsers = (accountIds: string[], reportId?: string) =>
const deactivatePleromaUsers = (accountIds: string[]) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const nicknames = nicknamesFromIds(getState, accountIds);
const nicknames = accountIdsToAccts(getState(), accountIds);
return api(getState)
.patch('/api/pleroma/admin/users/deactivate', { nicknames })
.patch('/api/v1/pleroma/admin/users/deactivate', { nicknames })
.then(({ data: { users } }) => {
dispatch({ type: ADMIN_USERS_DEACTIVATE_SUCCESS, users, accountIds });
}).catch(error => {
@ -357,10 +348,10 @@ const deactivateUsers = (accountIds: string[], reportId?: string) =>
const deleteUsers = (accountIds: string[]) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const nicknames = nicknamesFromIds(getState, accountIds);
const nicknames = accountIdsToAccts(getState(), accountIds);
dispatch({ type: ADMIN_USERS_DELETE_REQUEST, accountIds });
return api(getState)
.delete('/api/pleroma/admin/users', { data: { nicknames } })
.delete('/api/v1/pleroma/admin/users', { data: { nicknames } })
.then(({ data: nicknames }) => {
dispatch({ type: ADMIN_USERS_DELETE_SUCCESS, nicknames, accountIds });
}).catch(error => {
@ -382,9 +373,9 @@ const approveMastodonUsers = (accountIds: string[]) =>
const approvePleromaUsers = (accountIds: string[]) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const nicknames = nicknamesFromIds(getState, accountIds);
const nicknames = accountIdsToAccts(getState(), accountIds);
return api(getState)
.patch('/api/pleroma/admin/users/approve', { nicknames })
.patch('/api/v1/pleroma/admin/users/approve', { nicknames })
.then(({ data: { users } }) => {
dispatch({ type: ADMIN_USERS_APPROVE_SUCCESS, users, accountIds });
}).catch(error => {
@ -412,7 +403,7 @@ const deleteStatus = (id: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch({ type: ADMIN_STATUS_DELETE_REQUEST, id });
return api(getState)
.delete(`/api/pleroma/admin/statuses/${id}`)
.delete(`/api/v1/pleroma/admin/statuses/${id}`)
.then(() => {
dispatch({ type: ADMIN_STATUS_DELETE_SUCCESS, id });
}).catch(error => {
@ -424,7 +415,7 @@ const toggleStatusSensitivity = (id: string, sensitive: boolean) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch({ type: ADMIN_STATUS_TOGGLE_SENSITIVITY_REQUEST, id });
return api(getState)
.put(`/api/pleroma/admin/statuses/${id}`, { sensitive: !sensitive })
.put(`/api/v1/pleroma/admin/statuses/${id}`, { sensitive: !sensitive })
.then(() => {
dispatch({ type: ADMIN_STATUS_TOGGLE_SENSITIVITY_SUCCESS, id });
}).catch(error => {
@ -436,7 +427,7 @@ const fetchModerationLog = (params?: Record<string, any>) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch({ type: ADMIN_LOG_FETCH_REQUEST });
return api(getState)
.get('/api/pleroma/admin/moderation_log', { params })
.get('/api/v1/pleroma/admin/moderation_log', { params })
.then(({ data }) => {
dispatch({ type: ADMIN_LOG_FETCH_SUCCESS, items: data.items, total: data.total });
return data;
@ -447,7 +438,7 @@ const fetchModerationLog = (params?: Record<string, any>) =>
const tagUsers = (accountIds: string[], tags: string[]) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const nicknames = nicknamesFromIds(getState, accountIds);
const nicknames = accountIdsToAccts(getState(), accountIds);
dispatch({ type: ADMIN_USERS_TAG_REQUEST, accountIds, tags });
return api(getState)
.put('/api/v1/pleroma/admin/users/tag', { nicknames, tags })
@ -460,7 +451,7 @@ const tagUsers = (accountIds: string[], tags: string[]) =>
const untagUsers = (accountIds: string[], tags: string[]) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const nicknames = nicknamesFromIds(getState, accountIds);
const nicknames = accountIdsToAccts(getState(), accountIds);
// Legacy: allow removing legacy 'donor' tags.
if (tags.includes('badge:donor')) {
@ -495,17 +486,9 @@ const setBadges = (accountId: string, oldTags: string[], newTags: string[]) =>
return dispatch(setTags(accountId, oldBadges, newBadges));
};
const verifyUser = (accountId: string) =>
(dispatch: AppDispatch) =>
dispatch(tagUsers([accountId], ['verified']));
const unverifyUser = (accountId: string) =>
(dispatch: AppDispatch) =>
dispatch(untagUsers([accountId], ['verified']));
const addPermission = (accountIds: string[], permissionGroup: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const nicknames = nicknamesFromIds(getState, accountIds);
const nicknames = accountIdsToAccts(getState(), accountIds);
dispatch({ type: ADMIN_ADD_PERMISSION_GROUP_REQUEST, accountIds, permissionGroup });
return api(getState)
.post(`/api/v1/pleroma/admin/users/permission_group/${permissionGroup}`, { nicknames })
@ -518,7 +501,7 @@ const addPermission = (accountIds: string[], permissionGroup: string) =>
const removePermission = (accountIds: string[], permissionGroup: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const nicknames = nicknamesFromIds(getState, accountIds);
const nicknames = accountIdsToAccts(getState(), accountIds);
dispatch({ type: ADMIN_REMOVE_PERMISSION_GROUP_REQUEST, accountIds, permissionGroup });
return api(getState)
.delete(`/api/v1/pleroma/admin/users/permission_group/${permissionGroup}`, { data: { nicknames } })
@ -562,32 +545,6 @@ const setRole = (accountId: string, role: 'user' | 'moderator' | 'admin') =>
}
};
const suggestUsers = (accountIds: string[]) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const nicknames = nicknamesFromIds(getState, accountIds);
dispatch({ type: ADMIN_USERS_SUGGEST_REQUEST, accountIds });
return api(getState)
.patch('/api/pleroma/admin/users/suggest', { nicknames })
.then(({ data: { users } }) => {
dispatch({ type: ADMIN_USERS_SUGGEST_SUCCESS, users, accountIds });
}).catch(error => {
dispatch({ type: ADMIN_USERS_SUGGEST_FAIL, error, accountIds });
});
};
const unsuggestUsers = (accountIds: string[]) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const nicknames = nicknamesFromIds(getState, accountIds);
dispatch({ type: ADMIN_USERS_UNSUGGEST_REQUEST, accountIds });
return api(getState)
.patch('/api/pleroma/admin/users/unsuggest', { nicknames })
.then(({ data: { users } }) => {
dispatch({ type: ADMIN_USERS_UNSUGGEST_SUCCESS, users, accountIds });
}).catch(error => {
dispatch({ type: ADMIN_USERS_UNSUGGEST_FAIL, error, accountIds });
});
};
const setUserIndexQuery = (query: string) => ({ type: ADMIN_USER_INDEX_QUERY_SET, query });
const fetchUserIndex = () =>
@ -636,7 +593,7 @@ const fetchAdminAnnouncements = () =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch({ type: ADMIN_ANNOUNCEMENTS_FETCH_REQUEST });
return api(getState)
.get('/api/pleroma/admin/announcements', { params: { limit: 50 } })
.get('/api/v1/pleroma/admin/announcements', { params: { limit: 50 } })
.then(({ data }) => {
dispatch({ type: ADMIN_ANNOUNCEMENTS_FETCH_SUCCESS, announcements: data });
return data;
@ -651,7 +608,7 @@ const expandAdminAnnouncements = () =>
dispatch({ type: ADMIN_ANNOUNCEMENTS_EXPAND_REQUEST });
return api(getState)
.get('/api/pleroma/admin/announcements', { params: { limit: 50, offset: page * 50 } })
.get('/api/v1/pleroma/admin/announcements', { params: { limit: 50, offset: page * 50 } })
.then(({ data }) => {
dispatch({ type: ADMIN_ANNOUNCEMENTS_EXPAND_SUCCESS, announcements: data });
return data;
@ -687,7 +644,7 @@ const handleCreateAnnouncement = () =>
const { id, content, starts_at, ends_at, all_day } = getState().admin_announcements.form;
return api(getState)[id ? 'patch' : 'post'](
id ? `/api/pleroma/admin/announcements/${id}` : '/api/pleroma/admin/announcements',
id ? `/api/v1/pleroma/admin/announcements/${id}` : '/api/v1/pleroma/admin/announcements',
{ content, starts_at, ends_at, all_day },
).then(({ data }) => {
dispatch({ type: ADMIN_ANNOUNCEMENT_CREATE_SUCCESS, announcement: data });
@ -703,7 +660,7 @@ const deleteAnnouncement = (id: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch({ type: ADMIN_ANNOUNCEMENT_DELETE_REQUEST, id });
return api(getState).delete(`/api/pleroma/admin/announcements/${id}`).then(({ data }) => {
return api(getState).delete(`/api/v1/pleroma/admin/announcements/${id}`).then(({ data }) => {
dispatch({ type: ADMIN_ANNOUNCEMENT_DELETE_SUCCESS, id });
toast.success(messages.announcementDeleteSuccess);
dispatch(fetchAdminAnnouncements());
@ -765,12 +722,6 @@ export {
ADMIN_REMOVE_PERMISSION_GROUP_REQUEST,
ADMIN_REMOVE_PERMISSION_GROUP_SUCCESS,
ADMIN_REMOVE_PERMISSION_GROUP_FAIL,
ADMIN_USERS_SUGGEST_REQUEST,
ADMIN_USERS_SUGGEST_SUCCESS,
ADMIN_USERS_SUGGEST_FAIL,
ADMIN_USERS_UNSUGGEST_REQUEST,
ADMIN_USERS_UNSUGGEST_SUCCESS,
ADMIN_USERS_UNSUGGEST_FAIL,
ADMIN_USER_INDEX_EXPAND_FAIL,
ADMIN_USER_INDEX_EXPAND_REQUEST,
ADMIN_USER_INDEX_EXPAND_SUCCESS,
@ -811,16 +762,12 @@ export {
untagUsers,
setTags,
setBadges,
verifyUser,
unverifyUser,
addPermission,
removePermission,
promoteToAdmin,
promoteToModerator,
demoteToUser,
setRole,
suggestUsers,
unsuggestUsers,
setUserIndexQuery,
fetchUserIndex,
expandUserIndex,

Wyświetl plik

@ -10,8 +10,8 @@ import { importFetchedAccounts } from './importer';
import { patchMeSuccess } from './me';
import type { AxiosError } from 'axios';
import type { Account } from 'soapbox/schemas';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { APIEntity, Account } from 'soapbox/types/entities';
const ALIASES_FETCH_REQUEST = 'ALIASES_FETCH_REQUEST';
const ALIASES_FETCH_SUCCESS = 'ALIASES_FETCH_SUCCESS';
@ -56,7 +56,7 @@ const fetchAliasesRequest = () => ({
type: ALIASES_FETCH_REQUEST,
});
const fetchAliasesSuccess = (aliases: APIEntity[]) => ({
const fetchAliasesSuccess = (aliases: unknown[]) => ({
type: ALIASES_FETCH_SUCCESS,
value: aliases,
});
@ -82,7 +82,7 @@ const fetchAliasesSuggestions = (q: string) =>
}).catch(error => toast.showAlertForError(error));
};
const fetchAliasesSuggestionsReady = (query: string, accounts: APIEntity[]) => ({
const fetchAliasesSuggestionsReady = (query: string, accounts: unknown[]) => ({
type: ALIASES_SUGGESTIONS_READY,
query,
accounts,
@ -111,7 +111,7 @@ const addToAliases = (account: Account) =>
dispatch(addToAliasesRequest());
api(getState).patch('/api/v1/accounts/update_credentials', { also_known_as: [...alsoKnownAs, account.pleroma.get('ap_id')] })
api(getState).patch('/api/v1/accounts/update_credentials', { also_known_as: [...alsoKnownAs, account.pleroma?.ap_id] })
.then((response => {
toast.success(messages.createSuccess);
dispatch(addToAliasesSuccess);

Wyświetl plik

@ -16,6 +16,7 @@ import { obtainOAuthToken, revokeOAuthToken } from 'soapbox/actions/oauth';
import { startOnboarding } from 'soapbox/actions/onboarding';
import { custom } from 'soapbox/custom';
import { queryClient } from 'soapbox/queries/client';
import { selectAccount } from 'soapbox/selectors';
import KVStore from 'soapbox/storage/kv-store';
import toast from 'soapbox/toast';
import { getLoggedInAccount, parseBaseURL } from 'soapbox/utils/auth';
@ -178,8 +179,7 @@ export const rememberAuthAccount = (accountUrl: string) =>
export const loadCredentials = (token: string, accountUrl: string) =>
(dispatch: AppDispatch) => dispatch(rememberAuthAccount(accountUrl))
.then(() => dispatch(verifyCredentials(token, accountUrl)))
.catch(() => dispatch(verifyCredentials(token, accountUrl)));
.finally(() => dispatch(verifyCredentials(token, accountUrl)));
export const logIn = (username: string, password: string) =>
(dispatch: AppDispatch) => dispatch(getAuthApp()).then(() => {
@ -228,7 +228,7 @@ export const logOut = () =>
export const switchAccount = (accountId: string, background = false) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const account = getState().accounts.get(accountId);
const account = selectAccount(getState(), accountId);
// Clear all stored cache from React Query
queryClient.invalidateQueries();
queryClient.clear();
@ -240,9 +240,10 @@ export const fetchOwnAccounts = () =>
(dispatch: AppDispatch, getState: () => RootState) => {
const state = getState();
return state.auth.users.forEach((user) => {
const account = state.accounts.get(user.id);
const account = selectAccount(state, user.id);
if (!account) {
dispatch(verifyCredentials(user.access_token, user.url));
dispatch(verifyCredentials(user.access_token, user.url))
.catch(() => console.warn(`Failed to load account: ${user.url}`));
}
});
};

Wyświetl plik

@ -6,9 +6,8 @@ import api, { getLinks } from '../api';
import { fetchRelationships } from './accounts';
import { importFetchedAccounts } from './importer';
import type { AnyAction } from '@reduxjs/toolkit';
import type { AxiosError } from 'axios';
import type { RootState } from 'soapbox/store';
import type { AppDispatch, RootState } from 'soapbox/store';
const BLOCKS_FETCH_REQUEST = 'BLOCKS_FETCH_REQUEST';
const BLOCKS_FETCH_SUCCESS = 'BLOCKS_FETCH_SUCCESS';
@ -18,7 +17,7 @@ const BLOCKS_EXPAND_REQUEST = 'BLOCKS_EXPAND_REQUEST';
const BLOCKS_EXPAND_SUCCESS = 'BLOCKS_EXPAND_SUCCESS';
const BLOCKS_EXPAND_FAIL = 'BLOCKS_EXPAND_FAIL';
const fetchBlocks = () => (dispatch: React.Dispatch<AnyAction>, getState: () => RootState) => {
const fetchBlocks = () => (dispatch: AppDispatch, getState: () => RootState) => {
if (!isLoggedIn(getState)) return null;
const nextLinkName = getNextLinkName(getState);
@ -54,7 +53,7 @@ function fetchBlocksFail(error: AxiosError) {
};
}
const expandBlocks = () => (dispatch: React.Dispatch<AnyAction>, getState: () => RootState) => {
const expandBlocks = () => (dispatch: AppDispatch, getState: () => RootState) => {
if (!isLoggedIn(getState)) return null;
const nextLinkName = getNextLinkName(getState);

Wyświetl plik

@ -4,7 +4,9 @@ import throttle from 'lodash/throttle';
import { defineMessages, IntlShape } from 'react-intl';
import api from 'soapbox/api';
import { search as emojiSearch } from 'soapbox/features/emoji/emoji-mart-search-light';
import { isNativeEmoji } from 'soapbox/features/emoji';
import emojiSearch from 'soapbox/features/emoji/search';
import { selectAccount, selectOwnAccount } from 'soapbox/selectors';
import { tagHistory } from 'soapbox/settings';
import toast from 'soapbox/toast';
import { isLoggedIn } from 'soapbox/utils/auth';
@ -19,70 +21,71 @@ import { openModal, closeModal } from './modals';
import { getSettings } from './settings';
import { createStatus } from './statuses';
import type { Emoji } from 'soapbox/components/autosuggest-emoji';
import type { AutoSuggestion } from 'soapbox/components/autosuggest-input';
import type { Emoji } from 'soapbox/features/emoji';
import type { Account, Group } from 'soapbox/schemas';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { Account, APIEntity, Status, Tag } from 'soapbox/types/entities';
import type { APIEntity, Status, Tag } from 'soapbox/types/entities';
import type { History } from 'soapbox/types/history';
const { CancelToken, isCancel } = axios;
let cancelFetchComposeSuggestionsAccounts: Canceler;
const COMPOSE_CHANGE = 'COMPOSE_CHANGE';
const COMPOSE_SUBMIT_REQUEST = 'COMPOSE_SUBMIT_REQUEST';
const COMPOSE_SUBMIT_SUCCESS = 'COMPOSE_SUBMIT_SUCCESS';
const COMPOSE_SUBMIT_FAIL = 'COMPOSE_SUBMIT_FAIL';
const COMPOSE_REPLY = 'COMPOSE_REPLY';
const COMPOSE_EVENT_REPLY = 'COMPOSE_EVENT_REPLY';
const COMPOSE_REPLY_CANCEL = 'COMPOSE_REPLY_CANCEL';
const COMPOSE_QUOTE = 'COMPOSE_QUOTE';
const COMPOSE_QUOTE_CANCEL = 'COMPOSE_QUOTE_CANCEL';
const COMPOSE_DIRECT = 'COMPOSE_DIRECT';
const COMPOSE_MENTION = 'COMPOSE_MENTION';
const COMPOSE_RESET = 'COMPOSE_RESET';
const COMPOSE_UPLOAD_REQUEST = 'COMPOSE_UPLOAD_REQUEST';
const COMPOSE_UPLOAD_SUCCESS = 'COMPOSE_UPLOAD_SUCCESS';
const COMPOSE_UPLOAD_FAIL = 'COMPOSE_UPLOAD_FAIL';
const COMPOSE_UPLOAD_PROGRESS = 'COMPOSE_UPLOAD_PROGRESS';
const COMPOSE_UPLOAD_UNDO = 'COMPOSE_UPLOAD_UNDO';
const COMPOSE_GROUP_POST = 'COMPOSE_GROUP_POST';
const COMPOSE_CHANGE = 'COMPOSE_CHANGE' as const;
const COMPOSE_SUBMIT_REQUEST = 'COMPOSE_SUBMIT_REQUEST' as const;
const COMPOSE_SUBMIT_SUCCESS = 'COMPOSE_SUBMIT_SUCCESS' as const;
const COMPOSE_SUBMIT_FAIL = 'COMPOSE_SUBMIT_FAIL' as const;
const COMPOSE_REPLY = 'COMPOSE_REPLY' as const;
const COMPOSE_EVENT_REPLY = 'COMPOSE_EVENT_REPLY' as const;
const COMPOSE_REPLY_CANCEL = 'COMPOSE_REPLY_CANCEL' as const;
const COMPOSE_QUOTE = 'COMPOSE_QUOTE' as const;
const COMPOSE_QUOTE_CANCEL = 'COMPOSE_QUOTE_CANCEL' as const;
const COMPOSE_DIRECT = 'COMPOSE_DIRECT' as const;
const COMPOSE_MENTION = 'COMPOSE_MENTION' as const;
const COMPOSE_RESET = 'COMPOSE_RESET' as const;
const COMPOSE_UPLOAD_REQUEST = 'COMPOSE_UPLOAD_REQUEST' as const;
const COMPOSE_UPLOAD_SUCCESS = 'COMPOSE_UPLOAD_SUCCESS' as const;
const COMPOSE_UPLOAD_FAIL = 'COMPOSE_UPLOAD_FAIL' as const;
const COMPOSE_UPLOAD_PROGRESS = 'COMPOSE_UPLOAD_PROGRESS' as const;
const COMPOSE_UPLOAD_UNDO = 'COMPOSE_UPLOAD_UNDO' as const;
const COMPOSE_GROUP_POST = 'COMPOSE_GROUP_POST' as const;
const COMPOSE_SET_GROUP_TIMELINE_VISIBLE = 'COMPOSE_SET_GROUP_TIMELINE_VISIBLE' as const;
const COMPOSE_SUGGESTIONS_CLEAR = 'COMPOSE_SUGGESTIONS_CLEAR';
const COMPOSE_SUGGESTIONS_READY = 'COMPOSE_SUGGESTIONS_READY';
const COMPOSE_SUGGESTION_SELECT = 'COMPOSE_SUGGESTION_SELECT';
const COMPOSE_SUGGESTION_TAGS_UPDATE = 'COMPOSE_SUGGESTION_TAGS_UPDATE';
const COMPOSE_SUGGESTIONS_CLEAR = 'COMPOSE_SUGGESTIONS_CLEAR' as const;
const COMPOSE_SUGGESTIONS_READY = 'COMPOSE_SUGGESTIONS_READY' as const;
const COMPOSE_SUGGESTION_SELECT = 'COMPOSE_SUGGESTION_SELECT' as const;
const COMPOSE_SUGGESTION_TAGS_UPDATE = 'COMPOSE_SUGGESTION_TAGS_UPDATE' as const;
const COMPOSE_TAG_HISTORY_UPDATE = 'COMPOSE_TAG_HISTORY_UPDATE';
const COMPOSE_TAG_HISTORY_UPDATE = 'COMPOSE_TAG_HISTORY_UPDATE' as const;
const COMPOSE_SPOILERNESS_CHANGE = 'COMPOSE_SPOILERNESS_CHANGE';
const COMPOSE_TYPE_CHANGE = 'COMPOSE_TYPE_CHANGE';
const COMPOSE_SPOILER_TEXT_CHANGE = 'COMPOSE_SPOILER_TEXT_CHANGE';
const COMPOSE_VISIBILITY_CHANGE = 'COMPOSE_VISIBILITY_CHANGE';
const COMPOSE_LISTABILITY_CHANGE = 'COMPOSE_LISTABILITY_CHANGE';
const COMPOSE_COMPOSING_CHANGE = 'COMPOSE_COMPOSING_CHANGE';
const COMPOSE_SPOILERNESS_CHANGE = 'COMPOSE_SPOILERNESS_CHANGE' as const;
const COMPOSE_TYPE_CHANGE = 'COMPOSE_TYPE_CHANGE' as const;
const COMPOSE_SPOILER_TEXT_CHANGE = 'COMPOSE_SPOILER_TEXT_CHANGE' as const;
const COMPOSE_VISIBILITY_CHANGE = 'COMPOSE_VISIBILITY_CHANGE' as const;
const COMPOSE_LISTABILITY_CHANGE = 'COMPOSE_LISTABILITY_CHANGE' as const;
const COMPOSE_EMOJI_INSERT = 'COMPOSE_EMOJI_INSERT';
const COMPOSE_EMOJI_INSERT = 'COMPOSE_EMOJI_INSERT' as const;
const COMPOSE_UPLOAD_CHANGE_REQUEST = 'COMPOSE_UPLOAD_UPDATE_REQUEST';
const COMPOSE_UPLOAD_CHANGE_SUCCESS = 'COMPOSE_UPLOAD_UPDATE_SUCCESS';
const COMPOSE_UPLOAD_CHANGE_FAIL = 'COMPOSE_UPLOAD_UPDATE_FAIL';
const COMPOSE_UPLOAD_CHANGE_REQUEST = 'COMPOSE_UPLOAD_UPDATE_REQUEST' as const;
const COMPOSE_UPLOAD_CHANGE_SUCCESS = 'COMPOSE_UPLOAD_UPDATE_SUCCESS' as const;
const COMPOSE_UPLOAD_CHANGE_FAIL = 'COMPOSE_UPLOAD_UPDATE_FAIL' as const;
const COMPOSE_POLL_ADD = 'COMPOSE_POLL_ADD';
const COMPOSE_POLL_REMOVE = 'COMPOSE_POLL_REMOVE';
const COMPOSE_POLL_OPTION_ADD = 'COMPOSE_POLL_OPTION_ADD';
const COMPOSE_POLL_OPTION_CHANGE = 'COMPOSE_POLL_OPTION_CHANGE';
const COMPOSE_POLL_OPTION_REMOVE = 'COMPOSE_POLL_OPTION_REMOVE';
const COMPOSE_POLL_SETTINGS_CHANGE = 'COMPOSE_POLL_SETTINGS_CHANGE';
const COMPOSE_POLL_ADD = 'COMPOSE_POLL_ADD' as const;
const COMPOSE_POLL_REMOVE = 'COMPOSE_POLL_REMOVE' as const;
const COMPOSE_POLL_OPTION_ADD = 'COMPOSE_POLL_OPTION_ADD' as const;
const COMPOSE_POLL_OPTION_CHANGE = 'COMPOSE_POLL_OPTION_CHANGE' as const;
const COMPOSE_POLL_OPTION_REMOVE = 'COMPOSE_POLL_OPTION_REMOVE' as const;
const COMPOSE_POLL_SETTINGS_CHANGE = 'COMPOSE_POLL_SETTINGS_CHANGE' as const;
const COMPOSE_SCHEDULE_ADD = 'COMPOSE_SCHEDULE_ADD';
const COMPOSE_SCHEDULE_SET = 'COMPOSE_SCHEDULE_SET';
const COMPOSE_SCHEDULE_REMOVE = 'COMPOSE_SCHEDULE_REMOVE';
const COMPOSE_SCHEDULE_ADD = 'COMPOSE_SCHEDULE_ADD' as const;
const COMPOSE_SCHEDULE_SET = 'COMPOSE_SCHEDULE_SET' as const;
const COMPOSE_SCHEDULE_REMOVE = 'COMPOSE_SCHEDULE_REMOVE' as const;
const COMPOSE_ADD_TO_MENTIONS = 'COMPOSE_ADD_TO_MENTIONS';
const COMPOSE_REMOVE_FROM_MENTIONS = 'COMPOSE_REMOVE_FROM_MENTIONS';
const COMPOSE_ADD_TO_MENTIONS = 'COMPOSE_ADD_TO_MENTIONS' as const;
const COMPOSE_REMOVE_FROM_MENTIONS = 'COMPOSE_REMOVE_FROM_MENTIONS' as const;
const COMPOSE_SET_STATUS = 'COMPOSE_SET_STATUS';
const COMPOSE_SET_STATUS = 'COMPOSE_SET_STATUS' as const;
const messages = defineMessages({
exceededImageSizeLimit: { id: 'upload_error.image_size_limit', defaultMessage: 'Image exceeds the current file size limit ({limit})' },
@ -98,12 +101,24 @@ const messages = defineMessages({
replyMessage: { id: 'confirmations.reply.message', defaultMessage: 'Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?' },
});
interface ComposeSetStatusAction {
type: typeof COMPOSE_SET_STATUS
id: string
status: Status
rawText: string
explicitAddressing: boolean
spoilerText?: string
contentType?: string | false
v: ReturnType<typeof parseVersion>
withRedraft?: boolean
}
const setComposeToStatus = (status: Status, rawText: string, spoilerText?: string, contentType?: string | false, withRedraft?: boolean) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const { instance } = getState();
const { explicitAddressing } = getFeatures(instance);
dispatch({
const action: ComposeSetStatusAction = {
type: COMPOSE_SET_STATUS,
id: 'compose-modal',
status,
@ -113,7 +128,9 @@ const setComposeToStatus = (status: Status, rawText: string, spoilerText?: strin
contentType,
v: parseVersion(instance.version),
withRedraft,
});
};
dispatch(action);
};
const changeCompose = (composeId: string, text: string) => ({
@ -122,20 +139,35 @@ const changeCompose = (composeId: string, text: string) => ({
text: text,
});
interface ComposeReplyAction {
type: typeof COMPOSE_REPLY
id: string
status: Status
account: Account
explicitAddressing: boolean
preserveSpoilers: boolean
}
const replyCompose = (status: Status) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const state = getState();
const instance = state.instance;
const { explicitAddressing } = getFeatures(instance);
const preserveSpoilers = !!getSettings(state).get('preserveSpoilers');
const account = selectOwnAccount(state);
dispatch({
if (!account) return;
const action: ComposeReplyAction = {
type: COMPOSE_REPLY,
id: 'compose-modal',
status: status,
account: state.accounts.get(state.me),
account,
explicitAddressing,
});
preserveSpoilers,
};
dispatch(action);
dispatch(openModal('COMPOSE'));
};
@ -144,20 +176,29 @@ const cancelReplyCompose = () => ({
id: 'compose-modal',
});
interface ComposeQuoteAction {
type: typeof COMPOSE_QUOTE
id: string
status: Status
account: Account | undefined
explicitAddressing: boolean
}
const quoteCompose = (status: Status) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const state = getState();
const instance = state.instance;
const { explicitAddressing } = getFeatures(instance);
dispatch({
const action: ComposeQuoteAction = {
type: COMPOSE_QUOTE,
id: 'compose-modal',
status: status,
account: state.accounts.get(state.me),
account: selectOwnAccount(state),
explicitAddressing,
});
};
dispatch(action);
dispatch(openModal('COMPOSE'));
};
@ -166,43 +207,67 @@ const cancelQuoteCompose = () => ({
id: 'compose-modal',
});
const groupComposeModal = (group: Group) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const composeId = `group:${group.id}`;
dispatch(groupCompose(composeId, group.id));
dispatch(openModal('COMPOSE', { composeId }));
};
const resetCompose = (composeId = 'compose-modal') => ({
type: COMPOSE_RESET,
id: composeId,
});
interface ComposeMentionAction {
type: typeof COMPOSE_MENTION
id: string
account: Account
}
const mentionCompose = (account: Account) =>
(dispatch: AppDispatch) => {
dispatch({
const action: ComposeMentionAction = {
type: COMPOSE_MENTION,
id: 'compose-modal',
account: account,
});
};
dispatch(action);
dispatch(openModal('COMPOSE'));
};
interface ComposeDirectAction {
type: typeof COMPOSE_DIRECT
id: string
account: Account
}
const directCompose = (account: Account) =>
(dispatch: AppDispatch) => {
dispatch({
const action: ComposeDirectAction = {
type: COMPOSE_DIRECT,
id: 'compose-modal',
account: account,
});
account,
};
dispatch(action);
dispatch(openModal('COMPOSE'));
};
const directComposeById = (accountId: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const account = getState().accounts.get(accountId);
const account = selectAccount(getState(), accountId);
if (!account) return;
dispatch({
const action: ComposeDirectAction = {
type: COMPOSE_DIRECT,
id: 'compose-modal',
account: account,
});
account,
};
dispatch(action);
dispatch(openModal('COMPOSE'));
};
@ -277,7 +342,7 @@ const submitCompose = (composeId: string, routerHistory?: History, force = false
const idempotencyKey = compose.idempotencyKey;
const params = {
const params: Record<string, any> = {
status,
in_reply_to_id: compose.in_reply_to,
quote_id: compose.quote,
@ -289,9 +354,13 @@ const submitCompose = (composeId: string, routerHistory?: History, force = false
poll: compose.poll,
scheduled_at: compose.schedule,
to,
group_id: compose.privacy === 'group' ? compose.group_id : null,
};
if (compose.privacy === 'group') {
params.group_id = compose.group_id;
params.group_timeline_visible = compose.group_timeline_visible; // Truth Social
}
dispatch(createStatus(params, idempotencyKey, statusId)).then(function(data) {
if (!statusId && data.visibility === 'direct' && getState().conversations.mounted <= 0 && routerHistory) {
routerHistory.push('/messages');
@ -472,14 +541,17 @@ const undoUploadCompose = (composeId: string, media_id: string) => ({
media_id: media_id,
});
const groupCompose = (composeId: string, groupId: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch({
type: COMPOSE_GROUP_POST,
id: composeId,
group_id: groupId,
});
};
const groupCompose = (composeId: string, groupId: string) => ({
type: COMPOSE_GROUP_POST,
id: composeId,
group_id: groupId,
});
const setGroupTimelineVisible = (composeId: string, groupTimelineVisible: boolean) => ({
type: COMPOSE_SET_GROUP_TIMELINE_VISIBLE,
id: composeId,
groupTimelineVisible,
});
const clearComposeSuggestions = (composeId: string) => {
if (cancelFetchComposeSuggestionsAccounts) {
@ -515,7 +587,9 @@ const fetchComposeSuggestionsAccounts = throttle((dispatch, getState, composeId,
}, 200, { leading: true, trailing: true });
const fetchComposeSuggestionsEmojis = (dispatch: AppDispatch, getState: () => RootState, composeId: string, token: string) => {
const results = emojiSearch(token.replace(':', ''), { maxResults: 5 } as any);
const state = getState();
const results = emojiSearch(token.replace(':', ''), { maxResults: 5 }, state.custom_emojis);
dispatch(readyComposeSuggestionsEmojis(composeId, token, results));
};
@ -541,6 +615,14 @@ const fetchComposeSuggestions = (composeId: string, token: string) =>
}
};
interface ComposeSuggestionsReadyAction {
type: typeof COMPOSE_SUGGESTIONS_READY
id: string
token: string
emojis?: Emoji[]
accounts?: APIEntity[]
}
const readyComposeSuggestionsEmojis = (composeId: string, token: string, emojis: Emoji[]) => ({
type: COMPOSE_SUGGESTIONS_READY,
id: composeId,
@ -555,31 +637,42 @@ const readyComposeSuggestionsAccounts = (composeId: string, token: string, accou
accounts,
});
interface ComposeSuggestionSelectAction {
type: typeof COMPOSE_SUGGESTION_SELECT
id: string
position: number
token: string | null
completion: string
path: Array<string | number>
}
const selectComposeSuggestion = (composeId: string, position: number, token: string | null, suggestion: AutoSuggestion, path: Array<string | number>) =>
(dispatch: AppDispatch, getState: () => RootState) => {
let completion, startPosition;
let completion = '', startPosition = position;
if (typeof suggestion === 'object' && suggestion.id) {
completion = suggestion.native || suggestion.colons;
completion = isNativeEmoji(suggestion) ? suggestion.native : suggestion.colons;
startPosition = position - 1;
dispatch(useEmoji(suggestion));
} else if (typeof suggestion === 'string' && suggestion[0] === '#') {
completion = suggestion;
startPosition = position - 1;
} else {
completion = getState().accounts.get(suggestion)!.acct;
} else if (typeof suggestion === 'string') {
completion = selectAccount(getState(), suggestion)!.acct;
startPosition = position;
}
dispatch({
const action: ComposeSuggestionSelectAction = {
type: COMPOSE_SUGGESTION_SELECT,
id: composeId,
position: startPosition,
token,
completion,
path,
});
};
dispatch(action);
};
const updateSuggestionTags = (composeId: string, token: string, currentTrends: ImmutableList<Tag>) => ({
@ -689,7 +782,7 @@ const removePollOption = (composeId: string, index: number) => ({
index,
});
const changePollSettings = (composeId: string, expiresIn?: string | number, isMultiple?: boolean) => ({
const changePollSettings = (composeId: string, expiresIn?: number, isMultiple?: boolean) => ({
type: COMPOSE_POLL_SETTINGS_CHANGE,
id: composeId,
expiresIn,
@ -703,30 +796,56 @@ const openComposeWithText = (composeId: string, text = '') =>
dispatch(changeCompose(composeId, text));
};
interface ComposeAddToMentionsAction {
type: typeof COMPOSE_ADD_TO_MENTIONS
id: string
account: string
}
const addToMentions = (composeId: string, accountId: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const state = getState();
const acct = state.accounts.get(accountId)!.acct;
const account = selectAccount(state, accountId);
if (!account) return;
return dispatch({
const action: ComposeAddToMentionsAction = {
type: COMPOSE_ADD_TO_MENTIONS,
id: composeId,
account: acct,
});
account: account.acct,
};
return dispatch(action);
};
interface ComposeRemoveFromMentionsAction {
type: typeof COMPOSE_REMOVE_FROM_MENTIONS
id: string
account: string
}
const removeFromMentions = (composeId: string, accountId: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const state = getState();
const acct = state.accounts.get(accountId)!.acct;
const account = selectAccount(state, accountId);
if (!account) return;
return dispatch({
const action: ComposeRemoveFromMentionsAction = {
type: COMPOSE_REMOVE_FROM_MENTIONS,
id: composeId,
account: acct,
});
account: account.acct,
};
return dispatch(action);
};
interface ComposeEventReplyAction {
type: typeof COMPOSE_EVENT_REPLY
id: string
status: Status
account: Account
explicitAddressing: boolean
}
const eventDiscussionCompose = (composeId: string, status: Status) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const state = getState();
@ -737,11 +856,57 @@ const eventDiscussionCompose = (composeId: string, status: Status) =>
type: COMPOSE_EVENT_REPLY,
id: composeId,
status: status,
account: state.accounts.get(state.me),
account: selectOwnAccount(state),
explicitAddressing,
});
};
type ComposeAction =
ComposeSetStatusAction
| ReturnType<typeof changeCompose>
| ComposeReplyAction
| ReturnType<typeof cancelReplyCompose>
| ComposeQuoteAction
| ReturnType<typeof cancelQuoteCompose>
| ReturnType<typeof resetCompose>
| ComposeMentionAction
| ComposeDirectAction
| ReturnType<typeof submitComposeRequest>
| ReturnType<typeof submitComposeSuccess>
| ReturnType<typeof submitComposeFail>
| ReturnType<typeof changeUploadComposeRequest>
| ReturnType<typeof changeUploadComposeSuccess>
| ReturnType<typeof changeUploadComposeFail>
| ReturnType<typeof uploadComposeRequest>
| ReturnType<typeof uploadComposeProgress>
| ReturnType<typeof uploadComposeSuccess>
| ReturnType<typeof uploadComposeFail>
| ReturnType<typeof undoUploadCompose>
| ReturnType<typeof groupCompose>
| ReturnType<typeof setGroupTimelineVisible>
| ReturnType<typeof clearComposeSuggestions>
| ComposeSuggestionsReadyAction
| ComposeSuggestionSelectAction
| ReturnType<typeof updateSuggestionTags>
| ReturnType<typeof updateTagHistory>
| ReturnType<typeof changeComposeSpoilerness>
| ReturnType<typeof changeComposeContentType>
| ReturnType<typeof changeComposeSpoilerText>
| ReturnType<typeof changeComposeVisibility>
| ReturnType<typeof insertEmojiCompose>
| ReturnType<typeof addPoll>
| ReturnType<typeof removePoll>
| ReturnType<typeof addSchedule>
| ReturnType<typeof setSchedule>
| ReturnType<typeof removeSchedule>
| ReturnType<typeof addPollOption>
| ReturnType<typeof changePollOption>
| ReturnType<typeof removePollOption>
| ReturnType<typeof changePollSettings>
| ComposeAddToMentionsAction
| ComposeRemoveFromMentionsAction
| ComposeEventReplyAction
export {
COMPOSE_CHANGE,
COMPOSE_SUBMIT_REQUEST,
@ -771,7 +936,6 @@ export {
COMPOSE_SPOILER_TEXT_CHANGE,
COMPOSE_VISIBILITY_CHANGE,
COMPOSE_LISTABILITY_CHANGE,
COMPOSE_COMPOSING_CHANGE,
COMPOSE_EMOJI_INSERT,
COMPOSE_UPLOAD_CHANGE_REQUEST,
COMPOSE_UPLOAD_CHANGE_SUCCESS,
@ -788,6 +952,7 @@ export {
COMPOSE_ADD_TO_MENTIONS,
COMPOSE_REMOVE_FROM_MENTIONS,
COMPOSE_SET_STATUS,
COMPOSE_SET_GROUP_TIMELINE_VISIBLE,
setComposeToStatus,
changeCompose,
replyCompose,
@ -814,6 +979,8 @@ export {
uploadComposeFail,
undoUploadCompose,
groupCompose,
groupComposeModal,
setGroupTimelineVisible,
clearComposeSuggestions,
fetchComposeSuggestions,
readyComposeSuggestionsEmojis,
@ -839,4 +1006,5 @@ export {
addToMentions,
removeFromMentions,
eventDiscussionCompose,
type ComposeAction,
};

Wyświetl plik

@ -1,9 +1,11 @@
import { Entities } from 'soapbox/entity-store/entities';
import { isLoggedIn } from 'soapbox/utils/auth';
import api, { getLinks } from '../api';
import type { AxiosError } from 'axios';
import type { List as ImmutableList } from 'immutable';
import type { EntityStore } from 'soapbox/entity-store/types';
import type { Account } from 'soapbox/schemas';
import type { AppDispatch, RootState } from 'soapbox/store';
const DOMAIN_BLOCK_REQUEST = 'DOMAIN_BLOCK_REQUEST';
@ -29,9 +31,9 @@ const blockDomain = (domain: string) =>
dispatch(blockDomainRequest(domain));
api(getState).post('/api/v1/domain_blocks', { domain }).then(() => {
const at_domain = '@' + domain;
const accounts = getState().accounts.filter(item => item.acct.endsWith(at_domain)).valueSeq().map(item => item.id);
dispatch(blockDomainSuccess(domain, accounts.toList()));
const accounts = selectAccountsByDomain(getState(), domain);
if (!accounts) return;
dispatch(blockDomainSuccess(domain, accounts));
}).catch(err => {
dispatch(blockDomainFail(domain, err));
});
@ -42,7 +44,7 @@ const blockDomainRequest = (domain: string) => ({
domain,
});
const blockDomainSuccess = (domain: string, accounts: ImmutableList<string>) => ({
const blockDomainSuccess = (domain: string, accounts: string[]) => ({
type: DOMAIN_BLOCK_SUCCESS,
domain,
accounts,
@ -67,9 +69,9 @@ const unblockDomain = (domain: string) =>
};
api(getState).delete('/api/v1/domain_blocks', params).then(() => {
const at_domain = '@' + domain;
const accounts = getState().accounts.filter(item => item.get('acct').endsWith(at_domain)).valueSeq().map(item => item.get('id'));
dispatch(unblockDomainSuccess(domain, accounts.toList()));
const accounts = selectAccountsByDomain(getState(), domain);
if (!accounts) return;
dispatch(unblockDomainSuccess(domain, accounts));
}).catch(err => {
dispatch(unblockDomainFail(domain, err));
});
@ -80,7 +82,7 @@ const unblockDomainRequest = (domain: string) => ({
domain,
});
const unblockDomainSuccess = (domain: string, accounts: ImmutableList<string>) => ({
const unblockDomainSuccess = (domain: string, accounts: string[]) => ({
type: DOMAIN_UNBLOCK_SUCCESS,
domain,
accounts,
@ -141,6 +143,15 @@ const expandDomainBlocks = () =>
});
};
function selectAccountsByDomain(state: RootState, domain: string): string[] {
const store = state.entities[Entities.ACCOUNTS]?.store as EntityStore<Account> | undefined;
const entries = store ? Object.entries(store) : undefined;
const accounts = entries
?.filter(([_, item]) => item && item.acct.endsWith(`@${domain}`))
.map(([_, item]) => item!.id);
return accounts || [];
}
const expandDomainBlocksRequest = () => ({
type: DOMAIN_BLOCKS_EXPAND_REQUEST,
});

Wyświetl plik

@ -25,7 +25,7 @@ const EMOJI_REACTS_FETCH_FAIL = 'EMOJI_REACTS_FETCH_FAIL';
const noOp = () => () => new Promise(f => f(undefined));
const simpleEmojiReact = (status: Status, emoji: string) =>
const simpleEmojiReact = (status: Status, emoji: string, custom?: string) =>
(dispatch: AppDispatch) => {
const emojiReacts: ImmutableList<ImmutableMap<string, any>> = status.pleroma.get('emoji_reactions') || ImmutableList();
@ -43,7 +43,7 @@ const simpleEmojiReact = (status: Status, emoji: string) =>
if (emoji === '👍') {
dispatch(favourite(status));
} else {
dispatch(emojiReact(status, emoji));
dispatch(emojiReact(status, emoji, custom));
}
}).catch(err => {
console.error(err);
@ -70,14 +70,14 @@ const fetchEmojiReacts = (id: string, emoji: string) =>
});
};
const emojiReact = (status: Status, emoji: string) =>
const emojiReact = (status: Status, emoji: string, custom?: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
if (!isLoggedIn(getState)) return dispatch(noOp());
dispatch(emojiReactRequest(status, emoji));
dispatch(emojiReactRequest(status, emoji, custom));
return api(getState)
.put(`/api/v1/pleroma/statuses/${status.get('id')}/reactions/${emoji}`)
.put(`/api/v1/pleroma/statuses/${status.id}/reactions/${emoji}`)
.then(function(response) {
dispatch(importFetchedStatus(response.data));
dispatch(emojiReactSuccess(status, emoji));
@ -93,7 +93,7 @@ const unEmojiReact = (status: Status, emoji: string) =>
dispatch(unEmojiReactRequest(status, emoji));
return api(getState)
.delete(`/api/v1/pleroma/statuses/${status.get('id')}/reactions/${emoji}`)
.delete(`/api/v1/pleroma/statuses/${status.id}/reactions/${emoji}`)
.then(response => {
dispatch(importFetchedStatus(response.data));
dispatch(unEmojiReactSuccess(status, emoji));
@ -120,10 +120,11 @@ const fetchEmojiReactsFail = (id: string, error: AxiosError) => ({
error,
});
const emojiReactRequest = (status: Status, emoji: string) => ({
const emojiReactRequest = (status: Status, emoji: string, custom?: string) => ({
type: EMOJI_REACT_REQUEST,
status,
emoji,
custom,
skipLoading: true,
});

Wyświetl plik

@ -1,6 +1,6 @@
import { saveSettings } from './settings';
import type { Emoji } from 'soapbox/components/autosuggest-emoji';
import type { Emoji } from 'soapbox/features/emoji';
import type { AppDispatch } from 'soapbox/store';
const EMOJI_USE = 'EMOJI_USE';

Wyświetl plik

@ -569,7 +569,7 @@ const rejectEventParticipationRequestFail = (id: string, accountId: string, erro
});
const fetchEventIcs = (id: string) =>
(dispatch: any, getState: () => RootState) =>
(dispatch: AppDispatch, getState: () => RootState) =>
api(getState).get(`/api/v1/pleroma/events/${id}/ics`);
const cancelEventCompose = () => ({

Wyświetl plik

@ -34,8 +34,8 @@ type ExportDataActions = {
| typeof EXPORT_BLOCKS_FAIL
| typeof EXPORT_MUTES_REQUEST
| typeof EXPORT_MUTES_SUCCESS
| typeof EXPORT_MUTES_FAIL,
error?: any,
| typeof EXPORT_MUTES_FAIL
error?: any
}
function fileExport(content: string, fileName: string) {

Wyświetl plik

@ -1,8 +1,9 @@
import { RootState } from 'soapbox/store';
import { AppDispatch, RootState } from 'soapbox/store';
import api from '../api';
import { ACCOUNTS_IMPORT, importFetchedAccounts } from './importer';
import { fetchRelationships } from './accounts';
import { importFetchedAccounts } from './importer';
import type { APIEntity } from 'soapbox/types/entities';
@ -10,31 +11,7 @@ export const FAMILIAR_FOLLOWERS_FETCH_REQUEST = 'FAMILIAR_FOLLOWERS_FETCH_REQUES
export const FAMILIAR_FOLLOWERS_FETCH_SUCCESS = 'FAMILIAR_FOLLOWERS_FETCH_SUCCESS';
export const FAMILIAR_FOLLOWERS_FETCH_FAIL = 'FAMILIAR_FOLLOWERS_FETCH_FAIL';
type FamiliarFollowersFetchRequestAction = {
type: typeof FAMILIAR_FOLLOWERS_FETCH_REQUEST,
id: string,
}
type FamiliarFollowersFetchRequestSuccessAction = {
type: typeof FAMILIAR_FOLLOWERS_FETCH_SUCCESS,
id: string,
accounts: Array<APIEntity>,
}
type FamiliarFollowersFetchRequestFailAction = {
type: typeof FAMILIAR_FOLLOWERS_FETCH_FAIL,
id: string,
error: any,
}
type AccountsImportAction = {
type: typeof ACCOUNTS_IMPORT,
accounts: Array<APIEntity>,
}
export type FamiliarFollowersActions = FamiliarFollowersFetchRequestAction | FamiliarFollowersFetchRequestSuccessAction | FamiliarFollowersFetchRequestFailAction | AccountsImportAction
export const fetchAccountFamiliarFollowers = (accountId: string) => (dispatch: React.Dispatch<FamiliarFollowersActions>, getState: () => RootState) => {
export const fetchAccountFamiliarFollowers = (accountId: string) => (dispatch: AppDispatch, getState: () => RootState) => {
dispatch({
type: FAMILIAR_FOLLOWERS_FETCH_REQUEST,
id: accountId,
@ -44,7 +21,8 @@ export const fetchAccountFamiliarFollowers = (accountId: string) => (dispatch: R
.then(({ data }) => {
const accounts = data.find(({ id }: { id: string }) => id === accountId).accounts;
dispatch(importFetchedAccounts(accounts) as AccountsImportAction);
dispatch(importFetchedAccounts(accounts));
dispatch(fetchRelationships(accounts.map((item: APIEntity) => item.id)));
dispatch({
type: FAMILIAR_FOLLOWERS_FETCH_SUCCESS,
id: accountId,
@ -55,5 +33,6 @@ export const fetchAccountFamiliarFollowers = (accountId: string) => (dispatch: R
type: FAMILIAR_FOLLOWERS_FETCH_FAIL,
id: accountId,
error,
skipAlert: true,
}));
};

Wyświetl plik

@ -12,10 +12,18 @@ const FILTERS_FETCH_REQUEST = 'FILTERS_FETCH_REQUEST';
const FILTERS_FETCH_SUCCESS = 'FILTERS_FETCH_SUCCESS';
const FILTERS_FETCH_FAIL = 'FILTERS_FETCH_FAIL';
const FILTER_FETCH_REQUEST = 'FILTER_FETCH_REQUEST';
const FILTER_FETCH_SUCCESS = 'FILTER_FETCH_SUCCESS';
const FILTER_FETCH_FAIL = 'FILTER_FETCH_FAIL';
const FILTERS_CREATE_REQUEST = 'FILTERS_CREATE_REQUEST';
const FILTERS_CREATE_SUCCESS = 'FILTERS_CREATE_SUCCESS';
const FILTERS_CREATE_FAIL = 'FILTERS_CREATE_FAIL';
const FILTERS_UPDATE_REQUEST = 'FILTERS_UPDATE_REQUEST';
const FILTERS_UPDATE_SUCCESS = 'FILTERS_UPDATE_SUCCESS';
const FILTERS_UPDATE_FAIL = 'FILTERS_UPDATE_FAIL';
const FILTERS_DELETE_REQUEST = 'FILTERS_DELETE_REQUEST';
const FILTERS_DELETE_SUCCESS = 'FILTERS_DELETE_SUCCESS';
const FILTERS_DELETE_FAIL = 'FILTERS_DELETE_FAIL';
@ -25,22 +33,16 @@ const messages = defineMessages({
removed: { id: 'filters.removed', defaultMessage: 'Filter deleted.' },
});
const fetchFilters = () =>
type FilterKeywords = { keyword: string, whole_word: boolean }[];
const fetchFiltersV1 = () =>
(dispatch: AppDispatch, getState: () => RootState) => {
if (!isLoggedIn(getState)) return;
const state = getState();
const instance = state.instance;
const features = getFeatures(instance);
if (!features.filters) return;
dispatch({
type: FILTERS_FETCH_REQUEST,
skipLoading: true,
});
api(getState)
return api(getState)
.get('/api/v1/filters')
.then(({ data }) => dispatch({
type: FILTERS_FETCH_SUCCESS,
@ -55,15 +57,105 @@ const fetchFilters = () =>
}));
};
const createFilter = (phrase: string, expires_at: string, context: Array<string>, whole_word: boolean, irreversible: boolean) =>
const fetchFiltersV2 = () =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch({
type: FILTERS_FETCH_REQUEST,
skipLoading: true,
});
return api(getState)
.get('/api/v2/filters')
.then(({ data }) => dispatch({
type: FILTERS_FETCH_SUCCESS,
filters: data,
skipLoading: true,
}))
.catch(err => dispatch({
type: FILTERS_FETCH_FAIL,
err,
skipLoading: true,
skipAlert: true,
}));
};
const fetchFilters = (fromFiltersPage = false) =>
(dispatch: AppDispatch, getState: () => RootState) => {
if (!isLoggedIn(getState)) return;
const state = getState();
const instance = state.instance;
const features = getFeatures(instance);
if (features.filtersV2 && fromFiltersPage) return dispatch(fetchFiltersV2());
if (features.filters) return dispatch(fetchFiltersV1());
};
const fetchFilterV1 = (id: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch({
type: FILTER_FETCH_REQUEST,
skipLoading: true,
});
return api(getState)
.get(`/api/v1/filters/${id}`)
.then(({ data }) => dispatch({
type: FILTER_FETCH_SUCCESS,
filter: data,
skipLoading: true,
}))
.catch(err => dispatch({
type: FILTER_FETCH_FAIL,
err,
skipLoading: true,
skipAlert: true,
}));
};
const fetchFilterV2 = (id: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch({
type: FILTER_FETCH_REQUEST,
skipLoading: true,
});
return api(getState)
.get(`/api/v2/filters/${id}`)
.then(({ data }) => dispatch({
type: FILTER_FETCH_SUCCESS,
filter: data,
skipLoading: true,
}))
.catch(err => dispatch({
type: FILTER_FETCH_FAIL,
err,
skipLoading: true,
skipAlert: true,
}));
};
const fetchFilter = (id: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const state = getState();
const instance = state.instance;
const features = getFeatures(instance);
if (features.filtersV2) return dispatch(fetchFilterV2(id));
if (features.filters) return dispatch(fetchFilterV1(id));
};
const createFilterV1 = (title: string, expires_in: string | null, context: Array<string>, hide: boolean, keywords: FilterKeywords) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch({ type: FILTERS_CREATE_REQUEST });
return api(getState).post('/api/v1/filters', {
phrase,
phrase: keywords[0].keyword,
context,
irreversible,
whole_word,
expires_at,
irreversible: hide,
whole_word: keywords[0].whole_word,
expires_in,
}).then(response => {
dispatch({ type: FILTERS_CREATE_SUCCESS, filter: response.data });
toast.success(messages.added);
@ -72,7 +164,80 @@ const createFilter = (phrase: string, expires_at: string, context: Array<string>
});
};
const deleteFilter = (id: string) =>
const createFilterV2 = (title: string, expires_in: string | null, context: Array<string>, hide: boolean, keywords_attributes: FilterKeywords) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch({ type: FILTERS_CREATE_REQUEST });
return api(getState).post('/api/v2/filters', {
title,
context,
filter_action: hide ? 'hide' : 'warn',
expires_in,
keywords_attributes,
}).then(response => {
dispatch({ type: FILTERS_CREATE_SUCCESS, filter: response.data });
toast.success(messages.added);
}).catch(error => {
dispatch({ type: FILTERS_CREATE_FAIL, error });
});
};
const createFilter = (title: string, expires_in: string | null, context: Array<string>, hide: boolean, keywords: FilterKeywords) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const state = getState();
const instance = state.instance;
const features = getFeatures(instance);
if (features.filtersV2) return dispatch(createFilterV2(title, expires_in, context, hide, keywords));
return dispatch(createFilterV1(title, expires_in, context, hide, keywords));
};
const updateFilterV1 = (id: string, title: string, expires_in: string | null, context: Array<string>, hide: boolean, keywords: FilterKeywords) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch({ type: FILTERS_UPDATE_REQUEST });
return api(getState).patch(`/api/v1/filters/${id}`, {
phrase: keywords[0].keyword,
context,
irreversible: hide,
whole_word: keywords[0].whole_word,
expires_in,
}).then(response => {
dispatch({ type: FILTERS_UPDATE_SUCCESS, filter: response.data });
toast.success(messages.added);
}).catch(error => {
dispatch({ type: FILTERS_UPDATE_FAIL, error });
});
};
const updateFilterV2 = (id: string, title: string, expires_in: string | null, context: Array<string>, hide: boolean, keywords_attributes: FilterKeywords) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch({ type: FILTERS_UPDATE_REQUEST });
return api(getState).patch(`/api/v2/filters/${id}`, {
title,
context,
filter_action: hide ? 'hide' : 'warn',
expires_in,
keywords_attributes,
}).then(response => {
dispatch({ type: FILTERS_UPDATE_SUCCESS, filter: response.data });
toast.success(messages.added);
}).catch(error => {
dispatch({ type: FILTERS_UPDATE_FAIL, error });
});
};
const updateFilter = (id: string, title: string, expires_in: string | null, context: Array<string>, hide: boolean, keywords: FilterKeywords) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const state = getState();
const instance = state.instance;
const features = getFeatures(instance);
if (features.filtersV2) return dispatch(updateFilterV2(id, title, expires_in, context, hide, keywords));
return dispatch(updateFilterV1(id, title, expires_in, context, hide, keywords));
};
const deleteFilterV1 = (id: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch({ type: FILTERS_DELETE_REQUEST });
return api(getState).delete(`/api/v1/filters/${id}`).then(response => {
@ -83,17 +248,47 @@ const deleteFilter = (id: string) =>
});
};
const deleteFilterV2 = (id: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch({ type: FILTERS_DELETE_REQUEST });
return api(getState).delete(`/api/v2/filters/${id}`).then(response => {
dispatch({ type: FILTERS_DELETE_SUCCESS, filter: response.data });
toast.success(messages.removed);
}).catch(error => {
dispatch({ type: FILTERS_DELETE_FAIL, error });
});
};
const deleteFilter = (id: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const state = getState();
const instance = state.instance;
const features = getFeatures(instance);
if (features.filtersV2) return dispatch(deleteFilterV2(id));
return dispatch(deleteFilterV1(id));
};
export {
FILTERS_FETCH_REQUEST,
FILTERS_FETCH_SUCCESS,
FILTERS_FETCH_FAIL,
FILTER_FETCH_REQUEST,
FILTER_FETCH_SUCCESS,
FILTER_FETCH_FAIL,
FILTERS_CREATE_REQUEST,
FILTERS_CREATE_SUCCESS,
FILTERS_CREATE_FAIL,
FILTERS_UPDATE_REQUEST,
FILTERS_UPDATE_SUCCESS,
FILTERS_UPDATE_FAIL,
FILTERS_DELETE_REQUEST,
FILTERS_DELETE_SUCCESS,
FILTERS_DELETE_FAIL,
fetchFilters,
fetchFilter,
createFilter,
updateFilter,
deleteFilter,
};
};

Wyświetl plik

@ -1,20 +1,14 @@
import { defineMessages } from 'react-intl';
import toast from 'soapbox/toast';
import { deleteEntities } from 'soapbox/entity-store/actions';
import api, { getLinks } from '../api';
import { fetchRelationships } from './accounts';
import { importFetchedGroups, importFetchedAccounts } from './importer';
import { closeModal, openModal } from './modals';
import { deleteFromTimelines } from './timelines';
import type { AxiosError } from 'axios';
import type { GroupRole } from 'soapbox/reducers/group-memberships';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { APIEntity, Group } from 'soapbox/types/entities';
const GROUP_EDITOR_SET = 'GROUP_EDITOR_SET';
import type { APIEntity } from 'soapbox/types/entities';
const GROUP_CREATE_REQUEST = 'GROUP_CREATE_REQUEST';
const GROUP_CREATE_SUCCESS = 'GROUP_CREATE_SUCCESS';
@ -40,18 +34,6 @@ const GROUP_RELATIONSHIPS_FETCH_REQUEST = 'GROUP_RELATIONSHIPS_FETCH_REQUEST';
const GROUP_RELATIONSHIPS_FETCH_SUCCESS = 'GROUP_RELATIONSHIPS_FETCH_SUCCESS';
const GROUP_RELATIONSHIPS_FETCH_FAIL = 'GROUP_RELATIONSHIPS_FETCH_FAIL';
const GROUP_JOIN_REQUEST = 'GROUP_JOIN_REQUEST';
const GROUP_JOIN_SUCCESS = 'GROUP_JOIN_SUCCESS';
const GROUP_JOIN_FAIL = 'GROUP_JOIN_FAIL';
const GROUP_LEAVE_REQUEST = 'GROUP_LEAVE_REQUEST';
const GROUP_LEAVE_SUCCESS = 'GROUP_LEAVE_SUCCESS';
const GROUP_LEAVE_FAIL = 'GROUP_LEAVE_FAIL';
const GROUP_DELETE_STATUS_REQUEST = 'GROUP_DELETE_STATUS_REQUEST';
const GROUP_DELETE_STATUS_SUCCESS = 'GROUP_DELETE_STATUS_SUCCESS';
const GROUP_DELETE_STATUS_FAIL = 'GROUP_DELETE_STATUS_FAIL';
const GROUP_KICK_REQUEST = 'GROUP_KICK_REQUEST';
const GROUP_KICK_SUCCESS = 'GROUP_KICK_SUCCESS';
const GROUP_KICK_FAIL = 'GROUP_KICK_FAIL';
@ -104,101 +86,8 @@ const GROUP_MEMBERSHIP_REQUEST_REJECT_REQUEST = 'GROUP_MEMBERSHIP_REQUEST_REJECT
const GROUP_MEMBERSHIP_REQUEST_REJECT_SUCCESS = 'GROUP_MEMBERSHIP_REQUEST_REJECT_SUCCESS';
const GROUP_MEMBERSHIP_REQUEST_REJECT_FAIL = 'GROUP_MEMBERSHIP_REQUEST_REJECT_FAIL';
const GROUP_EDITOR_TITLE_CHANGE = 'GROUP_EDITOR_TITLE_CHANGE';
const GROUP_EDITOR_DESCRIPTION_CHANGE = 'GROUP_EDITOR_DESCRIPTION_CHANGE';
const GROUP_EDITOR_PRIVACY_CHANGE = 'GROUP_EDITOR_PRIVACY_CHANGE';
const GROUP_EDITOR_MEDIA_CHANGE = 'GROUP_EDITOR_MEDIA_CHANGE';
const GROUP_EDITOR_RESET = 'GROUP_EDITOR_RESET';
const messages = defineMessages({
success: { id: 'manage_group.submit_success', defaultMessage: 'The group was created' },
editSuccess: { id: 'manage_group.edit_success', defaultMessage: 'The group was edited' },
joinSuccess: { id: 'group.join.success', defaultMessage: 'Joined the group' },
joinRequestSuccess: { id: 'group.join.request_success', defaultMessage: 'Requested to join the group' },
leaveSuccess: { id: 'group.leave.success', defaultMessage: 'Left the group' },
view: { id: 'toast.view', defaultMessage: 'View' },
});
const editGroup = (group: Group) => (dispatch: AppDispatch) => {
dispatch({
type: GROUP_EDITOR_SET,
group,
});
dispatch(openModal('MANAGE_GROUP'));
};
const createGroup = (params: Record<string, any>, shouldReset?: boolean) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch(createGroupRequest());
return api(getState).post('/api/v1/groups', params, {
headers: {
'Content-Type': 'multipart/form-data',
},
})
.then(({ data }) => {
dispatch(importFetchedGroups([data]));
dispatch(createGroupSuccess(data));
toast.success(messages.success, {
actionLabel: messages.view,
actionLink: `/groups/${data.id}`,
});
if (shouldReset) {
dispatch(resetGroupEditor());
}
dispatch(closeModal('MANAGE_GROUP'));
}).catch(err => dispatch(createGroupFail(err)));
};
const createGroupRequest = () => ({
type: GROUP_CREATE_REQUEST,
});
const createGroupSuccess = (group: APIEntity) => ({
type: GROUP_CREATE_SUCCESS,
group,
});
const createGroupFail = (error: AxiosError) => ({
type: GROUP_CREATE_FAIL,
error,
});
const updateGroup = (id: string, params: Record<string, any>, shouldReset?: boolean) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch(updateGroupRequest());
return api(getState).put(`/api/v1/groups/${id}`, params)
.then(({ data }) => {
dispatch(importFetchedGroups([data]));
dispatch(updateGroupSuccess(data));
toast.success(messages.editSuccess);
if (shouldReset) {
dispatch(resetGroupEditor());
}
dispatch(closeModal('MANAGE_GROUP'));
}).catch(err => dispatch(updateGroupFail(err)));
};
const updateGroupRequest = () => ({
type: GROUP_UPDATE_REQUEST,
});
const updateGroupSuccess = (group: APIEntity) => ({
type: GROUP_UPDATE_SUCCESS,
group,
});
const updateGroupFail = (error: AxiosError) => ({
type: GROUP_UPDATE_FAIL,
error,
});
const deleteGroup = (id: string) => (dispatch: AppDispatch, getState: () => RootState) => {
dispatch(deleteGroupRequest(id));
dispatch(deleteEntities([id], 'Group'));
return api(getState).delete(`/api/v1/groups/${id}`)
.then(() => dispatch(deleteGroupSuccess(id)))
@ -312,100 +201,6 @@ const fetchGroupRelationshipsFail = (error: AxiosError) => ({
skipNotFound: true,
});
const joinGroup = (id: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const locked = (getState().groups.items.get(id) as any).locked || false;
dispatch(joinGroupRequest(id, locked));
return api(getState).post(`/api/v1/groups/${id}/join`).then(response => {
dispatch(joinGroupSuccess(response.data));
toast.success(locked ? messages.joinRequestSuccess : messages.joinSuccess);
}).catch(error => {
dispatch(joinGroupFail(error, locked));
});
};
const leaveGroup = (id: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch(leaveGroupRequest(id));
return api(getState).post(`/api/v1/groups/${id}/leave`).then(response => {
dispatch(leaveGroupSuccess(response.data));
toast.success(messages.leaveSuccess);
}).catch(error => {
dispatch(leaveGroupFail(error));
});
};
const joinGroupRequest = (id: string, locked: boolean) => ({
type: GROUP_JOIN_REQUEST,
id,
locked,
skipLoading: true,
});
const joinGroupSuccess = (relationship: APIEntity) => ({
type: GROUP_JOIN_SUCCESS,
relationship,
skipLoading: true,
});
const joinGroupFail = (error: AxiosError, locked: boolean) => ({
type: GROUP_JOIN_FAIL,
error,
locked,
skipLoading: true,
});
const leaveGroupRequest = (id: string) => ({
type: GROUP_LEAVE_REQUEST,
id,
skipLoading: true,
});
const leaveGroupSuccess = (relationship: APIEntity) => ({
type: GROUP_LEAVE_SUCCESS,
relationship,
skipLoading: true,
});
const leaveGroupFail = (error: AxiosError) => ({
type: GROUP_LEAVE_FAIL,
error,
skipLoading: true,
});
const groupDeleteStatus = (groupId: string, statusId: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch(groupDeleteStatusRequest(groupId, statusId));
return api(getState).delete(`/api/v1/groups/${groupId}/statuses/${statusId}`)
.then(() => {
dispatch(deleteFromTimelines(statusId));
dispatch(groupDeleteStatusSuccess(groupId, statusId));
}).catch(err => dispatch(groupDeleteStatusFail(groupId, statusId, err)));
};
const groupDeleteStatusRequest = (groupId: string, statusId: string) => ({
type: GROUP_DELETE_STATUS_REQUEST,
groupId,
statusId,
});
const groupDeleteStatusSuccess = (groupId: string, statusId: string) => ({
type: GROUP_DELETE_STATUS_SUCCESS,
groupId,
statusId,
});
const groupDeleteStatusFail = (groupId: string, statusId: string, error: AxiosError) => ({
type: GROUP_DELETE_STATUS_SUCCESS,
groupId,
statusId,
error,
});
const groupKick = (groupId: string, accountId: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch(groupKickRequest(groupId, accountId));
@ -828,55 +623,7 @@ const rejectGroupMembershipRequestFail = (groupId: string, accountId: string, er
error,
});
const changeGroupEditorTitle = (value: string) => ({
type: GROUP_EDITOR_TITLE_CHANGE,
value,
});
const changeGroupEditorDescription = (value: string) => ({
type: GROUP_EDITOR_DESCRIPTION_CHANGE,
value,
});
const changeGroupEditorPrivacy = (value: boolean) => ({
type: GROUP_EDITOR_PRIVACY_CHANGE,
value,
});
const changeGroupEditorMedia = (mediaType: 'header' | 'avatar', file: File) => ({
type: GROUP_EDITOR_MEDIA_CHANGE,
mediaType,
value: file,
});
const resetGroupEditor = () => ({
type: GROUP_EDITOR_RESET,
});
const submitGroupEditor = (shouldReset?: boolean) => (dispatch: AppDispatch, getState: () => RootState) => {
const groupId = getState().group_editor.groupId;
const displayName = getState().group_editor.displayName;
const note = getState().group_editor.note;
const avatar = getState().group_editor.avatar;
const header = getState().group_editor.header;
const params: Record<string, any> = {
display_name: displayName,
note,
};
if (avatar) params.avatar = avatar;
if (header) params.header = header;
if (groupId === null) {
dispatch(createGroup(params, shouldReset));
} else {
dispatch(updateGroup(groupId, params, shouldReset));
}
};
export {
GROUP_EDITOR_SET,
GROUP_CREATE_REQUEST,
GROUP_CREATE_SUCCESS,
GROUP_CREATE_FAIL,
@ -895,15 +642,6 @@ export {
GROUP_RELATIONSHIPS_FETCH_REQUEST,
GROUP_RELATIONSHIPS_FETCH_SUCCESS,
GROUP_RELATIONSHIPS_FETCH_FAIL,
GROUP_JOIN_REQUEST,
GROUP_JOIN_SUCCESS,
GROUP_JOIN_FAIL,
GROUP_LEAVE_REQUEST,
GROUP_LEAVE_SUCCESS,
GROUP_LEAVE_FAIL,
GROUP_DELETE_STATUS_REQUEST,
GROUP_DELETE_STATUS_SUCCESS,
GROUP_DELETE_STATUS_FAIL,
GROUP_KICK_REQUEST,
GROUP_KICK_SUCCESS,
GROUP_KICK_FAIL,
@ -943,20 +681,6 @@ export {
GROUP_MEMBERSHIP_REQUEST_REJECT_REQUEST,
GROUP_MEMBERSHIP_REQUEST_REJECT_SUCCESS,
GROUP_MEMBERSHIP_REQUEST_REJECT_FAIL,
GROUP_EDITOR_TITLE_CHANGE,
GROUP_EDITOR_DESCRIPTION_CHANGE,
GROUP_EDITOR_PRIVACY_CHANGE,
GROUP_EDITOR_MEDIA_CHANGE,
GROUP_EDITOR_RESET,
editGroup,
createGroup,
createGroupRequest,
createGroupSuccess,
createGroupFail,
updateGroup,
updateGroupRequest,
updateGroupSuccess,
updateGroupFail,
deleteGroup,
deleteGroupRequest,
deleteGroupSuccess,
@ -973,18 +697,6 @@ export {
fetchGroupRelationshipsRequest,
fetchGroupRelationshipsSuccess,
fetchGroupRelationshipsFail,
joinGroup,
leaveGroup,
joinGroupRequest,
joinGroupSuccess,
joinGroupFail,
leaveGroupRequest,
leaveGroupSuccess,
leaveGroupFail,
groupDeleteStatus,
groupDeleteStatusRequest,
groupDeleteStatusSuccess,
groupDeleteStatusFail,
groupKick,
groupKickRequest,
groupKickSuccess,
@ -1037,10 +749,4 @@ export {
rejectGroupMembershipRequestRequest,
rejectGroupMembershipRequestSuccess,
rejectGroupMembershipRequestFail,
changeGroupEditorTitle,
changeGroupEditorDescription,
changeGroupEditorPrivacy,
changeGroupEditorMedia,
resetGroupEditor,
submitGroupEditor,
};

Wyświetl plik

@ -27,8 +27,8 @@ type ImportDataActions = {
| typeof IMPORT_BLOCKS_FAIL
| typeof IMPORT_MUTES_REQUEST
| typeof IMPORT_MUTES_SUCCESS
| typeof IMPORT_MUTES_FAIL,
error?: any,
| typeof IMPORT_MUTES_FAIL
error?: any
config?: string
}

Wyświetl plik

@ -1,3 +1,8 @@
import { importEntities } from 'soapbox/entity-store/actions';
import { Entities } from 'soapbox/entity-store/entities';
import { Group, accountSchema, groupSchema } from 'soapbox/schemas';
import { filteredArray } from 'soapbox/schemas/utils';
import { getSettings } from '../settings';
import type { AppDispatch, RootState } from 'soapbox/store';
@ -12,17 +17,33 @@ const STATUSES_IMPORT = 'STATUSES_IMPORT';
const POLLS_IMPORT = 'POLLS_IMPORT';
const ACCOUNT_FETCH_FAIL_FOR_USERNAME_LOOKUP = 'ACCOUNT_FETCH_FAIL_FOR_USERNAME_LOOKUP';
const importAccount = (account: APIEntity) =>
({ type: ACCOUNT_IMPORT, account });
const importAccount = (data: APIEntity) =>
(dispatch: AppDispatch, _getState: () => RootState) => {
dispatch({ type: ACCOUNT_IMPORT, account: data });
try {
const account = accountSchema.parse(data);
dispatch(importEntities([account], Entities.ACCOUNTS));
} catch (e) {
//
}
};
const importAccounts = (accounts: APIEntity[]) =>
({ type: ACCOUNTS_IMPORT, accounts });
const importAccounts = (data: APIEntity[]) =>
(dispatch: AppDispatch, _getState: () => RootState) => {
dispatch({ type: ACCOUNTS_IMPORT, accounts: data });
try {
const accounts = filteredArray(accountSchema).parse(data);
dispatch(importEntities(accounts, Entities.ACCOUNTS));
} catch (e) {
//
}
};
const importGroup = (group: APIEntity) =>
({ type: GROUP_IMPORT, group });
const importGroup = (group: Group) =>
importEntities([group], Entities.GROUPS);
const importGroups = (groups: APIEntity[]) =>
({ type: GROUPS_IMPORT, groups });
const importGroups = (groups: Group[]) =>
importEntities(groups, Entities.GROUPS);
const importStatus = (status: APIEntity, idempotencyKey?: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
@ -69,17 +90,8 @@ const importFetchedGroup = (group: APIEntity) =>
importFetchedGroups([group]);
const importFetchedGroups = (groups: APIEntity[]) => {
const normalGroups: APIEntity[] = [];
const processGroup = (group: APIEntity) => {
if (!group.id) return;
normalGroups.push(group);
};
groups.forEach(processGroup);
return importGroups(normalGroups);
const entities = filteredArray(groupSchema).parse(groups);
return importGroups(entities);
};
const importFetchedStatus = (status: APIEntity, idempotencyKey?: string) =>

Wyświetl plik

@ -3,16 +3,11 @@ import get from 'lodash/get';
import KVStore from 'soapbox/storage/kv-store';
import { RootState } from 'soapbox/store';
import { getAuthUserUrl } from 'soapbox/utils/auth';
import { getAuthUserUrl, getMeUrl } from 'soapbox/utils/auth';
import { parseVersion } from 'soapbox/utils/features';
import api from '../api';
const getMeUrl = (state: RootState) => {
const me = state.me;
return state.accounts.get(me)?.url;
};
/** Figure out the appropriate instance to fetch depending on the state */
export const getHost = (state: RootState) => {
const accountUrl = getMeUrl(state) || getAuthUserUrl(state) as string;

Wyświetl plik

@ -3,14 +3,15 @@ import { defineMessages } from 'react-intl';
import toast from 'soapbox/toast';
import { isLoggedIn } from 'soapbox/utils/auth';
import api from '../api';
import api, { getLinks } from '../api';
import { fetchRelationships } from './accounts';
import { importFetchedAccounts, importFetchedStatus } from './importer';
import { expandGroupFeaturedTimeline } from './timelines';
import type { AxiosError } from 'axios';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { APIEntity, Status as StatusEntity } from 'soapbox/types/entities';
import type { APIEntity, Group, Status as StatusEntity } from 'soapbox/types/entities';
const REBLOG_REQUEST = 'REBLOG_REQUEST';
const REBLOG_SUCCESS = 'REBLOG_SUCCESS';
@ -20,6 +21,10 @@ const FAVOURITE_REQUEST = 'FAVOURITE_REQUEST';
const FAVOURITE_SUCCESS = 'FAVOURITE_SUCCESS';
const FAVOURITE_FAIL = 'FAVOURITE_FAIL';
const DISLIKE_REQUEST = 'DISLIKE_REQUEST';
const DISLIKE_SUCCESS = 'DISLIKE_SUCCESS';
const DISLIKE_FAIL = 'DISLIKE_FAIL';
const UNREBLOG_REQUEST = 'UNREBLOG_REQUEST';
const UNREBLOG_SUCCESS = 'UNREBLOG_SUCCESS';
const UNREBLOG_FAIL = 'UNREBLOG_FAIL';
@ -28,6 +33,10 @@ const UNFAVOURITE_REQUEST = 'UNFAVOURITE_REQUEST';
const UNFAVOURITE_SUCCESS = 'UNFAVOURITE_SUCCESS';
const UNFAVOURITE_FAIL = 'UNFAVOURITE_FAIL';
const UNDISLIKE_REQUEST = 'UNDISLIKE_REQUEST';
const UNDISLIKE_SUCCESS = 'UNDISLIKE_SUCCESS';
const UNDISLIKE_FAIL = 'UNDISLIKE_FAIL';
const REBLOGS_FETCH_REQUEST = 'REBLOGS_FETCH_REQUEST';
const REBLOGS_FETCH_SUCCESS = 'REBLOGS_FETCH_SUCCESS';
const REBLOGS_FETCH_FAIL = 'REBLOGS_FETCH_FAIL';
@ -36,6 +45,10 @@ const FAVOURITES_FETCH_REQUEST = 'FAVOURITES_FETCH_REQUEST';
const FAVOURITES_FETCH_SUCCESS = 'FAVOURITES_FETCH_SUCCESS';
const FAVOURITES_FETCH_FAIL = 'FAVOURITES_FETCH_FAIL';
const DISLIKES_FETCH_REQUEST = 'DISLIKES_FETCH_REQUEST';
const DISLIKES_FETCH_SUCCESS = 'DISLIKES_FETCH_SUCCESS';
const DISLIKES_FETCH_FAIL = 'DISLIKES_FETCH_FAIL';
const REACTIONS_FETCH_REQUEST = 'REACTIONS_FETCH_REQUEST';
const REACTIONS_FETCH_SUCCESS = 'REACTIONS_FETCH_SUCCESS';
const REACTIONS_FETCH_FAIL = 'REACTIONS_FETCH_FAIL';
@ -60,6 +73,12 @@ const REMOTE_INTERACTION_REQUEST = 'REMOTE_INTERACTION_REQUEST';
const REMOTE_INTERACTION_SUCCESS = 'REMOTE_INTERACTION_SUCCESS';
const REMOTE_INTERACTION_FAIL = 'REMOTE_INTERACTION_FAIL';
const FAVOURITES_EXPAND_SUCCESS = 'FAVOURITES_EXPAND_SUCCESS';
const FAVOURITES_EXPAND_FAIL = 'FAVOURITES_EXPAND_FAIL';
const REBLOGS_EXPAND_SUCCESS = 'REBLOGS_EXPAND_SUCCESS';
const REBLOGS_EXPAND_FAIL = 'REBLOGS_EXPAND_FAIL';
const messages = defineMessages({
bookmarkAdded: { id: 'status.bookmarked', defaultMessage: 'Bookmark added.' },
bookmarkRemoved: { id: 'status.unbookmarked', defaultMessage: 'Bookmark removed.' },
@ -72,7 +91,7 @@ const reblog = (status: StatusEntity) =>
dispatch(reblogRequest(status));
api(getState).post(`/api/v1/statuses/${status.get('id')}/reblog`).then(function(response) {
api(getState).post(`/api/v1/statuses/${status.id}/reblog`).then(function(response) {
// The reblog API method returns a new status wrapped around the original. In this case we are only
// interested in how the original is modified, hence passing it skipping the wrapper
dispatch(importFetchedStatus(response.data.reblog));
@ -88,7 +107,7 @@ const unreblog = (status: StatusEntity) =>
dispatch(unreblogRequest(status));
api(getState).post(`/api/v1/statuses/${status.get('id')}/unreblog`).then(() => {
api(getState).post(`/api/v1/statuses/${status.id}/unreblog`).then(() => {
dispatch(unreblogSuccess(status));
}).catch(error => {
dispatch(unreblogFail(status, error));
@ -96,7 +115,7 @@ const unreblog = (status: StatusEntity) =>
};
const toggleReblog = (status: StatusEntity) =>
(dispatch: AppDispatch, getState: () => RootState) => {
(dispatch: AppDispatch) => {
if (status.reblogged) {
dispatch(unreblog(status));
} else {
@ -148,7 +167,7 @@ const favourite = (status: StatusEntity) =>
dispatch(favouriteRequest(status));
api(getState).post(`/api/v1/statuses/${status.get('id')}/favourite`).then(function(response) {
api(getState).post(`/api/v1/statuses/${status.id}/favourite`).then(function(response) {
dispatch(favouriteSuccess(status));
}).catch(function(error) {
dispatch(favouriteFail(status, error));
@ -161,7 +180,7 @@ const unfavourite = (status: StatusEntity) =>
dispatch(unfavouriteRequest(status));
api(getState).post(`/api/v1/statuses/${status.get('id')}/unfavourite`).then(() => {
api(getState).post(`/api/v1/statuses/${status.id}/unfavourite`).then(() => {
dispatch(unfavouriteSuccess(status));
}).catch(error => {
dispatch(unfavouriteFail(status, error));
@ -169,7 +188,7 @@ const unfavourite = (status: StatusEntity) =>
};
const toggleFavourite = (status: StatusEntity) =>
(dispatch: AppDispatch, getState: () => RootState) => {
(dispatch: AppDispatch) => {
if (status.favourited) {
dispatch(unfavourite(status));
} else {
@ -215,11 +234,84 @@ const unfavouriteFail = (status: StatusEntity, error: AxiosError) => ({
skipLoading: true,
});
const dislike = (status: StatusEntity) =>
(dispatch: AppDispatch, getState: () => RootState) => {
if (!isLoggedIn(getState)) return;
dispatch(dislikeRequest(status));
api(getState).post(`/api/friendica/statuses/${status.id}/dislike`).then(function() {
dispatch(dislikeSuccess(status));
}).catch(function(error) {
dispatch(dislikeFail(status, error));
});
};
const undislike = (status: StatusEntity) =>
(dispatch: AppDispatch, getState: () => RootState) => {
if (!isLoggedIn(getState)) return;
dispatch(undislikeRequest(status));
api(getState).post(`/api/friendica/statuses/${status.id}/undislike`).then(() => {
dispatch(undislikeSuccess(status));
}).catch(error => {
dispatch(undislikeFail(status, error));
});
};
const toggleDislike = (status: StatusEntity) =>
(dispatch: AppDispatch) => {
if (status.disliked) {
dispatch(undislike(status));
} else {
dispatch(dislike(status));
}
};
const dislikeRequest = (status: StatusEntity) => ({
type: DISLIKE_REQUEST,
status: status,
skipLoading: true,
});
const dislikeSuccess = (status: StatusEntity) => ({
type: DISLIKE_SUCCESS,
status: status,
skipLoading: true,
});
const dislikeFail = (status: StatusEntity, error: AxiosError) => ({
type: DISLIKE_FAIL,
status: status,
error: error,
skipLoading: true,
});
const undislikeRequest = (status: StatusEntity) => ({
type: UNDISLIKE_REQUEST,
status: status,
skipLoading: true,
});
const undislikeSuccess = (status: StatusEntity) => ({
type: UNDISLIKE_SUCCESS,
status: status,
skipLoading: true,
});
const undislikeFail = (status: StatusEntity, error: AxiosError) => ({
type: UNDISLIKE_FAIL,
status: status,
error: error,
skipLoading: true,
});
const bookmark = (status: StatusEntity) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch(bookmarkRequest(status));
api(getState).post(`/api/v1/statuses/${status.get('id')}/bookmark`).then(function(response) {
api(getState).post(`/api/v1/statuses/${status.id}/bookmark`).then(function(response) {
dispatch(importFetchedStatus(response.data));
dispatch(bookmarkSuccess(status, response.data));
toast.success(messages.bookmarkAdded, {
@ -235,7 +327,7 @@ const unbookmark = (status: StatusEntity) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch(unbookmarkRequest(status));
api(getState).post(`/api/v1/statuses/${status.get('id')}/unbookmark`).then(response => {
api(getState).post(`/api/v1/statuses/${status.id}/unbookmark`).then(response => {
dispatch(importFetchedStatus(response.data));
dispatch(unbookmarkSuccess(status, response.data));
toast.success(messages.bookmarkRemoved);
@ -294,9 +386,10 @@ const fetchReblogs = (id: string) =>
dispatch(fetchReblogsRequest(id));
api(getState).get(`/api/v1/statuses/${id}/reblogged_by`).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedAccounts(response.data));
dispatch(fetchRelationships(response.data.map((item: APIEntity) => item.id)));
dispatch(fetchReblogsSuccess(id, response.data));
dispatch(fetchReblogsSuccess(id, response.data, next ? next.uri : null));
}).catch(error => {
dispatch(fetchReblogsFail(id, error));
});
@ -307,10 +400,11 @@ const fetchReblogsRequest = (id: string) => ({
id,
});
const fetchReblogsSuccess = (id: string, accounts: APIEntity[]) => ({
const fetchReblogsSuccess = (id: string, accounts: APIEntity[], next: string | null) => ({
type: REBLOGS_FETCH_SUCCESS,
id,
accounts,
next,
});
const fetchReblogsFail = (id: string, error: AxiosError) => ({
@ -319,6 +413,31 @@ const fetchReblogsFail = (id: string, error: AxiosError) => ({
error,
});
const expandReblogs = (id: string, path: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
api(getState).get(path).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedAccounts(response.data));
dispatch(fetchRelationships(response.data.map((item: APIEntity) => item.id)));
dispatch(expandReblogsSuccess(id, response.data, next ? next.uri : null));
}).catch(error => {
dispatch(expandReblogsFail(id, error));
});
};
const expandReblogsSuccess = (id: string, accounts: APIEntity[], next: string | null) => ({
type: REBLOGS_EXPAND_SUCCESS,
id,
accounts,
next,
});
const expandReblogsFail = (id: string, error: AxiosError) => ({
type: REBLOGS_EXPAND_FAIL,
id,
error,
});
const fetchFavourites = (id: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
if (!isLoggedIn(getState)) return;
@ -326,9 +445,10 @@ const fetchFavourites = (id: string) =>
dispatch(fetchFavouritesRequest(id));
api(getState).get(`/api/v1/statuses/${id}/favourited_by`).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedAccounts(response.data));
dispatch(fetchRelationships(response.data.map((item: APIEntity) => item.id)));
dispatch(fetchFavouritesSuccess(id, response.data));
dispatch(fetchFavouritesSuccess(id, response.data, next ? next.uri : null));
}).catch(error => {
dispatch(fetchFavouritesFail(id, error));
});
@ -339,10 +459,11 @@ const fetchFavouritesRequest = (id: string) => ({
id,
});
const fetchFavouritesSuccess = (id: string, accounts: APIEntity[]) => ({
const fetchFavouritesSuccess = (id: string, accounts: APIEntity[], next: string | null) => ({
type: FAVOURITES_FETCH_SUCCESS,
id,
accounts,
next,
});
const fetchFavouritesFail = (id: string, error: AxiosError) => ({
@ -351,6 +472,63 @@ const fetchFavouritesFail = (id: string, error: AxiosError) => ({
error,
});
const expandFavourites = (id: string, path: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
api(getState).get(path).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedAccounts(response.data));
dispatch(fetchRelationships(response.data.map((item: APIEntity) => item.id)));
dispatch(expandFavouritesSuccess(id, response.data, next ? next.uri : null));
}).catch(error => {
dispatch(expandFavouritesFail(id, error));
});
};
const expandFavouritesSuccess = (id: string, accounts: APIEntity[], next: string | null) => ({
type: FAVOURITES_EXPAND_SUCCESS,
id,
accounts,
next,
});
const expandFavouritesFail = (id: string, error: AxiosError) => ({
type: FAVOURITES_EXPAND_FAIL,
id,
error,
});
const fetchDislikes = (id: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
if (!isLoggedIn(getState)) return;
dispatch(fetchDislikesRequest(id));
api(getState).get(`/api/friendica/statuses/${id}/disliked_by`).then(response => {
dispatch(importFetchedAccounts(response.data));
dispatch(fetchRelationships(response.data.map((item: APIEntity) => item.id)));
dispatch(fetchDislikesSuccess(id, response.data));
}).catch(error => {
dispatch(fetchDislikesFail(id, error));
});
};
const fetchDislikesRequest = (id: string) => ({
type: DISLIKES_FETCH_REQUEST,
id,
});
const fetchDislikesSuccess = (id: string, accounts: APIEntity[]) => ({
type: DISLIKES_FETCH_SUCCESS,
id,
accounts,
});
const fetchDislikesFail = (id: string, error: AxiosError) => ({
type: DISLIKES_FETCH_FAIL,
id,
error,
});
const fetchReactions = (id: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch(fetchReactionsRequest(id));
@ -386,7 +564,7 @@ const pin = (status: StatusEntity) =>
dispatch(pinRequest(status));
api(getState).post(`/api/v1/statuses/${status.get('id')}/pin`).then(response => {
api(getState).post(`/api/v1/statuses/${status.id}/pin`).then(response => {
dispatch(importFetchedStatus(response.data));
dispatch(pinSuccess(status));
}).catch(error => {
@ -394,6 +572,20 @@ const pin = (status: StatusEntity) =>
});
};
const pinToGroup = (status: StatusEntity, group: Group) =>
(dispatch: AppDispatch, getState: () => RootState) => {
return api(getState)
.post(`/api/v1/groups/${group.id}/statuses/${status.id}/pin`)
.then(() => dispatch(expandGroupFeaturedTimeline(group.id)));
};
const unpinFromGroup = (status: StatusEntity, group: Group) =>
(dispatch: AppDispatch, getState: () => RootState) => {
return api(getState)
.post(`/api/v1/groups/${group.id}/statuses/${status.id}/unpin`)
.then(() => dispatch(expandGroupFeaturedTimeline(group.id)));
};
const pinRequest = (status: StatusEntity) => ({
type: PIN_REQUEST,
status,
@ -419,7 +611,7 @@ const unpin = (status: StatusEntity) =>
dispatch(unpinRequest(status));
api(getState).post(`/api/v1/statuses/${status.get('id')}/unpin`).then(response => {
api(getState).post(`/api/v1/statuses/${status.id}/unpin`).then(response => {
dispatch(importFetchedStatus(response.data));
dispatch(unpinSuccess(status));
}).catch(error => {
@ -498,18 +690,27 @@ export {
FAVOURITE_REQUEST,
FAVOURITE_SUCCESS,
FAVOURITE_FAIL,
DISLIKE_REQUEST,
DISLIKE_SUCCESS,
DISLIKE_FAIL,
UNREBLOG_REQUEST,
UNREBLOG_SUCCESS,
UNREBLOG_FAIL,
UNFAVOURITE_REQUEST,
UNFAVOURITE_SUCCESS,
UNFAVOURITE_FAIL,
UNDISLIKE_REQUEST,
UNDISLIKE_SUCCESS,
UNDISLIKE_FAIL,
REBLOGS_FETCH_REQUEST,
REBLOGS_FETCH_SUCCESS,
REBLOGS_FETCH_FAIL,
FAVOURITES_FETCH_REQUEST,
FAVOURITES_FETCH_SUCCESS,
FAVOURITES_FETCH_FAIL,
DISLIKES_FETCH_REQUEST,
DISLIKES_FETCH_SUCCESS,
DISLIKES_FETCH_FAIL,
REACTIONS_FETCH_REQUEST,
REACTIONS_FETCH_SUCCESS,
REACTIONS_FETCH_FAIL,
@ -528,6 +729,10 @@ export {
REMOTE_INTERACTION_REQUEST,
REMOTE_INTERACTION_SUCCESS,
REMOTE_INTERACTION_FAIL,
FAVOURITES_EXPAND_SUCCESS,
FAVOURITES_EXPAND_FAIL,
REBLOGS_EXPAND_SUCCESS,
REBLOGS_EXPAND_FAIL,
reblog,
unreblog,
toggleReblog,
@ -546,6 +751,15 @@ export {
unfavouriteRequest,
unfavouriteSuccess,
unfavouriteFail,
dislike,
undislike,
toggleDislike,
dislikeRequest,
dislikeSuccess,
dislikeFail,
undislikeRequest,
undislikeSuccess,
undislikeFail,
bookmark,
unbookmark,
toggleBookmark,
@ -559,10 +773,16 @@ export {
fetchReblogsRequest,
fetchReblogsSuccess,
fetchReblogsFail,
expandReblogs,
fetchFavourites,
fetchFavouritesRequest,
fetchFavouritesSuccess,
fetchFavouritesFail,
expandFavourites,
fetchDislikes,
fetchDislikesRequest,
fetchDislikesSuccess,
fetchDislikesFail,
fetchReactions,
fetchReactionsRequest,
fetchReactionsSuccess,
@ -576,6 +796,8 @@ export {
unpinSuccess,
unpinFail,
togglePin,
pinToGroup,
unpinFromGroup,
remoteInteraction,
remoteInteractionRequest,
remoteInteractionSuccess,

Wyświetl plik

@ -1,3 +1,4 @@
import { selectAccount } from 'soapbox/selectors';
import toast from 'soapbox/toast';
import { isLoggedIn } from 'soapbox/utils/auth';
@ -356,7 +357,7 @@ const resetListAdder = () => ({
const setupListAdder = (accountId: string) => (dispatch: AppDispatch, getState: () => RootState) => {
dispatch({
type: LIST_ADDER_SETUP,
account: getState().accounts.get(accountId),
account: selectAccount(getState(), accountId),
});
dispatch(fetchLists());
dispatch(fetchAccountLists(accountId));

Wyświetl plik

@ -1,3 +1,4 @@
import { selectAccount } from 'soapbox/selectors';
import KVStore from 'soapbox/storage/kv-store';
import { getAuthUserId, getAuthUserUrl } from 'soapbox/utils/auth';
@ -10,14 +11,14 @@ import type { AxiosError, RawAxiosRequestHeaders } from 'axios';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { APIEntity } from 'soapbox/types/entities';
const ME_FETCH_REQUEST = 'ME_FETCH_REQUEST';
const ME_FETCH_SUCCESS = 'ME_FETCH_SUCCESS';
const ME_FETCH_FAIL = 'ME_FETCH_FAIL';
const ME_FETCH_SKIP = 'ME_FETCH_SKIP';
const ME_FETCH_REQUEST = 'ME_FETCH_REQUEST' as const;
const ME_FETCH_SUCCESS = 'ME_FETCH_SUCCESS' as const;
const ME_FETCH_FAIL = 'ME_FETCH_FAIL' as const;
const ME_FETCH_SKIP = 'ME_FETCH_SKIP' as const;
const ME_PATCH_REQUEST = 'ME_PATCH_REQUEST';
const ME_PATCH_SUCCESS = 'ME_PATCH_SUCCESS';
const ME_PATCH_FAIL = 'ME_PATCH_FAIL';
const ME_PATCH_REQUEST = 'ME_PATCH_REQUEST' as const;
const ME_PATCH_SUCCESS = 'ME_PATCH_SUCCESS' as const;
const ME_PATCH_FAIL = 'ME_PATCH_FAIL' as const;
const noOp = () => new Promise(f => f(undefined));
@ -25,7 +26,9 @@ const getMeId = (state: RootState) => state.me || getAuthUserId(state);
const getMeUrl = (state: RootState) => {
const accountId = getMeId(state);
return state.accounts.get(accountId)?.url || getAuthUserUrl(state);
if (accountId) {
return selectAccount(state, accountId)?.url || getAuthUserUrl(state);
}
};
const getMeToken = (state: RootState) => {
@ -85,13 +88,10 @@ const fetchMeRequest = () => ({
type: ME_FETCH_REQUEST,
});
const fetchMeSuccess = (me: APIEntity) =>
(dispatch: AppDispatch) => {
dispatch({
type: ME_FETCH_SUCCESS,
me,
});
};
const fetchMeSuccess = (me: APIEntity) => ({
type: ME_FETCH_SUCCESS,
me,
});
const fetchMeFail = (error: APIEntity) => ({
type: ME_FETCH_FAIL,
@ -103,13 +103,20 @@ const patchMeRequest = () => ({
type: ME_PATCH_REQUEST,
});
interface MePatchSuccessAction {
type: typeof ME_PATCH_SUCCESS
me: APIEntity
}
const patchMeSuccess = (me: APIEntity) =>
(dispatch: AppDispatch) => {
dispatch(importFetchedAccount(me));
dispatch({
const action: MePatchSuccessAction = {
type: ME_PATCH_SUCCESS,
me,
});
};
dispatch(importFetchedAccount(me));
dispatch(action);
};
const patchMeFail = (error: AxiosError) => ({
@ -118,6 +125,14 @@ const patchMeFail = (error: AxiosError) => ({
skipAlert: true,
});
type MeAction =
| ReturnType<typeof fetchMeRequest>
| ReturnType<typeof fetchMeSuccess>
| ReturnType<typeof fetchMeFail>
| ReturnType<typeof patchMeRequest>
| MePatchSuccessAction
| ReturnType<typeof patchMeFail>;
export {
ME_FETCH_REQUEST,
ME_FETCH_SUCCESS,
@ -134,4 +149,5 @@ export {
patchMeRequest,
patchMeSuccess,
patchMeFail,
type MeAction,
};

Wyświetl plik

@ -1,3 +1,5 @@
import { AppDispatch } from 'soapbox/store';
import type { ModalType } from 'soapbox/features/ui/components/modal-root';
export const MODAL_OPEN = 'MODAL_OPEN';
@ -5,13 +7,18 @@ export const MODAL_CLOSE = 'MODAL_CLOSE';
/** Open a modal of the given type */
export function openModal(type: ModalType, props?: any) {
return {
type: MODAL_OPEN,
modalType: type,
modalProps: props,
return (dispatch: AppDispatch) => {
dispatch(closeModal(type));
dispatch(openModalSuccess(type, props));
};
}
const openModalSuccess = (type: ModalType, props?: any) => ({
type: MODAL_OPEN,
modalType: type,
modalProps: props,
});
/** Close the modal */
export function closeModal(type?: ModalType) {
return {

Wyświetl plik

@ -7,6 +7,7 @@ import { openModal } from 'soapbox/actions/modals';
import OutlineBox from 'soapbox/components/outline-box';
import { Stack, Text } from 'soapbox/components/ui';
import AccountContainer from 'soapbox/containers/account-container';
import { selectAccount } from 'soapbox/selectors';
import toast from 'soapbox/toast';
import { isLocal } from 'soapbox/utils/accounts';
@ -42,13 +43,13 @@ const messages = defineMessages({
const deactivateUserModal = (intl: IntlShape, accountId: string, afterConfirm = () => {}) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const state = getState();
const acct = state.accounts.get(accountId)!.acct;
const name = state.accounts.get(accountId)!.username;
const acct = selectAccount(state, accountId)!.acct;
const name = selectAccount(state, accountId)!.username;
const message = (
<Stack space={4}>
<OutlineBox>
<AccountContainer id={accountId} />
<AccountContainer id={accountId} hideActions />
</OutlineBox>
<Text>
@ -75,7 +76,7 @@ const deactivateUserModal = (intl: IntlShape, accountId: string, afterConfirm =
const deleteUserModal = (intl: IntlShape, accountId: string, afterConfirm = () => {}) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const state = getState();
const account = state.accounts.get(accountId)!;
const account = selectAccount(state, accountId)!;
const acct = account.acct;
const name = account.username;
const local = isLocal(account);
@ -83,7 +84,7 @@ const deleteUserModal = (intl: IntlShape, accountId: string, afterConfirm = () =
const message = (
<Stack space={4}>
<OutlineBox>
<AccountContainer id={accountId} />
<AccountContainer id={accountId} hideActions />
</OutlineBox>
<Text>
@ -112,32 +113,10 @@ const deleteUserModal = (intl: IntlShape, accountId: string, afterConfirm = () =
}));
};
const rejectUserModal = (intl: IntlShape, accountId: string, afterConfirm = () => {}) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const state = getState();
const acct = state.accounts.get(accountId)!.acct;
const name = state.accounts.get(accountId)!.username;
dispatch(openModal('CONFIRM', {
icon: require('@tabler/icons/user-off.svg'),
heading: intl.formatMessage(messages.rejectUserHeading, { acct }),
message: intl.formatMessage(messages.rejectUserPrompt, { acct }),
confirm: intl.formatMessage(messages.rejectUserConfirm, { name }),
onConfirm: () => {
dispatch(deleteUsers([accountId]))
.then(() => {
afterConfirm();
})
.catch(() => {});
},
}));
};
const toggleStatusSensitivityModal = (intl: IntlShape, statusId: string, sensitive: boolean, afterConfirm = () => {}) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const state = getState();
const accountId = state.statuses.get(statusId)!.account;
const acct = state.accounts.get(accountId)!.acct;
const acct = state.statuses.get(statusId)!.account.acct;
dispatch(openModal('CONFIRM', {
icon: require('@tabler/icons/alert-triangle.svg'),
@ -157,13 +136,12 @@ const toggleStatusSensitivityModal = (intl: IntlShape, statusId: string, sensiti
const deleteStatusModal = (intl: IntlShape, statusId: string, afterConfirm = () => {}) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const state = getState();
const accountId = state.statuses.get(statusId)!.account;
const acct = state.accounts.get(accountId)!.acct;
const acct = state.statuses.get(statusId)!.account.acct;
dispatch(openModal('CONFIRM', {
icon: require('@tabler/icons/trash.svg'),
heading: intl.formatMessage(messages.deleteStatusHeading),
message: intl.formatMessage(messages.deleteStatusPrompt, { acct }),
message: intl.formatMessage(messages.deleteStatusPrompt, { acct: <strong className='break-words'>{acct}</strong> }),
confirm: intl.formatMessage(messages.deleteStatusConfirm),
onConfirm: () => {
dispatch(deleteStatus(statusId)).then(() => {
@ -178,7 +156,6 @@ const deleteStatusModal = (intl: IntlShape, statusId: string, afterConfirm = ()
export {
deactivateUserModal,
deleteUserModal,
rejectUserModal,
toggleStatusSensitivityModal,
deleteStatusModal,
};

Wyświetl plik

@ -1,95 +1,14 @@
import { isLoggedIn } from 'soapbox/utils/auth';
import { getNextLinkName } from 'soapbox/utils/quirks';
import api, { getLinks } from '../api';
import { fetchRelationships } from './accounts';
import { importFetchedAccounts } from './importer';
import { openModal } from './modals';
import type { AxiosError } from 'axios';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { APIEntity, Account as AccountEntity } from 'soapbox/types/entities';
const MUTES_FETCH_REQUEST = 'MUTES_FETCH_REQUEST';
const MUTES_FETCH_SUCCESS = 'MUTES_FETCH_SUCCESS';
const MUTES_FETCH_FAIL = 'MUTES_FETCH_FAIL';
const MUTES_EXPAND_REQUEST = 'MUTES_EXPAND_REQUEST';
const MUTES_EXPAND_SUCCESS = 'MUTES_EXPAND_SUCCESS';
const MUTES_EXPAND_FAIL = 'MUTES_EXPAND_FAIL';
import type { Account } from 'soapbox/schemas';
import type { AppDispatch } from 'soapbox/store';
import type { Account as AccountEntity } from 'soapbox/types/entities';
const MUTES_INIT_MODAL = 'MUTES_INIT_MODAL';
const MUTES_TOGGLE_HIDE_NOTIFICATIONS = 'MUTES_TOGGLE_HIDE_NOTIFICATIONS';
const MUTES_CHANGE_DURATION = 'MUTES_CHANGE_DURATION';
const fetchMutes = () =>
(dispatch: AppDispatch, getState: () => RootState) => {
if (!isLoggedIn(getState)) return;
const nextLinkName = getNextLinkName(getState);
dispatch(fetchMutesRequest());
api(getState).get('/api/v1/mutes').then(response => {
const next = getLinks(response).refs.find(link => link.rel === nextLinkName);
dispatch(importFetchedAccounts(response.data));
dispatch(fetchMutesSuccess(response.data, next ? next.uri : null));
dispatch(fetchRelationships(response.data.map((item: APIEntity) => item.id)));
}).catch(error => dispatch(fetchMutesFail(error)));
};
const fetchMutesRequest = () => ({
type: MUTES_FETCH_REQUEST,
});
const fetchMutesSuccess = (accounts: APIEntity[], next: string | null) => ({
type: MUTES_FETCH_SUCCESS,
accounts,
next,
});
const fetchMutesFail = (error: AxiosError) => ({
type: MUTES_FETCH_FAIL,
error,
});
const expandMutes = () =>
(dispatch: AppDispatch, getState: () => RootState) => {
if (!isLoggedIn(getState)) return;
const nextLinkName = getNextLinkName(getState);
const url = getState().user_lists.mutes.next;
if (url === null) {
return;
}
dispatch(expandMutesRequest());
api(getState).get(url).then(response => {
const next = getLinks(response).refs.find(link => link.rel === nextLinkName);
dispatch(importFetchedAccounts(response.data));
dispatch(expandMutesSuccess(response.data, next ? next.uri : null));
dispatch(fetchRelationships(response.data.map((item: APIEntity) => item.id)));
}).catch(error => dispatch(expandMutesFail(error)));
};
const expandMutesRequest = () => ({
type: MUTES_EXPAND_REQUEST,
});
const expandMutesSuccess = (accounts: APIEntity[], next: string | null) => ({
type: MUTES_EXPAND_SUCCESS,
accounts,
next,
});
const expandMutesFail = (error: AxiosError) => ({
type: MUTES_EXPAND_FAIL,
error,
});
const initMuteModal = (account: AccountEntity) =>
const initMuteModal = (account: AccountEntity | Account) =>
(dispatch: AppDispatch) => {
dispatch({
type: MUTES_INIT_MODAL,
@ -113,23 +32,9 @@ const changeMuteDuration = (duration: number) =>
};
export {
MUTES_FETCH_REQUEST,
MUTES_FETCH_SUCCESS,
MUTES_FETCH_FAIL,
MUTES_EXPAND_REQUEST,
MUTES_EXPAND_SUCCESS,
MUTES_EXPAND_FAIL,
MUTES_INIT_MODAL,
MUTES_TOGGLE_HIDE_NOTIFICATIONS,
MUTES_CHANGE_DURATION,
fetchMutes,
fetchMutesRequest,
fetchMutesSuccess,
fetchMutesFail,
expandMutes,
expandMutesRequest,
expandMutesSuccess,
expandMutesFail,
initMuteModal,
toggleHideNotifications,
changeMuteDuration,

Wyświetl plik

@ -12,6 +12,7 @@ import { EXCLUDE_TYPES, NOTIFICATION_TYPES } from 'soapbox/utils/notification';
import { joinPublicPath } from 'soapbox/utils/static';
import { fetchRelationships } from './accounts';
import { fetchGroupRelationships } from './groups';
import {
importFetchedAccount,
importFetchedAccounts,
@ -23,7 +24,7 @@ import { getSettings, saveSettings } from './settings';
import type { AxiosError } from 'axios';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { APIEntity } from 'soapbox/types/entities';
import type { APIEntity, Status } from 'soapbox/types/entities';
const NOTIFICATIONS_UPDATE = 'NOTIFICATIONS_UPDATE';
const NOTIFICATIONS_UPDATE_NOOP = 'NOTIFICATIONS_UPDATE_NOOP';
@ -237,6 +238,9 @@ const expandNotifications = ({ maxId }: Record<string, any> = {}, done: () => an
dispatch(importFetchedAccounts(Object.values(entries.accounts)));
dispatch(importFetchedStatuses(Object.values(entries.statuses)));
const statusesFromGroups = (Object.values(entries.statuses) as Status[]).filter((status) => !!status.group);
dispatch(fetchGroupRelationships(statusesFromGroups.map((status: any) => status.group?.id)));
dispatch(expandNotificationsSuccess(response.data, next ? next.uri : null, isLoadingMore));
fetchRelatedRelationships(dispatch, response.data);
done();

Wyświetl plik

@ -6,9 +6,11 @@
* @see module:soapbox/actions/auth
*/
import { getBaseURL } from 'soapbox/utils/state';
import { baseClient } from '../api';
import type { AppDispatch } from 'soapbox/store';
import type { AppDispatch, RootState } from 'soapbox/store';
export const OAUTH_TOKEN_CREATE_REQUEST = 'OAUTH_TOKEN_CREATE_REQUEST';
export const OAUTH_TOKEN_CREATE_SUCCESS = 'OAUTH_TOKEN_CREATE_SUCCESS';
@ -31,9 +33,10 @@ export const obtainOAuthToken = (params: Record<string, string | undefined>, bas
};
export const revokeOAuthToken = (params: Record<string, string>) =>
(dispatch: AppDispatch) => {
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch({ type: OAUTH_TOKEN_REVOKE_REQUEST, params });
return baseClient().post('/oauth/revoke', params).then(({ data }) => {
const baseURL = getBaseURL(getState());
return baseClient(null, baseURL).post('/oauth/revoke', params).then(({ data }) => {
dispatch({ type: OAUTH_TOKEN_REVOKE_SUCCESS, params, data });
return data;
}).catch(error => {

Wyświetl plik

@ -37,8 +37,8 @@ const subscribe = (registration: ServiceWorkerRegistration, getState: () => Root
});
const unsubscribe = ({ registration, subscription }: {
registration: ServiceWorkerRegistration,
subscription: PushSubscription | null,
registration: ServiceWorkerRegistration
subscription: PushSubscription | null
}) =>
subscription ? subscription.unsubscribe().then(() => registration) : new Promise<ServiceWorkerRegistration>(r => r(registration));
@ -82,8 +82,8 @@ const register = () =>
.then(getPushSubscription)
// @ts-ignore
.then(({ registration, subscription }: {
registration: ServiceWorkerRegistration,
subscription: PushSubscription | null,
registration: ServiceWorkerRegistration
subscription: PushSubscription | null
}) => {
if (subscription !== null) {
// We have a subscription, check if it is still valid

Wyświetl plik

@ -3,8 +3,9 @@ import api from '../api';
import { openModal } from './modals';
import type { AxiosError } from 'axios';
import type { Account } from 'soapbox/schemas';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { Account, ChatMessage, Status } from 'soapbox/types/entities';
import type { ChatMessage, Group, Status } from 'soapbox/types/entities';
const REPORT_INIT = 'REPORT_INIT';
const REPORT_CANCEL = 'REPORT_CANCEL';
@ -20,19 +21,29 @@ const REPORT_BLOCK_CHANGE = 'REPORT_BLOCK_CHANGE';
const REPORT_RULE_CHANGE = 'REPORT_RULE_CHANGE';
type ReportedEntity = {
status?: Status,
chatMessage?: ChatMessage
enum ReportableEntities {
ACCOUNT = 'ACCOUNT',
CHAT_MESSAGE = 'CHAT_MESSAGE',
GROUP = 'GROUP',
STATUS = 'STATUS'
}
const initReport = (account: Account, entities?: ReportedEntity) => (dispatch: AppDispatch) => {
const { status, chatMessage } = entities || {};
type ReportedEntity = {
status?: Status
chatMessage?: ChatMessage
group?: Group
}
const initReport = (entityType: ReportableEntities, account: Account, entities?: ReportedEntity) => (dispatch: AppDispatch) => {
const { status, chatMessage, group } = entities || {};
dispatch({
type: REPORT_INIT,
entityType,
account,
status,
chatMessage,
group,
});
return dispatch(openModal('REPORT'));
@ -56,7 +67,8 @@ const submitReport = () =>
return api(getState).post('/api/v1/reports', {
account_id: reports.getIn(['new', 'account_id']),
status_ids: reports.getIn(['new', 'status_ids']),
message_ids: [reports.getIn(['new', 'chat_message', 'id'])],
message_ids: [reports.getIn(['new', 'chat_message', 'id'])].filter(Boolean),
group_id: reports.getIn(['new', 'group', 'id']),
rule_ids: reports.getIn(['new', 'rule_ids']),
comment: reports.getIn(['new', 'comment']),
forward: reports.getIn(['new', 'forward']),
@ -97,6 +109,7 @@ const changeReportRule = (ruleId: string) => ({
});
export {
ReportableEntities,
REPORT_INIT,
REPORT_CANCEL,
REPORT_SUBMIT_REQUEST,

Wyświetl plik

@ -1,7 +1,7 @@
import api from '../api';
import api, { getLinks } from '../api';
import { fetchRelationships } from './accounts';
import { importFetchedAccounts, importFetchedGroups, importFetchedStatuses } from './importer';
import { importFetchedAccounts, importFetchedStatuses } from './importer';
import type { AxiosError } from 'axios';
import type { SearchFilter } from 'soapbox/reducers/search';
@ -83,11 +83,9 @@ const submitSearch = (filter?: SearchFilter) =>
dispatch(importFetchedStatuses(response.data.statuses));
}
if (response.data.groups) {
dispatch(importFetchedGroups(response.data.groups));
}
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(fetchSearchSuccess(response.data, value, type));
dispatch(fetchSearchSuccess(response.data, value, type, next ? next.uri : null));
dispatch(fetchRelationships(response.data.accounts.map((item: APIEntity) => item.id)));
}).catch(error => {
dispatch(fetchSearchFail(error));
@ -99,11 +97,12 @@ const fetchSearchRequest = (value: string) => ({
value,
});
const fetchSearchSuccess = (results: APIEntity[], searchTerm: string, searchType: SearchFilter) => ({
const fetchSearchSuccess = (results: APIEntity[], searchTerm: string, searchType: SearchFilter, next: string | null) => ({
type: SEARCH_FETCH_SUCCESS,
results,
searchTerm,
searchType,
next,
});
const fetchSearchFail = (error: AxiosError) => ({
@ -123,18 +122,32 @@ const setFilter = (filterType: SearchFilter) =>
};
const expandSearch = (type: SearchFilter) => (dispatch: AppDispatch, getState: () => RootState) => {
const value = getState().search.value;
const offset = getState().search.results[type].size;
const value = getState().search.value;
const offset = getState().search.results[type].size;
const accountId = getState().search.accountId;
dispatch(expandSearchRequest(type));
api(getState).get('/api/v2/search', {
params: {
let url = getState().search.next as string;
let params: Record<string, any> = {};
// if no URL was extracted from the Link header,
// fall back on querying with the offset
if (!url) {
url = '/api/v2/search';
params = {
q: value,
type,
offset,
},
}).then(({ data }) => {
};
if (accountId) params.account_id = accountId;
}
api(getState).get(url, {
params,
}).then(response => {
const data = response.data;
if (data.accounts) {
dispatch(importFetchedAccounts(data.accounts));
}
@ -143,11 +156,9 @@ const expandSearch = (type: SearchFilter) => (dispatch: AppDispatch, getState: (
dispatch(importFetchedStatuses(data.statuses));
}
if (data.groups) {
dispatch(importFetchedGroups(data.groups));
}
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(expandSearchSuccess(data, value, type));
dispatch(expandSearchSuccess(data, value, type, next ? next.uri : null));
dispatch(fetchRelationships(data.accounts.map((item: APIEntity) => item.id)));
}).catch(error => {
dispatch(expandSearchFail(error));
@ -159,11 +170,12 @@ const expandSearchRequest = (searchType: SearchFilter) => ({
searchType,
});
const expandSearchSuccess = (results: APIEntity[], searchTerm: string, searchType: SearchFilter) => ({
const expandSearchSuccess = (results: APIEntity[], searchTerm: string, searchType: SearchFilter, next: string | null) => ({
type: SEARCH_EXPAND_SUCCESS,
results,
searchTerm,
searchType,
next,
});
const expandSearchFail = (error: AxiosError) => ({

Wyświetl plik

@ -1,29 +1,28 @@
import { Map as ImmutableMap, List as ImmutableList, OrderedSet as ImmutableOrderedSet } from 'immutable';
import { defineMessages } from 'react-intl';
import { defineMessage } from 'react-intl';
import { createSelector } from 'reselect';
import { v4 as uuid } from 'uuid';
import { patchMe } from 'soapbox/actions/me';
import messages from 'soapbox/messages';
import toast from 'soapbox/toast';
import { isLoggedIn } from 'soapbox/utils/auth';
import type { AppDispatch, RootState } from 'soapbox/store';
const SETTING_CHANGE = 'SETTING_CHANGE';
const SETTING_SAVE = 'SETTING_SAVE';
const SETTINGS_UPDATE = 'SETTINGS_UPDATE';
const SETTING_CHANGE = 'SETTING_CHANGE' as const;
const SETTING_SAVE = 'SETTING_SAVE' as const;
const SETTINGS_UPDATE = 'SETTINGS_UPDATE' as const;
const FE_NAME = 'soapbox_fe';
/** Options when changing/saving settings. */
type SettingOpts = {
/** Whether to display an alert when settings are saved. */
showAlert?: boolean,
showAlert?: boolean
}
const messages = defineMessages({
saveSuccess: { id: 'settings.save.success', defaultMessage: 'Your preferences have been saved!' },
});
const saveSuccessMessage = defineMessage({ id: 'settings.save.success', defaultMessage: 'Your preferences have been saved!' });
const defaultSettings = ImmutableMap({
onboarded: false,
@ -40,11 +39,12 @@ const defaultSettings = ImmutableMap({
defaultPrivacy: 'public',
defaultContentType: 'text/plain',
themeMode: 'system',
locale: navigator.language.split(/[-_]/)[0] || 'en',
locale: navigator.language || 'en',
showExplanationBox: true,
explanationBox: true,
autoloadTimelines: true,
autoloadMore: true,
preserveSpoilers: false,
systemFont: false,
demetricator: false,
@ -182,25 +182,33 @@ const getSettings = createSelector([
.mergeDeep(settings);
});
interface SettingChangeAction {
type: typeof SETTING_CHANGE
path: string[]
value: any
}
const changeSettingImmediate = (path: string[], value: any, opts?: SettingOpts) =>
(dispatch: AppDispatch) => {
dispatch({
const action: SettingChangeAction = {
type: SETTING_CHANGE,
path,
value,
});
};
dispatch(action);
dispatch(saveSettingsImmediate(opts));
};
const changeSetting = (path: string[], value: any, opts?: SettingOpts) =>
(dispatch: AppDispatch) => {
dispatch({
const action: SettingChangeAction = {
type: SETTING_CHANGE,
path,
value,
});
};
dispatch(action);
return dispatch(saveSettings(opts));
};
@ -221,7 +229,7 @@ const saveSettingsImmediate = (opts?: SettingOpts) =>
dispatch({ type: SETTING_SAVE });
if (opts?.showAlert) {
toast.success(messages.saveSuccess);
toast.success(saveSuccessMessage);
}
}).catch(error => {
toast.showAlertForError(error);
@ -231,6 +239,16 @@ const saveSettingsImmediate = (opts?: SettingOpts) =>
const saveSettings = (opts?: SettingOpts) =>
(dispatch: AppDispatch) => dispatch(saveSettingsImmediate(opts));
const getLocale = (state: RootState, fallback = 'en') => {
const localeWithVariant = (getSettings(state).get('locale') as string).replace('_', '-');
const locale = localeWithVariant.split('-')[0];
return Object.keys(messages).includes(localeWithVariant) ? localeWithVariant : Object.keys(messages).includes(locale) ? locale : fallback;
};
type SettingsAction =
| SettingChangeAction
| { type: typeof SETTING_SAVE }
export {
SETTING_CHANGE,
SETTING_SAVE,
@ -242,4 +260,6 @@ export {
changeSetting,
saveSettingsImmediate,
saveSettings,
getLocale,
type SettingsAction,
};

Wyświetl plik

@ -5,6 +5,7 @@ import { shouldHaveCard } from 'soapbox/utils/status';
import api, { getNextLink } from '../api';
import { setComposeToStatus } from './compose';
import { fetchGroupRelationships } from './groups';
import { importFetchedStatus, importFetchedStatuses } from './importer';
import { openModal } from './modals';
import { deleteFromTimelines } from './timelines';
@ -48,6 +49,8 @@ const STATUS_TRANSLATE_SUCCESS = 'STATUS_TRANSLATE_SUCCESS';
const STATUS_TRANSLATE_FAIL = 'STATUS_TRANSLATE_FAIL';
const STATUS_TRANSLATE_UNDO = 'STATUS_TRANSLATE_UNDO';
const STATUS_UNFILTER = 'STATUS_UNFILTER';
const statusExists = (getState: () => RootState, statusId: string) => {
return (getState().statuses.get(statusId) || null) !== null;
};
@ -122,6 +125,9 @@ const fetchStatus = (id: string) => {
return api(getState).get(`/api/v1/statuses/${id}`).then(({ data: status }) => {
dispatch(importFetchedStatus(status));
if (status.group) {
dispatch(fetchGroupRelationships([status.group.id]));
}
dispatch({ type: STATUS_FETCH_SUCCESS, status, skipLoading });
return status;
}).catch(error => {
@ -335,6 +341,11 @@ const undoStatusTranslation = (id: string) => ({
id,
});
const unfilterStatus = (id: string) => ({
type: STATUS_UNFILTER,
id,
});
export {
STATUS_CREATE_REQUEST,
STATUS_CREATE_SUCCESS,
@ -363,6 +374,7 @@ export {
STATUS_TRANSLATE_SUCCESS,
STATUS_TRANSLATE_FAIL,
STATUS_TRANSLATE_UNDO,
STATUS_UNFILTER,
createStatus,
editStatus,
fetchStatus,
@ -381,4 +393,5 @@ export {
toggleStatusHidden,
translateStatus,
undoStatusTranslation,
unfilterStatus,
};

Wyświetl plik

@ -1,5 +1,8 @@
import { getSettings } from 'soapbox/actions/settings';
import messages from 'soapbox/locales/messages';
import { getLocale, getSettings } from 'soapbox/actions/settings';
import { importEntities } from 'soapbox/entity-store/actions';
import { Entities } from 'soapbox/entity-store/entities';
import { selectEntity } from 'soapbox/entity-store/selectors';
import messages from 'soapbox/messages';
import { ChatKeys, IChat, isLastMessage } from 'soapbox/queries/chats';
import { queryClient } from 'soapbox/queries/client';
import { getUnreadChatsCount, updateChatListItem, updateChatMessage } from 'soapbox/utils/chats';
@ -10,46 +13,27 @@ import { connectStream } from '../stream';
import {
deleteAnnouncement,
fetchAnnouncements,
updateAnnouncements,
updateReaction as updateAnnouncementsReaction,
} from './announcements';
import { updateConversations } from './conversations';
import { fetchFilters } from './filters';
import { MARKER_FETCH_SUCCESS } from './markers';
import { updateNotificationsQueue, expandNotifications } from './notifications';
import { updateNotificationsQueue } from './notifications';
import { updateStatus } from './statuses';
import {
// deleteFromTimelines,
expandHomeTimeline,
connectTimeline,
disconnectTimeline,
processTimelineUpdate,
} from './timelines';
import type { IStatContext } from 'soapbox/contexts/stat-context';
import type { Relationship } from 'soapbox/schemas';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { APIEntity, Chat } from 'soapbox/types/entities';
const STREAMING_CHAT_UPDATE = 'STREAMING_CHAT_UPDATE';
const STREAMING_FOLLOW_RELATIONSHIPS_UPDATE = 'STREAMING_FOLLOW_RELATIONSHIPS_UPDATE';
const validLocale = (locale: string) => Object.keys(messages).includes(locale);
const getLocale = (state: RootState) => {
const locale = getSettings(state).get('locale') as string;
return validLocale(locale) ? locale : 'en';
};
const updateFollowRelationships = (relationships: APIEntity) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const me = getState().me;
return dispatch({
type: STREAMING_FOLLOW_RELATIONSHIPS_UPDATE,
me,
...relationships,
});
};
const removeChatMessage = (payload: string) => {
const data = JSON.parse(payload);
@ -80,8 +64,9 @@ const updateChatQuery = (chat: IChat) => {
queryClient.setQueryData<Chat>(ChatKeys.chat(chat.id), newChat as any);
};
interface StreamOpts {
statContext?: IStatContext,
interface TimelineStreamOpts {
statContext?: IStatContext
enabled?: boolean
}
const connectTimelineStream = (
@ -89,7 +74,7 @@ const connectTimelineStream = (
path: string,
pollingRefresh: ((dispatch: AppDispatch, done?: () => void) => void) | null = null,
accept: ((status: APIEntity) => boolean) | null = null,
opts?: StreamOpts,
opts?: TimelineStreamOpts,
) => connectStream(path, pollingRefresh, (dispatch: AppDispatch, getState: () => RootState) => {
const locale = getLocale(getState());
@ -102,7 +87,7 @@ const connectTimelineStream = (
dispatch(disconnectTimeline(timelineId));
},
onReceive(data: any) {
onReceive(websocket, data: any) {
switch (data.event) {
case 'update':
dispatch(processTimelineUpdate(timelineId, JSON.parse(data.payload), accept));
@ -193,45 +178,52 @@ const connectTimelineStream = (
};
});
const refreshHomeTimelineAndNotification = (dispatch: AppDispatch, done?: () => void) =>
dispatch(expandHomeTimeline({}, () =>
dispatch(expandNotifications({}, () =>
dispatch(fetchAnnouncements(done))))));
function followStateToRelationship(followState: string) {
switch (followState) {
case 'follow_pending':
return { following: false, requested: true };
case 'follow_accept':
return { following: true, requested: false };
case 'follow_reject':
return { following: false, requested: false };
default:
return {};
}
}
const connectUserStream = (opts?: StreamOpts) =>
connectTimelineStream('home', 'user', refreshHomeTimelineAndNotification, null, opts);
interface FollowUpdate {
state: 'follow_pending' | 'follow_accept' | 'follow_reject'
follower: {
id: string
follower_count: number
following_count: number
}
following: {
id: string
follower_count: number
following_count: number
}
}
const connectCommunityStream = ({ onlyMedia }: Record<string, any> = {}) =>
connectTimelineStream(`community${onlyMedia ? ':media' : ''}`, `public:local${onlyMedia ? ':media' : ''}`);
function updateFollowRelationships(update: FollowUpdate) {
return (dispatch: AppDispatch, getState: () => RootState) => {
const me = getState().me;
const relationship = selectEntity<Relationship>(getState(), Entities.RELATIONSHIPS, update.following.id);
const connectPublicStream = ({ onlyMedia }: Record<string, any> = {}) =>
connectTimelineStream(`public${onlyMedia ? ':media' : ''}`, `public${onlyMedia ? ':media' : ''}`);
if (update.follower.id === me && relationship) {
const updated = {
...relationship,
...followStateToRelationship(update.state),
};
const connectRemoteStream = (instance: string, { onlyMedia }: Record<string, any> = {}) =>
connectTimelineStream(`remote${onlyMedia ? ':media' : ''}:${instance}`, `public:remote${onlyMedia ? ':media' : ''}&instance=${instance}`);
const connectHashtagStream = (id: string, tag: string, accept: (status: APIEntity) => boolean) =>
connectTimelineStream(`hashtag:${id}`, `hashtag&tag=${tag}`, null, accept);
const connectDirectStream = () =>
connectTimelineStream('direct', 'direct');
const connectListStream = (id: string) =>
connectTimelineStream(`list:${id}`, `list&list=${id}`);
const connectGroupStream = (id: string) =>
connectTimelineStream(`group:${id}`, `group&group=${id}`);
// Add a small delay to deal with API race conditions.
setTimeout(() => dispatch(importEntities([updated], Entities.RELATIONSHIPS)), 300);
}
};
}
export {
STREAMING_CHAT_UPDATE,
STREAMING_FOLLOW_RELATIONSHIPS_UPDATE,
connectTimelineStream,
connectUserStream,
connectCommunityStream,
connectPublicStream,
connectRemoteStream,
connectHashtagStream,
connectDirectStream,
connectListStream,
connectGroupStream,
type TimelineStreamOpts,
};

Wyświetl plik

@ -0,0 +1,201 @@
import api, { getLinks } from '../api';
import type { AxiosError } from 'axios';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { APIEntity } from 'soapbox/types/entities';
const HASHTAG_FETCH_REQUEST = 'HASHTAG_FETCH_REQUEST';
const HASHTAG_FETCH_SUCCESS = 'HASHTAG_FETCH_SUCCESS';
const HASHTAG_FETCH_FAIL = 'HASHTAG_FETCH_FAIL';
const HASHTAG_FOLLOW_REQUEST = 'HASHTAG_FOLLOW_REQUEST';
const HASHTAG_FOLLOW_SUCCESS = 'HASHTAG_FOLLOW_SUCCESS';
const HASHTAG_FOLLOW_FAIL = 'HASHTAG_FOLLOW_FAIL';
const HASHTAG_UNFOLLOW_REQUEST = 'HASHTAG_UNFOLLOW_REQUEST';
const HASHTAG_UNFOLLOW_SUCCESS = 'HASHTAG_UNFOLLOW_SUCCESS';
const HASHTAG_UNFOLLOW_FAIL = 'HASHTAG_UNFOLLOW_FAIL';
const FOLLOWED_HASHTAGS_FETCH_REQUEST = 'FOLLOWED_HASHTAGS_FETCH_REQUEST';
const FOLLOWED_HASHTAGS_FETCH_SUCCESS = 'FOLLOWED_HASHTAGS_FETCH_SUCCESS';
const FOLLOWED_HASHTAGS_FETCH_FAIL = 'FOLLOWED_HASHTAGS_FETCH_FAIL';
const FOLLOWED_HASHTAGS_EXPAND_REQUEST = 'FOLLOWED_HASHTAGS_EXPAND_REQUEST';
const FOLLOWED_HASHTAGS_EXPAND_SUCCESS = 'FOLLOWED_HASHTAGS_EXPAND_SUCCESS';
const FOLLOWED_HASHTAGS_EXPAND_FAIL = 'FOLLOWED_HASHTAGS_EXPAND_FAIL';
const fetchHashtag = (name: string) => (dispatch: AppDispatch, getState: () => RootState) => {
dispatch(fetchHashtagRequest());
api(getState).get(`/api/v1/tags/${name}`).then(({ data }) => {
dispatch(fetchHashtagSuccess(name, data));
}).catch(err => {
dispatch(fetchHashtagFail(err));
});
};
const fetchHashtagRequest = () => ({
type: HASHTAG_FETCH_REQUEST,
});
const fetchHashtagSuccess = (name: string, tag: APIEntity) => ({
type: HASHTAG_FETCH_SUCCESS,
name,
tag,
});
const fetchHashtagFail = (error: AxiosError) => ({
type: HASHTAG_FETCH_FAIL,
error,
});
const followHashtag = (name: string) => (dispatch: AppDispatch, getState: () => RootState) => {
dispatch(followHashtagRequest(name));
api(getState).post(`/api/v1/tags/${name}/follow`).then(({ data }) => {
dispatch(followHashtagSuccess(name, data));
}).catch(err => {
dispatch(followHashtagFail(name, err));
});
};
const followHashtagRequest = (name: string) => ({
type: HASHTAG_FOLLOW_REQUEST,
name,
});
const followHashtagSuccess = (name: string, tag: APIEntity) => ({
type: HASHTAG_FOLLOW_SUCCESS,
name,
tag,
});
const followHashtagFail = (name: string, error: AxiosError) => ({
type: HASHTAG_FOLLOW_FAIL,
name,
error,
});
const unfollowHashtag = (name: string) => (dispatch: AppDispatch, getState: () => RootState) => {
dispatch(unfollowHashtagRequest(name));
api(getState).post(`/api/v1/tags/${name}/unfollow`).then(({ data }) => {
dispatch(unfollowHashtagSuccess(name, data));
}).catch(err => {
dispatch(unfollowHashtagFail(name, err));
});
};
const unfollowHashtagRequest = (name: string) => ({
type: HASHTAG_UNFOLLOW_REQUEST,
name,
});
const unfollowHashtagSuccess = (name: string, tag: APIEntity) => ({
type: HASHTAG_UNFOLLOW_SUCCESS,
name,
tag,
});
const unfollowHashtagFail = (name: string, error: AxiosError) => ({
type: HASHTAG_UNFOLLOW_FAIL,
name,
error,
});
const fetchFollowedHashtags = () => (dispatch: AppDispatch, getState: () => RootState) => {
dispatch(fetchFollowedHashtagsRequest());
api(getState).get('/api/v1/followed_tags').then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(fetchFollowedHashtagsSuccess(response.data, next ? next.uri : null));
}).catch(err => {
dispatch(fetchFollowedHashtagsFail(err));
});
};
const fetchFollowedHashtagsRequest = () => ({
type: FOLLOWED_HASHTAGS_FETCH_REQUEST,
});
const fetchFollowedHashtagsSuccess = (followed_tags: APIEntity[], next: string | null) => ({
type: FOLLOWED_HASHTAGS_FETCH_SUCCESS,
followed_tags,
next,
});
const fetchFollowedHashtagsFail = (error: AxiosError) => ({
type: FOLLOWED_HASHTAGS_FETCH_FAIL,
error,
});
const expandFollowedHashtags = () => (dispatch: AppDispatch, getState: () => RootState) => {
const url = getState().followed_tags.next;
if (url === null) {
return;
}
dispatch(expandFollowedHashtagsRequest());
api(getState).get(url).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(expandFollowedHashtagsSuccess(response.data, next ? next.uri : null));
}).catch(error => {
dispatch(expandFollowedHashtagsFail(error));
});
};
const expandFollowedHashtagsRequest = () => ({
type: FOLLOWED_HASHTAGS_EXPAND_REQUEST,
});
const expandFollowedHashtagsSuccess = (followed_tags: APIEntity[], next: string | null) => ({
type: FOLLOWED_HASHTAGS_EXPAND_SUCCESS,
followed_tags,
next,
});
const expandFollowedHashtagsFail = (error: AxiosError) => ({
type: FOLLOWED_HASHTAGS_EXPAND_FAIL,
error,
});
export {
HASHTAG_FETCH_REQUEST,
HASHTAG_FETCH_SUCCESS,
HASHTAG_FETCH_FAIL,
HASHTAG_FOLLOW_REQUEST,
HASHTAG_FOLLOW_SUCCESS,
HASHTAG_FOLLOW_FAIL,
HASHTAG_UNFOLLOW_REQUEST,
HASHTAG_UNFOLLOW_SUCCESS,
HASHTAG_UNFOLLOW_FAIL,
FOLLOWED_HASHTAGS_FETCH_REQUEST,
FOLLOWED_HASHTAGS_FETCH_SUCCESS,
FOLLOWED_HASHTAGS_FETCH_FAIL,
FOLLOWED_HASHTAGS_EXPAND_REQUEST,
FOLLOWED_HASHTAGS_EXPAND_SUCCESS,
FOLLOWED_HASHTAGS_EXPAND_FAIL,
fetchHashtag,
fetchHashtagRequest,
fetchHashtagSuccess,
fetchHashtagFail,
followHashtag,
followHashtagRequest,
followHashtagSuccess,
followHashtagFail,
unfollowHashtag,
unfollowHashtagRequest,
unfollowHashtagSuccess,
unfollowHashtagFail,
fetchFollowedHashtags,
fetchFollowedHashtagsRequest,
fetchFollowedHashtagsSuccess,
fetchFollowedHashtagsFail,
expandFollowedHashtags,
expandFollowedHashtagsRequest,
expandFollowedHashtagsSuccess,
expandFollowedHashtagsFail,
};

Wyświetl plik

@ -4,31 +4,32 @@ import { getSettings } from 'soapbox/actions/settings';
import { normalizeStatus } from 'soapbox/normalizers';
import { shouldFilter } from 'soapbox/utils/timelines';
import api, { getLinks } from '../api';
import api, { getNextLink, getPrevLink } from '../api';
import { fetchGroupRelationships } from './groups';
import { importFetchedStatus, importFetchedStatuses } from './importer';
import type { AxiosError } from 'axios';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { APIEntity, Status } from 'soapbox/types/entities';
const TIMELINE_UPDATE = 'TIMELINE_UPDATE';
const TIMELINE_DELETE = 'TIMELINE_DELETE';
const TIMELINE_CLEAR = 'TIMELINE_CLEAR';
const TIMELINE_UPDATE_QUEUE = 'TIMELINE_UPDATE_QUEUE';
const TIMELINE_DEQUEUE = 'TIMELINE_DEQUEUE';
const TIMELINE_SCROLL_TOP = 'TIMELINE_SCROLL_TOP';
const TIMELINE_UPDATE = 'TIMELINE_UPDATE' as const;
const TIMELINE_DELETE = 'TIMELINE_DELETE' as const;
const TIMELINE_CLEAR = 'TIMELINE_CLEAR' as const;
const TIMELINE_UPDATE_QUEUE = 'TIMELINE_UPDATE_QUEUE' as const;
const TIMELINE_DEQUEUE = 'TIMELINE_DEQUEUE' as const;
const TIMELINE_SCROLL_TOP = 'TIMELINE_SCROLL_TOP' as const;
const TIMELINE_EXPAND_REQUEST = 'TIMELINE_EXPAND_REQUEST';
const TIMELINE_EXPAND_SUCCESS = 'TIMELINE_EXPAND_SUCCESS';
const TIMELINE_EXPAND_FAIL = 'TIMELINE_EXPAND_FAIL';
const TIMELINE_EXPAND_REQUEST = 'TIMELINE_EXPAND_REQUEST' as const;
const TIMELINE_EXPAND_SUCCESS = 'TIMELINE_EXPAND_SUCCESS' as const;
const TIMELINE_EXPAND_FAIL = 'TIMELINE_EXPAND_FAIL' as const;
const TIMELINE_CONNECT = 'TIMELINE_CONNECT';
const TIMELINE_DISCONNECT = 'TIMELINE_DISCONNECT';
const TIMELINE_CONNECT = 'TIMELINE_CONNECT' as const;
const TIMELINE_DISCONNECT = 'TIMELINE_DISCONNECT' as const;
const TIMELINE_REPLACE = 'TIMELINE_REPLACE';
const TIMELINE_INSERT = 'TIMELINE_INSERT';
const TIMELINE_CLEAR_FEED_ACCOUNT_ID = 'TIMELINE_CLEAR_FEED_ACCOUNT_ID';
const TIMELINE_REPLACE = 'TIMELINE_REPLACE' as const;
const TIMELINE_INSERT = 'TIMELINE_INSERT' as const;
const TIMELINE_CLEAR_FEED_ACCOUNT_ID = 'TIMELINE_CLEAR_FEED_ACCOUNT_ID' as const;
const MAX_QUEUED_ITEMS = 40;
@ -39,7 +40,7 @@ const processTimelineUpdate = (timeline: string, status: APIEntity, accept: ((st
const hasPendingStatuses = !getState().pending_statuses.isEmpty();
const columnSettings = getSettings(getState()).get(timeline, ImmutableMap());
const shouldSkipQueue = shouldFilter(normalizeStatus(status) as Status, columnSettings);
const shouldSkipQueue = shouldFilter(normalizeStatus(status) as Status, columnSettings as any);
if (ownStatus && hasPendingStatuses) {
// WebSockets push statuses without the Idempotency-Key,
@ -110,19 +111,29 @@ const dequeueTimeline = (timelineId: string, expandFunc?: (lastStatusId: string)
}
};
interface TimelineDeleteAction {
type: typeof TIMELINE_DELETE
id: string
accountId: string
references: ImmutableMap<string, readonly [statusId: string, accountId: string]>
reblogOf: unknown
}
const deleteFromTimelines = (id: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const accountId = getState().statuses.get(id)?.account;
const references = getState().statuses.filter(status => status.get('reblog') === id).map(status => [status.get('id'), status.get('account')]);
const accountId = getState().statuses.get(id)?.account?.id!;
const references = getState().statuses.filter(status => status.reblog === id).map(status => [status.id, status.account.id] as const);
const reblogOf = getState().statuses.getIn([id, 'reblog'], null);
dispatch({
const action: TimelineDeleteAction = {
type: TIMELINE_DELETE,
id,
accountId,
references,
reblogOf,
});
};
dispatch(action);
};
const clearTimeline = (timeline: string) =>
@ -139,7 +150,7 @@ const parseTags = (tags: Record<string, any[]> = {}, mode: 'any' | 'all' | 'none
};
const replaceHomeTimeline = (
accountId: string | null,
accountId: string | undefined,
{ maxId }: Record<string, any> = {},
done?: () => void,
) => (dispatch: AppDispatch, _getState: () => RootState) => {
@ -162,7 +173,12 @@ const expandTimeline = (timelineId: string, path: string, params: Record<string,
return dispatch(noOpAsync());
}
if (!params.max_id && !params.pinned && (timeline.items || ImmutableOrderedSet()).size > 0) {
if (
!params.max_id &&
!params.pinned &&
(timeline.items || ImmutableOrderedSet()).size > 0 &&
!path.includes('max_id=')
) {
params.since_id = timeline.getIn(['items', 0]);
}
@ -171,9 +187,20 @@ const expandTimeline = (timelineId: string, path: string, params: Record<string,
dispatch(expandTimelineRequest(timelineId, isLoadingMore));
return api(getState).get(path, { params }).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedStatuses(response.data));
dispatch(expandTimelineSuccess(timelineId, response.data, next ? next.uri : null, response.status === 206, isLoadingRecent, isLoadingMore));
const statusesFromGroups = (response.data as Status[]).filter((status) => !!status.group);
dispatch(fetchGroupRelationships(statusesFromGroups.map((status: any) => status.group?.id)));
dispatch(expandTimelineSuccess(
timelineId,
response.data,
getNextLink(response),
getPrevLink(response),
response.status === 206,
isLoadingRecent,
isLoadingMore,
));
done();
}).catch(error => {
dispatch(expandTimelineFail(timelineId, error, isLoadingMore));
@ -181,9 +208,26 @@ const expandTimeline = (timelineId: string, path: string, params: Record<string,
});
};
const expandHomeTimeline = ({ accountId, maxId }: Record<string, any> = {}, done = noOp) => {
const endpoint = accountId ? `/api/v1/accounts/${accountId}/statuses` : '/api/v1/timelines/home';
const params: any = { max_id: maxId };
interface ExpandHomeTimelineOpts {
accountId?: string
maxId?: string
url?: string
}
interface HomeTimelineParams {
max_id?: string
exclude_replies?: boolean
with_muted?: boolean
}
const expandHomeTimeline = ({ url, accountId, maxId }: ExpandHomeTimelineOpts = {}, done = noOp) => {
const endpoint = url || (accountId ? `/api/v1/accounts/${accountId}/statuses` : '/api/v1/timelines/home');
const params: HomeTimelineParams = {};
if (!url && maxId) {
params.max_id = maxId;
}
if (accountId) {
params.exclude_replies = true;
params.with_muted = true;
@ -192,38 +236,44 @@ const expandHomeTimeline = ({ accountId, maxId }: Record<string, any> = {}, done
return expandTimeline('home', endpoint, params, done);
};
const expandPublicTimeline = ({ maxId, onlyMedia }: Record<string, any> = {}, done = noOp) =>
expandTimeline(`public${onlyMedia ? ':media' : ''}`, '/api/v1/timelines/public', { max_id: maxId, only_media: !!onlyMedia }, done);
const expandPublicTimeline = ({ url, maxId, onlyMedia }: Record<string, any> = {}, done = noOp) =>
expandTimeline(`public${onlyMedia ? ':media' : ''}`, url || '/api/v1/timelines/public', url ? {} : { max_id: maxId, only_media: !!onlyMedia }, done);
const expandRemoteTimeline = (instance: string, { maxId, onlyMedia }: Record<string, any> = {}, done = noOp) =>
expandTimeline(`remote${onlyMedia ? ':media' : ''}:${instance}`, '/api/v1/timelines/public', { local: false, instance: instance, max_id: maxId, only_media: !!onlyMedia }, done);
const expandRemoteTimeline = (instance: string, { url, maxId, onlyMedia }: Record<string, any> = {}, done = noOp) =>
expandTimeline(`remote${onlyMedia ? ':media' : ''}:${instance}`, url || '/api/v1/timelines/public', url ? {} : { local: false, instance: instance, max_id: maxId, only_media: !!onlyMedia }, done);
const expandCommunityTimeline = ({ maxId, onlyMedia }: Record<string, any> = {}, done = noOp) =>
expandTimeline(`community${onlyMedia ? ':media' : ''}`, '/api/v1/timelines/public', { local: true, max_id: maxId, only_media: !!onlyMedia }, done);
const expandCommunityTimeline = ({ url, maxId, onlyMedia }: Record<string, any> = {}, done = noOp) =>
expandTimeline(`community${onlyMedia ? ':media' : ''}`, url || '/api/v1/timelines/public', url ? {} : { local: true, max_id: maxId, only_media: !!onlyMedia }, done);
const expandDirectTimeline = ({ maxId }: Record<string, any> = {}, done = noOp) =>
expandTimeline('direct', '/api/v1/timelines/direct', { max_id: maxId }, done);
const expandDirectTimeline = ({ url, maxId }: Record<string, any> = {}, done = noOp) =>
expandTimeline('direct', url || '/api/v1/timelines/direct', url ? {} : { max_id: maxId }, done);
const expandAccountTimeline = (accountId: string, { maxId, withReplies }: Record<string, any> = {}) =>
expandTimeline(`account:${accountId}${withReplies ? ':with_replies' : ''}`, `/api/v1/accounts/${accountId}/statuses`, { exclude_replies: !withReplies, max_id: maxId, with_muted: true });
const expandAccountTimeline = (accountId: string, { url, maxId, withReplies }: Record<string, any> = {}) =>
expandTimeline(`account:${accountId}${withReplies ? ':with_replies' : ''}`, url || `/api/v1/accounts/${accountId}/statuses`, url ? {} : { exclude_replies: !withReplies, max_id: maxId, with_muted: true });
const expandAccountFeaturedTimeline = (accountId: string) =>
expandTimeline(`account:${accountId}:pinned`, `/api/v1/accounts/${accountId}/statuses`, { pinned: true, with_muted: true });
const expandAccountMediaTimeline = (accountId: string | number, { maxId }: Record<string, any> = {}) =>
expandTimeline(`account:${accountId}:media`, `/api/v1/accounts/${accountId}/statuses`, { max_id: maxId, only_media: true, limit: 40, with_muted: true });
const expandAccountMediaTimeline = (accountId: string | number, { url, maxId }: Record<string, any> = {}) =>
expandTimeline(`account:${accountId}:media`, url || `/api/v1/accounts/${accountId}/statuses`, url ? {} : { max_id: maxId, only_media: true, limit: 40, with_muted: true });
const expandListTimeline = (id: string, { maxId }: Record<string, any> = {}, done = noOp) =>
expandTimeline(`list:${id}`, `/api/v1/timelines/list/${id}`, { max_id: maxId }, done);
const expandListTimeline = (id: string, { url, maxId }: Record<string, any> = {}, done = noOp) =>
expandTimeline(`list:${id}`, url || `/api/v1/timelines/list/${id}`, url ? {} : { max_id: maxId }, done);
const expandGroupTimeline = (id: string, { maxId }: Record<string, any> = {}, done = noOp) =>
expandTimeline(`group:${id}`, `/api/v1/timelines/group/${id}`, { max_id: maxId }, done);
const expandGroupFeaturedTimeline = (id: string) =>
expandTimeline(`group:${id}:pinned`, `/api/v1/timelines/group/${id}`, { pinned: true });
const expandGroupTimelineFromTag = (id: string, tagName: string, { maxId }: Record<string, any> = {}, done = noOp) =>
expandTimeline(`group:tags:${id}:${tagName}`, `/api/v1/timelines/group/${id}/tags/${tagName}`, { max_id: maxId }, done);
const expandGroupMediaTimeline = (id: string | number, { maxId }: Record<string, any> = {}) =>
expandTimeline(`group:${id}:media`, `/api/v1/timelines/group/${id}`, { max_id: maxId, only_media: true, limit: 40, with_muted: true });
const expandHashtagTimeline = (hashtag: string, { maxId, tags }: Record<string, any> = {}, done = noOp) => {
return expandTimeline(`hashtag:${hashtag}`, `/api/v1/timelines/tag/${hashtag}`, {
const expandHashtagTimeline = (hashtag: string, { url, maxId, tags }: Record<string, any> = {}, done = noOp) => {
return expandTimeline(`hashtag:${hashtag}`, url || `/api/v1/timelines/tag/${hashtag}`, url ? {} : {
max_id: maxId,
any: parseTags(tags, 'any'),
all: parseTags(tags, 'all'),
@ -237,11 +287,20 @@ const expandTimelineRequest = (timeline: string, isLoadingMore: boolean) => ({
skipLoading: !isLoadingMore,
});
const expandTimelineSuccess = (timeline: string, statuses: APIEntity[], next: string | null, partial: boolean, isLoadingRecent: boolean, isLoadingMore: boolean) => ({
const expandTimelineSuccess = (
timeline: string,
statuses: APIEntity[],
next: string | undefined,
prev: string | undefined,
partial: boolean,
isLoadingRecent: boolean,
isLoadingMore: boolean,
) => ({
type: TIMELINE_EXPAND_SUCCESS,
timeline,
statuses,
next,
prev,
partial,
isLoadingRecent,
skipLoading: !isLoadingMore,
@ -278,6 +337,9 @@ const clearFeedAccountId = () => (dispatch: AppDispatch, _getState: () => RootSt
dispatch({ type: TIMELINE_CLEAR_FEED_ACCOUNT_ID });
};
// TODO: other actions
type TimelineAction = TimelineDeleteAction;
export {
TIMELINE_UPDATE,
TIMELINE_DELETE,
@ -312,6 +374,8 @@ export {
expandAccountMediaTimeline,
expandListTimeline,
expandGroupTimeline,
expandGroupFeaturedTimeline,
expandGroupTimelineFromTag,
expandGroupMediaTimeline,
expandHashtagTimeline,
expandTimelineRequest,
@ -322,4 +386,5 @@ export {
scrollTopTimeline,
insertSuggestionsIntoTimeline,
clearFeedAccountId,
type TimelineAction,
};

Wyświetl plik

@ -31,14 +31,14 @@ const AGE: Challenge = 'age';
export type Challenge = 'age' | 'sms' | 'email'
type Challenges = {
email?: 0 | 1,
sms?: 0 | 1,
age?: 0 | 1,
email?: 0 | 1
sms?: 0 | 1
age?: 0 | 1
}
type Verification = {
token?: string,
challenges?: Challenges,
token?: string
challenges?: Challenges
challengeTypes?: Array<'age' | 'sms' | 'email'>
};

Wyświetl plik

@ -1,10 +1,10 @@
import { jest } from '@jest/globals';
import MockAdapter from 'axios-mock-adapter';
import LinkHeader from 'http-link-header';
import { vi } from 'vitest';
import type { AxiosInstance, AxiosResponse } from 'axios';
const api = jest.requireActual('../index') as Record<string, Function>;
const api = await vi.importActual('../index') as Record<string, Function>;
let mocks: Array<Function> = [];
export const __stub = (func: (mock: MockAdapter) => void) => mocks.push(func);
@ -23,7 +23,12 @@ export const getLinks = (response: AxiosResponse): LinkHeader => {
export const getNextLink = (response: AxiosResponse) => {
const nextLink = new LinkHeader(response.headers?.link);
return nextLink.refs.find((ref) => ref.uri)?.uri;
return nextLink.refs.find(link => link.rel === 'next')?.uri;
};
export const getPrevLink = (response: AxiosResponse) => {
const prevLink = new LinkHeader(response.headers?.link);
return prevLink.refs.find(link => link.rel === 'prev')?.uri;
};
export const baseClient = (...params: any[]) => {

Wyświetl plik

@ -0,0 +1,58 @@
import { useEffect, useMemo } from 'react';
import { useHistory } from 'react-router-dom';
import { Entities } from 'soapbox/entity-store/entities';
import { useEntity } from 'soapbox/entity-store/hooks';
import { useFeatures, useLoggedIn } from 'soapbox/hooks';
import { useApi } from 'soapbox/hooks/useApi';
import { type Account, accountSchema } from 'soapbox/schemas';
import { useRelationship } from './useRelationship';
interface UseAccountOpts {
withRelationship?: boolean
}
function useAccount(accountId?: string, opts: UseAccountOpts = {}) {
const api = useApi();
const history = useHistory();
const features = useFeatures();
const { me } = useLoggedIn();
const { withRelationship } = opts;
const { entity, isUnauthorized, ...result } = useEntity<Account>(
[Entities.ACCOUNTS, accountId!],
() => api.get(`/api/v1/accounts/${accountId}`),
{ schema: accountSchema, enabled: !!accountId },
);
const {
relationship,
isLoading: isRelationshipLoading,
} = useRelationship(accountId, { enabled: withRelationship });
const isBlocked = entity?.relationship?.blocked_by === true;
const isUnavailable = (me === entity?.id) ? false : (isBlocked && !features.blockersVisible);
const account = useMemo(
() => entity ? { ...entity, relationship } : undefined,
[entity, relationship],
);
useEffect(() => {
if (isUnauthorized) {
history.push('/login');
}
}, [isUnauthorized]);
return {
...result,
isLoading: result.isLoading,
isRelationshipLoading,
isUnauthorized,
isUnavailable,
account,
};
}
export { useAccount };

Wyświetl plik

@ -0,0 +1,70 @@
import { Entities } from 'soapbox/entity-store/entities';
import { useEntities } from 'soapbox/entity-store/hooks';
import { useApi } from 'soapbox/hooks';
import { Account, accountSchema } from 'soapbox/schemas';
import { useRelationships } from './useRelationships';
import type { EntityFn } from 'soapbox/entity-store/hooks/types';
interface useAccountListOpts {
enabled?: boolean
}
function useAccountList(listKey: string[], entityFn: EntityFn<void>, opts: useAccountListOpts = {}) {
const { entities, ...rest } = useEntities(
[Entities.ACCOUNTS, ...listKey],
entityFn,
{ schema: accountSchema, enabled: opts.enabled },
);
const { relationships } = useRelationships(
listKey,
entities.map(({ id }) => id),
);
const accounts: Account[] = entities.map((account) => ({
...account,
relationship: relationships[account.id],
}));
return { accounts, ...rest };
}
function useBlocks() {
const api = useApi();
return useAccountList(['blocks'], () => api.get('/api/v1/blocks'));
}
function useMutes() {
const api = useApi();
return useAccountList(['mutes'], () => api.get('/api/v1/mutes'));
}
function useFollowing(accountId: string | undefined) {
const api = useApi();
return useAccountList(
[accountId!, 'following'],
() => api.get(`/api/v1/accounts/${accountId}/following`),
{ enabled: !!accountId },
);
}
function useFollowers(accountId: string | undefined) {
const api = useApi();
return useAccountList(
[accountId!, 'followers'],
() => api.get(`/api/v1/accounts/${accountId}/followers`),
{ enabled: !!accountId },
);
}
export {
useAccountList,
useBlocks,
useMutes,
useFollowing,
useFollowers,
};

Wyświetl plik

@ -0,0 +1,54 @@
import { useEffect } from 'react';
import { useHistory } from 'react-router-dom';
import { Entities } from 'soapbox/entity-store/entities';
import { useEntityLookup } from 'soapbox/entity-store/hooks';
import { useFeatures, useLoggedIn } from 'soapbox/hooks';
import { useApi } from 'soapbox/hooks/useApi';
import { type Account, accountSchema } from 'soapbox/schemas';
import { useRelationship } from './useRelationship';
interface UseAccountLookupOpts {
withRelationship?: boolean
}
function useAccountLookup(acct: string | undefined, opts: UseAccountLookupOpts = {}) {
const api = useApi();
const features = useFeatures();
const history = useHistory();
const { me } = useLoggedIn();
const { withRelationship } = opts;
const { entity: account, isUnauthorized, ...result } = useEntityLookup<Account>(
Entities.ACCOUNTS,
(account) => account.acct.toLowerCase() === acct?.toLowerCase(),
() => api.get(`/api/v1/accounts/lookup?acct=${acct}`),
{ schema: accountSchema, enabled: !!acct },
);
const {
relationship,
isLoading: isRelationshipLoading,
} = useRelationship(account?.id, { enabled: withRelationship });
const isBlocked = account?.relationship?.blocked_by === true;
const isUnavailable = (me === account?.id) ? false : (isBlocked && !features.blockersVisible);
useEffect(() => {
if (isUnauthorized) {
history.push('/login');
}
}, [isUnauthorized]);
return {
...result,
isLoading: result.isLoading,
isRelationshipLoading,
isUnauthorized,
isUnavailable,
account: account ? { ...account, relationship } : undefined,
};
}
export { useAccountLookup };

Wyświetl plik

@ -0,0 +1,88 @@
import { importEntities } from 'soapbox/entity-store/actions';
import { Entities } from 'soapbox/entity-store/entities';
import { useTransaction } from 'soapbox/entity-store/hooks';
import { useAppDispatch, useLoggedIn } from 'soapbox/hooks';
import { useApi } from 'soapbox/hooks/useApi';
import { relationshipSchema } from 'soapbox/schemas';
interface FollowOpts {
reblogs?: boolean
notify?: boolean
languages?: string[]
}
function useFollow() {
const api = useApi();
const dispatch = useAppDispatch();
const { isLoggedIn } = useLoggedIn();
const { transaction } = useTransaction();
function followEffect(accountId: string) {
transaction({
Accounts: {
[accountId]: (account) => ({
...account,
followers_count: account.followers_count + 1,
}),
},
Relationships: {
[accountId]: (relationship) => ({
...relationship,
following: true,
}),
},
});
}
function unfollowEffect(accountId: string) {
transaction({
Accounts: {
[accountId]: (account) => ({
...account,
followers_count: Math.max(0, account.followers_count - 1),
}),
},
Relationships: {
[accountId]: (relationship) => ({
...relationship,
following: false,
}),
},
});
}
async function follow(accountId: string, options: FollowOpts = {}) {
if (!isLoggedIn) return;
followEffect(accountId);
try {
const response = await api.post(`/api/v1/accounts/${accountId}/follow`, options);
const result = relationshipSchema.safeParse(response.data);
if (result.success) {
dispatch(importEntities([result.data], Entities.RELATIONSHIPS));
}
} catch (e) {
unfollowEffect(accountId);
}
}
async function unfollow(accountId: string) {
if (!isLoggedIn) return;
unfollowEffect(accountId);
try {
await api.post(`/api/v1/accounts/${accountId}/unfollow`);
} catch (e) {
followEffect(accountId);
}
}
return {
follow,
unfollow,
followEffect,
unfollowEffect,
};
}
export { useFollow };

Wyświetl plik

@ -0,0 +1,18 @@
import { Entities } from 'soapbox/entity-store/entities';
import { useEntity } from 'soapbox/entity-store/hooks';
import { useApi } from 'soapbox/hooks/useApi';
import { type PatronUser, patronUserSchema } from 'soapbox/schemas';
function usePatronUser(url?: string) {
const api = useApi();
const { entity: patronUser, ...result } = useEntity<PatronUser>(
[Entities.PATRON_USERS, url || ''],
() => api.get(`/api/patron/v1/accounts/${encodeURIComponent(url!)}`),
{ schema: patronUserSchema, enabled: !!url },
);
return { patronUser, ...result };
}
export { usePatronUser };

Wyświetl plik

@ -0,0 +1,28 @@
import { z } from 'zod';
import { Entities } from 'soapbox/entity-store/entities';
import { useEntity } from 'soapbox/entity-store/hooks';
import { useApi } from 'soapbox/hooks';
import { type Relationship, relationshipSchema } from 'soapbox/schemas';
interface UseRelationshipOpts {
enabled?: boolean
}
function useRelationship(accountId: string | undefined, opts: UseRelationshipOpts = {}) {
const api = useApi();
const { enabled = false } = opts;
const { entity: relationship, ...result } = useEntity<Relationship>(
[Entities.RELATIONSHIPS, accountId!],
() => api.get(`/api/v1/accounts/relationships?id[]=${accountId}`),
{
enabled: enabled && !!accountId,
schema: z.array(relationshipSchema).nonempty().transform(arr => arr[0]),
},
);
return { relationship, ...result };
}
export { useRelationship };

Wyświetl plik

@ -0,0 +1,26 @@
import { Entities } from 'soapbox/entity-store/entities';
import { useBatchedEntities } from 'soapbox/entity-store/hooks/useBatchedEntities';
import { useLoggedIn } from 'soapbox/hooks';
import { useApi } from 'soapbox/hooks/useApi';
import { type Relationship, relationshipSchema } from 'soapbox/schemas';
function useRelationships(listKey: string[], ids: string[]) {
const api = useApi();
const { isLoggedIn } = useLoggedIn();
function fetchRelationships(ids: string[]) {
const q = ids.map((id) => `id[]=${id}`).join('&');
return api.get(`/api/v1/accounts/relationships?${q}`);
}
const { entityMap: relationships, ...result } = useBatchedEntities<Relationship>(
[Entities.RELATIONSHIPS, ...listKey],
ids,
fetchRelationships,
{ schema: relationshipSchema, enabled: isLoggedIn },
);
return { relationships, ...result };
}
export { useRelationships };

Wyświetl plik

@ -0,0 +1,2 @@
export { useSuggest } from './useSuggest';
export { useVerify } from './useVerify';

Wyświetl plik

@ -0,0 +1,58 @@
import { useTransaction } from 'soapbox/entity-store/hooks';
import { EntityCallbacks } from 'soapbox/entity-store/hooks/types';
import { useApi, useGetState } from 'soapbox/hooks';
import { accountIdsToAccts } from 'soapbox/selectors';
import type { Account } from 'soapbox/schemas';
function useSuggest() {
const api = useApi();
const getState = useGetState();
const { transaction } = useTransaction();
function suggestEffect(accountIds: string[], suggested: boolean) {
const updater = (account: Account): Account => {
if (account.pleroma) {
account.pleroma.is_suggested = suggested;
}
return account;
};
transaction({
Accounts: accountIds.reduce<Record<string, (account: Account) => Account>>(
(result, id) => ({ ...result, [id]: updater }),
{}),
});
}
async function suggest(accountIds: string[], callbacks?: EntityCallbacks<void, unknown>) {
const accts = accountIdsToAccts(getState(), accountIds);
suggestEffect(accountIds, true);
try {
await api.patch('/api/v1/pleroma/admin/users/suggest', { nicknames: accts });
callbacks?.onSuccess?.();
} catch (e) {
callbacks?.onError?.(e);
suggestEffect(accountIds, false);
}
}
async function unsuggest(accountIds: string[], callbacks?: EntityCallbacks<void, unknown>) {
const accts = accountIdsToAccts(getState(), accountIds);
suggestEffect(accountIds, false);
try {
await api.patch('/api/v1/pleroma/admin/users/unsuggest', { nicknames: accts });
callbacks?.onSuccess?.();
} catch (e) {
callbacks?.onError?.(e);
suggestEffect(accountIds, true);
}
}
return {
suggest,
unsuggest,
};
}
export { useSuggest };

Wyświetl plik

@ -0,0 +1,63 @@
import { useTransaction } from 'soapbox/entity-store/hooks';
import { EntityCallbacks } from 'soapbox/entity-store/hooks/types';
import { useApi, useGetState } from 'soapbox/hooks';
import { accountIdsToAccts } from 'soapbox/selectors';
import type { Account } from 'soapbox/schemas';
function useVerify() {
const api = useApi();
const getState = useGetState();
const { transaction } = useTransaction();
function verifyEffect(accountIds: string[], verified: boolean) {
const updater = (account: Account): Account => {
if (account.pleroma) {
const tags = account.pleroma.tags.filter((tag) => tag !== 'verified');
if (verified) {
tags.push('verified');
}
account.pleroma.tags = tags;
}
account.verified = verified;
return account;
};
transaction({
Accounts: accountIds.reduce<Record<string, (account: Account) => Account>>(
(result, id) => ({ ...result, [id]: updater }),
{}),
});
}
async function verify(accountIds: string[], callbacks?: EntityCallbacks<void, unknown>) {
const accts = accountIdsToAccts(getState(), accountIds);
verifyEffect(accountIds, true);
try {
await api.put('/api/v1/pleroma/admin/users/tag', { nicknames: accts, tags: ['verified'] });
callbacks?.onSuccess?.();
} catch (e) {
callbacks?.onError?.(e);
verifyEffect(accountIds, false);
}
}
async function unverify(accountIds: string[], callbacks?: EntityCallbacks<void, unknown>) {
const accts = accountIdsToAccts(getState(), accountIds);
verifyEffect(accountIds, false);
try {
await api.delete('/api/v1/pleroma/admin/users/tag', { data: { nicknames: accts, tags: ['verified'] } });
callbacks?.onSuccess?.();
} catch (e) {
callbacks?.onError?.(e);
verifyEffect(accountIds, true);
}
}
return {
verify,
unverify,
};
}
export { useVerify };

Wyświetl plik

@ -0,0 +1,41 @@
import { __stub } from 'soapbox/api';
import { buildGroup } from 'soapbox/jest/factory';
import { renderHook, waitFor } from 'soapbox/jest/test-helpers';
import { useGroup } from '../useGroup';
const group = buildGroup({ id: '1', display_name: 'soapbox' });
describe('useGroup hook', () => {
describe('with a successful request', () => {
beforeEach(() => {
__stub((mock) => {
mock.onGet(`/api/v1/groups/${group.id}`).reply(200, group);
});
});
it('is successful', async () => {
const { result } = renderHook(() => useGroup(group.id));
await waitFor(() => expect(result.current.isFetching).toBe(false));
expect(result.current.group?.id).toBe(group.id);
});
});
describe('with an unsuccessful query', () => {
beforeEach(() => {
__stub((mock) => {
mock.onGet(`/api/v1/groups/${group.id}`).networkError();
});
});
it('is has error state', async() => {
const { result } = renderHook(() => useGroup(group.id));
await waitFor(() => expect(result.current.isFetching).toBe(false));
expect(result.current.group).toBeUndefined();
});
});
});

Wyświetl plik

@ -0,0 +1,42 @@
import { __stub } from 'soapbox/api';
import { buildGroup } from 'soapbox/jest/factory';
import { renderHook, rootState, waitFor } from 'soapbox/jest/test-helpers';
import { useGroupLookup } from '../useGroupLookup';
const group = buildGroup({ id: '1', slug: 'soapbox' });
const state = rootState.setIn(['instance', 'version'], '3.4.1 (compatible; TruthSocial 1.0.0)');
describe('useGroupLookup hook', () => {
describe('with a successful request', () => {
beforeEach(() => {
__stub((mock) => {
mock.onGet(`/api/v1/groups/lookup?name=${group.slug}`).reply(200, group);
});
});
it('is successful', async () => {
const { result } = renderHook(() => useGroupLookup(group.slug), undefined, state);
await waitFor(() => expect(result.current.isFetching).toBe(false));
expect(result.current.entity?.id).toBe(group.id);
});
});
describe('with an unsuccessful query', () => {
beforeEach(() => {
__stub((mock) => {
mock.onGet(`/api/v1/groups/lookup?name=${group.slug}`).networkError();
});
});
it('is has error state', async() => {
const { result } = renderHook(() => useGroupLookup(group.slug), undefined, state);
await waitFor(() => expect(result.current.isFetching).toBe(false));
expect(result.current.entity).toBeUndefined();
});
});
});

Wyświetl plik

@ -0,0 +1,44 @@
import { __stub } from 'soapbox/api';
import { buildStatus } from 'soapbox/jest/factory';
import { renderHook, waitFor } from 'soapbox/jest/test-helpers';
import { useGroupMedia } from '../useGroupMedia';
const status = buildStatus();
const groupId = '1';
describe('useGroupMedia hook', () => {
describe('with a successful request', () => {
beforeEach(() => {
__stub((mock) => {
mock.onGet(`/api/v1/timelines/group/${groupId}?only_media=true`).reply(200, [status]);
});
});
it('is successful', async () => {
const { result } = renderHook(() => useGroupMedia(groupId));
await waitFor(() => expect(result.current.isFetching).toBe(false));
expect(result.current.entities.length).toBe(1);
expect(result.current.entities[0].id).toBe(status.id);
});
});
describe('with an unsuccessful query', () => {
beforeEach(() => {
__stub((mock) => {
mock.onGet(`/api/v1/timelines/group/${groupId}?only_media=true`).networkError();
});
});
it('is has error state', async() => {
const { result } = renderHook(() => useGroupMedia(groupId));
await waitFor(() => expect(result.current.isFetching).toBe(false));
expect(result.current.entities.length).toBe(0);
expect(result.current.isError).toBeTruthy();
});
});
});

Wyświetl plik

@ -0,0 +1,45 @@
import { __stub } from 'soapbox/api';
import { buildGroupMember } from 'soapbox/jest/factory';
import { renderHook, waitFor } from 'soapbox/jest/test-helpers';
import { GroupRoles } from 'soapbox/schemas/group-member';
import { useGroupMembers } from '../useGroupMembers';
const groupMember = buildGroupMember();
const groupId = '1';
describe('useGroupMembers hook', () => {
describe('with a successful request', () => {
beforeEach(() => {
__stub((mock) => {
mock.onGet(`/api/v1/groups/${groupId}/memberships?role=${GroupRoles.ADMIN}`).reply(200, [groupMember]);
});
});
it('is successful', async () => {
const { result } = renderHook(() => useGroupMembers(groupId, GroupRoles.ADMIN));
await waitFor(() => expect(result.current.isFetching).toBe(false));
expect(result.current.groupMembers.length).toBe(1);
expect(result.current.groupMembers[0].id).toBe(groupMember.id);
});
});
describe('with an unsuccessful query', () => {
beforeEach(() => {
__stub((mock) => {
mock.onGet(`/api/v1/groups/${groupId}/memberships?role=${GroupRoles.ADMIN}`).networkError();
});
});
it('is has error state', async() => {
const { result } = renderHook(() => useGroupMembers(groupId, GroupRoles.ADMIN));
await waitFor(() => expect(result.current.isFetching).toBe(false));
expect(result.current.groupMembers.length).toBe(0);
expect(result.current.isError).toBeTruthy();
});
});
});

Wyświetl plik

@ -0,0 +1,47 @@
import { __stub } from 'soapbox/api';
import { buildGroup } from 'soapbox/jest/factory';
import { renderHook, waitFor } from 'soapbox/jest/test-helpers';
import { normalizeInstance } from 'soapbox/normalizers';
import { useGroups } from '../useGroups';
const group = buildGroup({ id: '1', display_name: 'soapbox' });
const store = {
instance: normalizeInstance({
version: '3.4.1 (compatible; TruthSocial 1.0.0+unreleased)',
}),
};
describe('useGroups hook', () => {
describe('with a successful request', () => {
beforeEach(() => {
__stub((mock) => {
mock.onGet('/api/v1/groups').reply(200, [group]);
});
});
it('is successful', async () => {
const { result } = renderHook(useGroups, undefined, store);
await waitFor(() => expect(result.current.isFetching).toBe(false));
expect(result.current.groups).toHaveLength(1);
});
});
describe('with an unsuccessful query', () => {
beforeEach(() => {
__stub((mock) => {
mock.onGet('/api/v1/groups').networkError();
});
});
it('is has error state', async() => {
const { result } = renderHook(useGroups, undefined, store);
await waitFor(() => expect(result.current.isFetching).toBe(false));
expect(result.current.groups).toHaveLength(0);
});
});
});

Wyświetl plik

@ -0,0 +1,64 @@
import { __stub } from 'soapbox/api';
import { Entities } from 'soapbox/entity-store/entities';
import { buildAccount, buildGroup } from 'soapbox/jest/factory';
import { renderHook, waitFor } from 'soapbox/jest/test-helpers';
import { normalizeInstance } from 'soapbox/normalizers';
import { usePendingGroups } from '../usePendingGroups';
const id = '1';
const group = buildGroup({ id, display_name: 'soapbox' });
const store = {
instance: normalizeInstance({
version: '3.4.1 (compatible; TruthSocial 1.0.0+unreleased)',
}),
me: '1',
entities: {
[Entities.ACCOUNTS]: {
store: {
[id]: buildAccount({
id,
acct: 'tiger',
display_name: 'Tiger',
avatar: 'test.jpg',
verified: true,
}),
},
lists: {},
},
},
};
describe('usePendingGroups hook', () => {
describe('with a successful request', () => {
beforeEach(() => {
__stub((mock) => {
mock.onGet('/api/v1/groups').reply(200, [group]);
});
});
it('is successful', async () => {
const { result } = renderHook(usePendingGroups, undefined, store);
await waitFor(() => expect(result.current.isFetching).toBe(false));
expect(result.current.groups).toHaveLength(1);
});
});
describe('with an unsuccessful query', () => {
beforeEach(() => {
__stub((mock) => {
mock.onGet('/api/v1/groups').networkError();
});
});
it('is has error state', async() => {
const { result } = renderHook(usePendingGroups, undefined, store);
await waitFor(() => expect(result.current.isFetching).toBe(false));
expect(result.current.groups).toHaveLength(0);
});
});
});

Wyświetl plik

@ -0,0 +1,15 @@
import { Entities } from 'soapbox/entity-store/entities';
import { useEntityActions } from 'soapbox/entity-store/hooks';
import type { Account, Group, GroupMember } from 'soapbox/schemas';
function useBlockGroupMember(group: Group, account: Account) {
const { createEntity } = useEntityActions<GroupMember>(
[Entities.GROUP_MEMBERSHIPS, account.id],
{ post: `/api/v1/groups/${group?.id}/blocks` },
);
return createEntity;
}
export { useBlockGroupMember };

Wyświetl plik

@ -0,0 +1,22 @@
import { Entities } from 'soapbox/entity-store/entities';
import { useCreateEntity } from 'soapbox/entity-store/hooks';
import { useApi, useOwnAccount } from 'soapbox/hooks';
import type { Group } from 'soapbox/schemas';
function useCancelMembershipRequest(group: Group) {
const api = useApi();
const { account: me } = useOwnAccount();
const { createEntity, isSubmitting } = useCreateEntity(
[Entities.GROUP_RELATIONSHIPS],
() => api.post(`/api/v1/groups/${group.id}/membership_requests/${me?.id}/reject`),
);
return {
mutate: createEntity,
isSubmitting,
};
}
export { useCancelMembershipRequest };

Wyświetl plik

@ -0,0 +1,33 @@
import { Entities } from 'soapbox/entity-store/entities';
import { useCreateEntity } from 'soapbox/entity-store/hooks';
import { useApi } from 'soapbox/hooks/useApi';
import { groupSchema } from 'soapbox/schemas';
interface CreateGroupParams {
display_name?: string
note?: string
avatar?: File
header?: File
group_visibility?: 'members_only' | 'everyone'
discoverable?: boolean
tags?: string[]
}
function useCreateGroup() {
const api = useApi();
const { createEntity, ...rest } = useCreateEntity([Entities.GROUPS, 'search', ''], (params: CreateGroupParams) => {
return api.post('/api/v1/groups', params, {
headers: {
'Content-Type': 'multipart/form-data',
},
});
}, { schema: groupSchema });
return {
createGroup: createEntity,
...rest,
};
}
export { useCreateGroup, type CreateGroupParams };

Wyświetl plik

@ -0,0 +1,18 @@
import { Entities } from 'soapbox/entity-store/entities';
import { useEntityActions } from 'soapbox/entity-store/hooks';
import type { Group } from 'soapbox/schemas';
function useDeleteGroup() {
const { deleteEntity, isSubmitting } = useEntityActions<Group>(
[Entities.GROUPS],
{ delete: '/api/v1/groups/:id' },
);
return {
mutate: deleteEntity,
isSubmitting,
};
}
export { useDeleteGroup };

Wyświetl plik

@ -0,0 +1,20 @@
import { Entities } from 'soapbox/entity-store/entities';
import { useDeleteEntity } from 'soapbox/entity-store/hooks';
import { useApi } from 'soapbox/hooks';
import type { Group } from 'soapbox/schemas';
function useDeleteGroupStatus(group: Group, statusId: string) {
const api = useApi();
const { deleteEntity, isSubmitting } = useDeleteEntity(
Entities.STATUSES,
() => api.delete(`/api/v1/groups/${group.id}/statuses/${statusId}`),
);
return {
mutate: deleteEntity,
isSubmitting,
};
}
export { useDeleteGroupStatus };

Wyświetl plik

@ -0,0 +1,19 @@
import { z } from 'zod';
import { Entities } from 'soapbox/entity-store/entities';
import { useEntityActions } from 'soapbox/entity-store/hooks';
import { groupMemberSchema } from 'soapbox/schemas';
import type { Group, GroupMember } from 'soapbox/schemas';
function useDemoteGroupMember(group: Group, groupMember: GroupMember) {
const { createEntity } = useEntityActions<GroupMember>(
[Entities.GROUP_MEMBERSHIPS, groupMember.id],
{ post: `/api/v1/groups/${group.id}/demote` },
{ schema: z.array(groupMemberSchema).transform((arr) => arr[0]) },
);
return createEntity;
}
export { useDemoteGroupMember };

Wyświetl plik

@ -0,0 +1,39 @@
import { useEffect } from 'react';
import { useHistory } from 'react-router-dom';
import { Entities } from 'soapbox/entity-store/entities';
import { useEntity } from 'soapbox/entity-store/hooks';
import { useApi } from 'soapbox/hooks';
import { type Group, groupSchema } from 'soapbox/schemas';
import { useGroupRelationship } from './useGroupRelationship';
function useGroup(groupId: string, refetch = true) {
const api = useApi();
const history = useHistory();
const { entity: group, isUnauthorized, ...result } = useEntity<Group>(
[Entities.GROUPS, groupId],
() => api.get(`/api/v1/groups/${groupId}`),
{
schema: groupSchema,
refetch,
enabled: !!groupId,
},
);
const { groupRelationship: relationship } = useGroupRelationship(groupId);
useEffect(() => {
if (isUnauthorized) {
history.push('/login');
}
}, [isUnauthorized]);
return {
...result,
isUnauthorized,
group: group ? { ...group, relationship: relationship || null } : undefined,
};
}
export { useGroup };

Wyświetl plik

@ -0,0 +1,39 @@
import { useEffect } from 'react';
import { useHistory } from 'react-router-dom';
import { Entities } from 'soapbox/entity-store/entities';
import { useEntityLookup } from 'soapbox/entity-store/hooks';
import { useApi } from 'soapbox/hooks/useApi';
import { useFeatures } from 'soapbox/hooks/useFeatures';
import { groupSchema } from 'soapbox/schemas';
import { useGroupRelationship } from './useGroupRelationship';
function useGroupLookup(slug: string) {
const api = useApi();
const features = useFeatures();
const history = useHistory();
const { entity: group, isUnauthorized, ...result } = useEntityLookup(
Entities.GROUPS,
(group) => group.slug.toLowerCase() === slug.toLowerCase(),
() => api.get(`/api/v1/groups/lookup?name=${slug}`),
{ schema: groupSchema, enabled: features.groups && !!slug },
);
const { groupRelationship: relationship } = useGroupRelationship(group?.id);
useEffect(() => {
if (isUnauthorized) {
history.push('/login');
}
}, [isUnauthorized]);
return {
...result,
isUnauthorized,
entity: group ? { ...group, relationship: relationship || null } : undefined,
};
}
export { useGroupLookup };

Wyświetl plik

@ -0,0 +1,17 @@
import { Entities } from 'soapbox/entity-store/entities';
import { useEntities } from 'soapbox/entity-store/hooks';
import { useApi } from 'soapbox/hooks/useApi';
import { normalizeStatus } from 'soapbox/normalizers';
import { toSchema } from 'soapbox/utils/normalizers';
const statusSchema = toSchema(normalizeStatus);
function useGroupMedia(groupId: string) {
const api = useApi();
return useEntities([Entities.STATUSES, 'groupMedia', groupId], () => {
return api.get(`/api/v1/timelines/group/${groupId}?only_media=true`);
}, { schema: statusSchema });
}
export { useGroupMedia };

Wyświetl plik

@ -0,0 +1,23 @@
import { Entities } from 'soapbox/entity-store/entities';
import { useEntities } from 'soapbox/entity-store/hooks';
import { GroupMember, groupMemberSchema } from 'soapbox/schemas';
import { GroupRoles } from 'soapbox/schemas/group-member';
import { useApi } from '../../../hooks/useApi';
function useGroupMembers(groupId: string, role: GroupRoles) {
const api = useApi();
const { entities, ...result } = useEntities<GroupMember>(
[Entities.GROUP_MEMBERSHIPS, groupId, role],
() => api.get(`/api/v1/groups/${groupId}/memberships?role=${role}`),
{ schema: groupMemberSchema },
);
return {
...result,
groupMembers: entities,
};
}
export { useGroupMembers };

Wyświetl plik

@ -0,0 +1,47 @@
import { Entities } from 'soapbox/entity-store/entities';
import { useDismissEntity, useEntities } from 'soapbox/entity-store/hooks';
import { useApi } from 'soapbox/hooks/useApi';
import { accountSchema } from 'soapbox/schemas';
import { GroupRoles } from 'soapbox/schemas/group-member';
import { useGroupRelationship } from './useGroupRelationship';
import type { ExpandedEntitiesPath } from 'soapbox/entity-store/hooks/types';
function useGroupMembershipRequests(groupId: string) {
const api = useApi();
const path: ExpandedEntitiesPath = [Entities.ACCOUNTS, 'membership_requests', groupId];
const { groupRelationship: relationship } = useGroupRelationship(groupId);
const { entities, invalidate, fetchEntities, ...rest } = useEntities(
path,
() => api.get(`/api/v1/groups/${groupId}/membership_requests`),
{
schema: accountSchema,
enabled: relationship?.role === GroupRoles.OWNER || relationship?.role === GroupRoles.ADMIN,
},
);
const { dismissEntity: authorize } = useDismissEntity(path, async (accountId: string) => {
const response = await api.post(`/api/v1/groups/${groupId}/membership_requests/${accountId}/authorize`);
invalidate();
return response;
});
const { dismissEntity: reject } = useDismissEntity(path, async (accountId: string) => {
const response = await api.post(`/api/v1/groups/${groupId}/membership_requests/${accountId}/reject`);
invalidate();
return response;
});
return {
accounts: entities,
refetch: fetchEntities,
authorize,
reject,
...rest,
};
}
export { useGroupMembershipRequests };

Wyświetl plik

@ -0,0 +1,25 @@
import { Entities } from 'soapbox/entity-store/entities';
import { useEntities } from 'soapbox/entity-store/hooks';
import { useFeatures } from 'soapbox/hooks';
import { useApi } from 'soapbox/hooks/useApi';
import { groupSchema } from 'soapbox/schemas';
import type { Group } from 'soapbox/schemas';
function useGroupMutes() {
const api = useApi();
const features = useFeatures();
const { entities, ...result } = useEntities<Group>(
[Entities.GROUP_MUTES],
() => api.get('/api/v1/groups/mutes'),
{ schema: groupSchema, enabled: features.groupsMuting },
);
return {
...result,
mutes: entities,
};
}
export { useGroupMutes };

Wyświetl plik

@ -0,0 +1,26 @@
import { z } from 'zod';
import { Entities } from 'soapbox/entity-store/entities';
import { useEntity } from 'soapbox/entity-store/hooks';
import { useApi } from 'soapbox/hooks';
import { type GroupRelationship, groupRelationshipSchema } from 'soapbox/schemas';
function useGroupRelationship(groupId: string | undefined) {
const api = useApi();
const { entity: groupRelationship, ...result } = useEntity<GroupRelationship>(
[Entities.GROUP_RELATIONSHIPS, groupId!],
() => api.get(`/api/v1/groups/relationships?id[]=${groupId}`),
{
enabled: !!groupId,
schema: z.array(groupRelationshipSchema).nonempty().transform(arr => arr[0]),
},
);
return {
groupRelationship,
...result,
};
}
export { useGroupRelationship };

Wyświetl plik

@ -0,0 +1,25 @@
import { Entities } from 'soapbox/entity-store/entities';
import { useBatchedEntities } from 'soapbox/entity-store/hooks/useBatchedEntities';
import { useApi, useLoggedIn } from 'soapbox/hooks';
import { type GroupRelationship, groupRelationshipSchema } from 'soapbox/schemas';
function useGroupRelationships(listKey: string[], ids: string[]) {
const api = useApi();
const { isLoggedIn } = useLoggedIn();
function fetchGroupRelationships(ids: string[]) {
const q = ids.map((id) => `id[]=${id}`).join('&');
return api.get(`/api/v1/groups/relationships?${q}`);
}
const { entityMap: relationships, ...result } = useBatchedEntities<GroupRelationship>(
[Entities.RELATIONSHIPS, ...listKey],
ids,
fetchGroupRelationships,
{ schema: groupRelationshipSchema, enabled: isLoggedIn },
);
return { relationships, ...result };
}
export { useGroupRelationships };

Wyświetl plik

@ -0,0 +1,40 @@
import { Entities } from 'soapbox/entity-store/entities';
import { useEntities } from 'soapbox/entity-store/hooks';
import { useApi, useFeatures } from 'soapbox/hooks';
import { groupSchema } from 'soapbox/schemas';
import { useGroupRelationships } from './useGroupRelationships';
import type { Group } from 'soapbox/schemas';
function useGroupSearch(search: string) {
const api = useApi();
const features = useFeatures();
const { entities, ...result } = useEntities<Group>(
[Entities.GROUPS, 'discover', 'search', search],
() => api.get('/api/v1/groups/search', {
params: {
q: search,
},
}),
{ enabled: features.groupsDiscovery && !!search, schema: groupSchema },
);
const { relationships } = useGroupRelationships(
['discover', 'search', search],
entities.map(entity => entity.id),
);
const groups = entities.map((group) => ({
...group,
relationship: relationships[group.id] || null,
}));
return {
...result,
groups,
};
}
export { useGroupSearch };

Wyświetl plik

@ -0,0 +1,21 @@
import { Entities } from 'soapbox/entity-store/entities';
import { useEntity } from 'soapbox/entity-store/hooks';
import { useApi } from 'soapbox/hooks';
import { type GroupTag, groupTagSchema } from 'soapbox/schemas';
function useGroupTag(tagId: string) {
const api = useApi();
const { entity: tag, ...result } = useEntity<GroupTag>(
[Entities.GROUP_TAGS, tagId],
() => api.get(`/api/v1/tags/${tagId }`),
{ schema: groupTagSchema },
);
return {
...result,
tag,
};
}
export { useGroupTag };

Wyświetl plik

@ -0,0 +1,23 @@
import { Entities } from 'soapbox/entity-store/entities';
import { useEntities } from 'soapbox/entity-store/hooks';
import { useApi } from 'soapbox/hooks/useApi';
import { groupTagSchema } from 'soapbox/schemas';
import type { GroupTag } from 'soapbox/schemas';
function useGroupTags(groupId: string) {
const api = useApi();
const { entities, ...result } = useEntities<GroupTag>(
[Entities.GROUP_TAGS, groupId],
() => api.get(`/api/v1/truth/trends/groups/${groupId}/tags`),
{ schema: groupTagSchema },
);
return {
...result,
tags: entities,
};
}
export { useGroupTags };

Wyświetl plik

@ -0,0 +1,47 @@
import { useQuery } from '@tanstack/react-query';
import { useApi } from 'soapbox/hooks/useApi';
import { useFeatures } from 'soapbox/hooks/useFeatures';
type Validation = {
error: string
message: string
}
const ValidationKeys = {
validation: (name: string) => ['group', 'validation', name] as const,
};
function useGroupValidation(name: string = '') {
const api = useApi();
const features = useFeatures();
const getValidation = async() => {
const { data } = await api.get<Validation>('/api/v1/groups/validate', {
params: { name },
})
.catch((error) => {
if (error.response.status === 422) {
return { data: error.response.data };
}
throw error;
});
return data;
};
const queryInfo = useQuery<Validation>(ValidationKeys.validation(name), getValidation, {
enabled: features.groupsValidation && !!name,
});
return {
...queryInfo,
data: {
...queryInfo.data,
isValid: !queryInfo.data?.error ?? true,
},
};
}
export { useGroupValidation };

Wyświetl plik

@ -0,0 +1,34 @@
import { Entities } from 'soapbox/entity-store/entities';
import { useEntities } from 'soapbox/entity-store/hooks';
import { useApi } from 'soapbox/hooks';
import { useFeatures } from 'soapbox/hooks/useFeatures';
import { groupSchema, type Group } from 'soapbox/schemas/group';
import { useGroupRelationships } from './useGroupRelationships';
function useGroups(q: string = '') {
const api = useApi();
const features = useFeatures();
const { entities, ...result } = useEntities<Group>(
[Entities.GROUPS, 'search', q],
() => api.get('/api/v1/groups', { params: { q } }),
{ enabled: features.groups, schema: groupSchema },
);
const { relationships } = useGroupRelationships(
['search', q],
entities.map(entity => entity.id),
);
const groups = entities.map((group) => ({
...group,
relationship: relationships[group.id] || null,
}));
return {
...result,
groups,
};
}
export { useGroups };

Wyświetl plik

@ -0,0 +1,38 @@
import { Entities } from 'soapbox/entity-store/entities';
import { useEntities } from 'soapbox/entity-store/hooks';
import { useApi, useFeatures } from 'soapbox/hooks';
import { groupSchema } from 'soapbox/schemas';
import { useGroupRelationships } from './useGroupRelationships';
import type { Group } from 'soapbox/schemas';
function useGroupsFromTag(tagId: string) {
const api = useApi();
const features = useFeatures();
const { entities, ...result } = useEntities<Group>(
[Entities.GROUPS, 'tags', tagId],
() => api.get(`/api/v1/tags/${tagId}/groups`),
{
schema: groupSchema,
enabled: features.groupsDiscovery,
},
);
const { relationships } = useGroupRelationships(
['tags', tagId],
entities.map(entity => entity.id),
);
const groups = entities.map((group) => ({
...group,
relationship: relationships[group.id] || null,
}));
return {
...result,
groups,
};
}
export { useGroupsFromTag };

Wyświetl plik

@ -0,0 +1,25 @@
import { Entities } from 'soapbox/entity-store/entities';
import { useEntityActions } from 'soapbox/entity-store/hooks';
import { groupRelationshipSchema } from 'soapbox/schemas';
import { useGroups } from './useGroups';
import type { Group, GroupRelationship } from 'soapbox/schemas';
function useJoinGroup(group: Group) {
const { invalidate } = useGroups();
const { createEntity, isSubmitting } = useEntityActions<GroupRelationship>(
[Entities.GROUP_RELATIONSHIPS, group.id],
{ post: `/api/v1/groups/${group.id}/join` },
{ schema: groupRelationshipSchema },
);
return {
mutate: createEntity,
isSubmitting,
invalidate,
};
}
export { useJoinGroup };

Wyświetl plik

@ -0,0 +1,25 @@
import { Entities } from 'soapbox/entity-store/entities';
import { useEntityActions } from 'soapbox/entity-store/hooks';
import { groupRelationshipSchema } from 'soapbox/schemas';
import { useGroups } from './useGroups';
import type { Group, GroupRelationship } from 'soapbox/schemas';
function useLeaveGroup(group: Group) {
const { invalidate } = useGroups();
const { createEntity, isSubmitting } = useEntityActions<GroupRelationship>(
[Entities.GROUP_RELATIONSHIPS, group.id],
{ post: `/api/v1/groups/${group.id}/leave` },
{ schema: groupRelationshipSchema },
);
return {
mutate: createEntity,
isSubmitting,
invalidate,
};
}
export { useLeaveGroup };

Wyświetl plik

@ -0,0 +1,18 @@
import { Entities } from 'soapbox/entity-store/entities';
import { useEntityActions } from 'soapbox/entity-store/hooks';
import { type Group, groupRelationshipSchema } from 'soapbox/schemas';
function useMuteGroup(group?: Group) {
const { createEntity, isSubmitting } = useEntityActions(
[Entities.GROUP_RELATIONSHIPS, group?.id as string],
{ post: `/api/v1/groups/${group?.id}/mute` },
{ schema: groupRelationshipSchema },
);
return {
mutate: createEntity,
isSubmitting,
};
}
export { useMuteGroup };

Wyświetl plik

@ -0,0 +1,30 @@
import { Entities } from 'soapbox/entity-store/entities';
import { useEntities } from 'soapbox/entity-store/hooks';
import { useApi, useFeatures, useOwnAccount } from 'soapbox/hooks';
import { Group, groupSchema } from 'soapbox/schemas';
function usePendingGroups() {
const api = useApi();
const { account } = useOwnAccount();
const features = useFeatures();
const { entities, ...result } = useEntities<Group>(
[Entities.GROUPS, account?.id!, 'pending'],
() => api.get('/api/v1/groups', {
params: {
pending: true,
},
}),
{
schema: groupSchema,
enabled: !!account && features.groupsPending,
},
);
return {
...result,
groups: entities,
};
}
export { usePendingGroups };

Wyświetl plik

@ -0,0 +1,36 @@
import { Entities } from 'soapbox/entity-store/entities';
import { useEntities } from 'soapbox/entity-store/hooks';
import { Group, groupSchema } from 'soapbox/schemas';
import { useApi } from '../../../hooks/useApi';
import { useFeatures } from '../../../hooks/useFeatures';
import { useGroupRelationships } from './useGroupRelationships';
function usePopularGroups() {
const api = useApi();
const features = useFeatures();
const { entities, ...result } = useEntities<Group>(
[Entities.GROUPS, 'popular'],
() => api.get('/api/v1/truth/trends/groups'),
{
schema: groupSchema,
enabled: features.groupsDiscovery,
},
);
const { relationships } = useGroupRelationships(['popular'], entities.map(entity => entity.id));
const groups = entities.map((group) => ({
...group,
relationship: relationships[group.id] || null,
}));
return {
...result,
groups,
};
}
export { usePopularGroups };

Wyświetl plik

@ -0,0 +1,25 @@
import { Entities } from 'soapbox/entity-store/entities';
import { useEntities } from 'soapbox/entity-store/hooks';
import { useApi, useFeatures } from 'soapbox/hooks';
import { type GroupTag, groupTagSchema } from 'soapbox/schemas';
function usePopularTags() {
const api = useApi();
const features = useFeatures();
const { entities, ...result } = useEntities<GroupTag>(
[Entities.GROUP_TAGS],
() => api.get('/api/v1/groups/tags'),
{
schema: groupTagSchema,
enabled: features.groupsDiscovery,
},
);
return {
...result,
tags: entities,
};
}
export { usePopularTags };

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