Porównaj commity

...

1793 Commity

Autor SHA1 Wiadomość Data
miklobit 7dc1cca40c Merge remote-tracking branch 'upstream/develop' into develop 2023-03-31 22:02:56 +02: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
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
miklobit eb188b0dfa Add custom logo 2023-02-18 15:06:29 +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
Alex Gleason c108c8cfbd Merge branch 'release-v3.2' into 'develop'
Bump version to v3.2.0

See merge request soapbox-pub/soapbox!2295
2023-02-15 18:58:18 +00:00
Alex Gleason e3307193e7
Bump version to v3.2.0 2023-02-15 12:57:36 -06:00
Alex Gleason 67bf9a7b20 Merge branch 'picker-mobile' into 'develop'
EmojiSelector: ensure the full picker fits on the screen on mobile

See merge request soapbox-pub/soapbox!2291
2023-02-15 18:48:08 +00:00
Alex Gleason 5f55e71fc0 Merge branch 'bump-sentry' into 'develop'
Bump Sentry versions

See merge request soapbox-pub/soapbox!2279
2023-02-15 18:47:43 +00:00
Alex Gleason 919b545e82 Merge branch 'fixes-1371' into 'develop'
DropdownMenu: close only if open in Redux

Closes #1371

See merge request soapbox-pub/soapbox!2294
2023-02-15 18:47:04 +00:00
Alex Gleason d92a4fd239
DropdownMenu: close only if open in Redux 2023-02-15 12:18:00 -06:00
marcin mikołajczak dec2cc69e8 Merge branch 'quoted-status-card' into 'develop'
Don't display card for quoted posts

See merge request soapbox-pub/soapbox!2281
2023-02-15 16:53:05 +00:00
marcin mikołajczak 2cfd402bec Merge branch 'admin-announcements' into 'develop'
Dashboard: Allow to create announcements

See merge request soapbox-pub/soapbox!2276
2023-02-14 23:05:07 +00:00
marcin mikołajczak a4681fddf8 Announcements: Feature-gate link
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-14 23:35:04 +01:00
marcin mikołajczak 45cf156a79 Add link to announcements
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-14 23:34:27 +01:00
Alex Gleason 1c46820d03 Merge branch 'i-1329-2' into 'develop'
hovering reportee shows reportee card, not reporter's

Closes #1329

See merge request soapbox-pub/soapbox!2292
2023-02-14 22:10:24 +00:00
marcin mikołajczak a85bf8d284 Merge branch 'cleanup' into 'develop'
Remove unused styles

See merge request soapbox-pub/soapbox!2289
2023-02-14 21:28:37 +00:00
tassoman 4a205fddc1 hovering reportee shows reportee card, not reporter's 2023-02-14 22:22:57 +01:00
Alex Gleason 0e7136ec04
EmojiSelector: ensure the full picker fits on the screen on mobile 2023-02-14 15:20:23 -06:00
Alex Gleason 23acbc115c Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2272
2023-02-14 21:08:43 +00:00
HiSubway 8437ef4f4b
Translated using Weblate (Japanese)
Currently translated at 84.2% (1217 of 1445 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ja/
2023-02-14 21:50:56 +01:00
HiSubway 25d65a0524
Translated using Weblate (Japanese)
Currently translated at 83.8% (1212 of 1445 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ja/
2023-02-14 21:50:56 +01:00
HiSubway cdeb5c12fa
Translated using Weblate (Japanese)
Currently translated at 82.9% (1199 of 1445 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ja/
2023-02-14 21:50:56 +01:00
HiSubway 73948374c4
Translated using Weblate (Japanese)
Currently translated at 82.8% (1197 of 1445 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ja/
2023-02-14 21:50:56 +01:00
HiSubway d959136f36
Translated using Weblate (Japanese)
Currently translated at 82.6% (1195 of 1445 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ja/
2023-02-14 21:50:56 +01:00
HiSubway 0ac5eda63e
Translated using Weblate (Japanese)
Currently translated at 82.6% (1194 of 1445 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ja/
2023-02-14 21:50:55 +01:00
Tassoman 9d0b034c0f
Translated using Weblate (Italian)
Currently translated at 100.0% (1445 of 1445 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/it/
2023-02-14 21:50:55 +01:00
Tassoman e8e4d4d5bc
Translated using Weblate (Italian)
Currently translated at 100.0% (1445 of 1445 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/it/
2023-02-14 21:50:55 +01:00
Hosted Weblate f5b60f25b5
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-02-14 21:50:55 +01:00
Hosted Weblate c1858f32f0
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-02-14 21:50:55 +01:00
Ahmad Dakhlallah bee84db236
Translated using Weblate (Arabic)
Currently translated at 89.1% (1290 of 1447 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ar/
2023-02-14 21:50:55 +01:00
Chewbacca 5eea84c5fb Merge branch 'prevent-excess-redux-actions' into 'develop'
Prevent unnecessary calls to redux action

See merge request soapbox-pub/soapbox!2290
2023-02-14 20:50:44 +00:00
Alex Gleason ed8f48816e Merge branch 'i-1244' into 'develop'
verified badge on profile's header

Closes #1244

See merge request soapbox-pub/soapbox!2212
2023-02-14 20:28:16 +00:00
Tassoman 5828e239b1 verified badge on profile's header 2023-02-14 20:28:16 +00:00
Alex Gleason 78328a0ce2 Merge branch 'gate-chat-reactions' into 'develop'
Fix chatEmojiReactions feature gating

See merge request soapbox-pub/soapbox!2286
2023-02-14 20:21:53 +00:00
Alex Gleason 63ca831d16 Merge branch 'chats-scrollbars' into 'develop'
Fix chat overflow-x

See merge request soapbox-pub/soapbox!2285
2023-02-14 20:21:40 +00:00
Alex Gleason 6fc8b181e6 Merge branch 'status-list-null' into 'develop'
StatusList: don't push null item to Virtuoso (LoadGap)

See merge request soapbox-pub/soapbox!2283
2023-02-14 20:21:21 +00:00
Alex Gleason 2a50a6c26f Merge branch 'sentry-localforage' into 'develop'
Sentry: filter out localForage "No storage found" error

See merge request soapbox-pub/soapbox!2282
2023-02-14 20:21:03 +00:00
Chewbacca f3469cf972 Prevent unnecessary calls to redux action 2023-02-14 15:04:26 -05:00
marcin mikołajczak 4a183e3ba6 Remove unused styles
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-14 20:56:12 +01:00
Chewbacca 225df82be8 Merge branch 'use-floating-ui-middleware' into 'develop'
Use flip and arrow middleware

See merge request soapbox-pub/soapbox!2288
2023-02-14 19:53:54 +00:00
marcin mikołajczak 75fc756bd1 Merge branch 'prefer-clsx' into 'develop'
Use clsx instead of template strings

See merge request soapbox-pub/soapbox!2287
2023-02-14 19:25:16 +00:00
Chewbacca 5b7c6793e6 Remove z-index 2023-02-14 14:01:11 -05:00
Chewbacca ce2e7f3785 Use flip and arrow middleware 2023-02-14 13:58:10 -05:00
Chewbacca 9b74f9264d Merge branch 'fix-pointer-events-bug' into 'develop'
Close dropdown-menu when component unmounts

See merge request soapbox-pub/soapbox!2284
2023-02-14 18:47:48 +00:00
Alex Gleason f271553213
Fix type of chat_message.emoji_reactions, fix tests with +unreleased 2023-02-14 12:36:15 -06:00
Alex Gleason 2a131a8407
Add "unreleased" build to features for tests 2023-02-14 12:35:27 -06:00
Chewbacca f068d6280d prevent scrolling when focused 2023-02-14 13:28:11 -05:00
marcin mikołajczak 3aba4218c5 Use clsx instead of template strings
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-14 19:00:43 +01:00
Alex Gleason d273947f70
Fix chatEmojiReactions feature gating 2023-02-14 11:41:27 -06:00
Alex Gleason 0aeeeb1dc4
Performance: hide EmojiSelector until portaled 2023-02-14 11:27:32 -06:00
Alex Gleason ec2235011f
ChatMessageReactionWrapper: put EmojiSelector in a portal to avoid overflow-x issues 2023-02-14 11:27:28 -06:00
Chewbacca d19f8a267a Close dropdown-menu when component unmounts 2023-02-14 12:18:26 -05:00
Alex Gleason 41b4a229b6
StatusList: don't push null item to Virtuoso (LoadGap) 2023-02-14 10:44:00 -06:00
Alex Gleason 55f99980e6
Sentry: filter out localForage "No storage found" error 2023-02-14 10:30:14 -06:00
Alex Gleason 783a79d306 Merge branch 'multiple-attachments' into 'develop'
Chats: allow uploading multiple attachments

See merge request soapbox-pub/soapbox!2268
2023-02-14 15:54:31 +00:00
Alex Gleason 261d900b51 Merge branch 'fix-dropdown' into 'develop'
Fix Profile Dropdown

See merge request soapbox-pub/soapbox!2261
2023-02-14 15:27:51 +00:00
Alex Gleason 14efff51ff
Merge remote-tracking branch 'origin/develop' into multiple-attachments 2023-02-14 09:24:12 -06:00
marcin mikołajczak 9958b66409 Don't display card for quoted posts
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-14 14:57:39 +01:00
Chewbacca 66f78144ea Bump Sentry versions 2023-02-14 07:39:26 -05:00
Alex Gleason 4ce28750c2 Merge branch 'fix-test' into 'develop'
ChatMessage: remove testid from emoji button resulting in failing test

See merge request soapbox-pub/soapbox!2280
2023-02-13 20:47:37 +00:00
Alex Gleason 04ae0f2ee4
ChatMessage: remove testid from emoji button resulting in failing test 2023-02-13 14:46:15 -06:00
Alex Gleason 01952c8fad Merge branch 'bugfixes' into 'develop'
Fix pipeline, fix emoji selector position

See merge request soapbox-pub/soapbox!2278
2023-02-13 20:28:39 +00:00
Alex Gleason 45657c7a2a
EmojiSelector: pass offset as a prop 2023-02-13 13:17:05 -06:00
Alex Gleason ae606a1db0
StatusReactionWrapper: switch to our Portal component 2023-02-13 13:16:57 -06:00
Chewbacca 0b9fe2cfca Merge branch 'hoverable-menu' into 'develop'
Add new hoverable menu for Chat Messages (and rebuild DropdownMenu component with Popper)

See merge request soapbox-pub/soapbox!2274
2023-02-13 17:32:02 +00:00
Chewbacca 8290b54dd5 Fix commented out code 2023-02-13 08:01:47 -05:00
Alex Gleason 998ff44e80 Merge branch 'react-any-emoji' into 'develop'
React with any emoji

See merge request soapbox-pub/soapbox!2271
2023-02-13 02:48:01 +00:00
Alex Gleason cc2eafdfac
Merge remote-tracking branch 'origin/develop' into react-any-emoji 2023-02-12 20:30:33 -06:00
Alex Gleason f9cb9d468b
EmojiSelector: improve style of 3-dots icon 2023-02-12 20:29:33 -06:00
Alex Gleason 16179a6371
Transpile emoji-mart for jest 2023-02-12 20:23:29 -06:00
marcin mikołajczak 195ec1b67d Merge branch 'chat-resize-reset' into 'develop'
Chats: reset chat message field height after sending a message

See merge request soapbox-pub/soapbox!2277
2023-02-12 22:14:03 +00:00
marcin mikołajczak 35bf20507d Merge branch 'cleanup' into 'develop'
Fixes, styles improvements, cleanup, enforce classes order for classNames

See merge request soapbox-pub/soapbox!2258
2023-02-12 21:59:53 +00:00
marcin mikołajczak 00657c201f Sort en.json keys
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-12 22:29:20 +01:00
marcin mikołajczak 4936c3ed38 Merge remote-tracking branch 'soapbox/develop' into cleanup
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-12 22:26:55 +01:00
marcin mikołajczak 7759f64fed Chats: reset chat message field height after sending a message
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-12 22:23:44 +01:00
marcin mikołajczak 8f79ef2bcd Merge branch 'filters' into 'develop'
Fix filters, restyle filters page

See merge request soapbox-pub/soapbox!2262
2023-02-12 21:08:15 +00:00
marcin mikołajczak 0872a17542 Fix en.json
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-12 22:06:37 +01:00
marcin mikołajczak 9dc7c92c5a add sort-keys rule to modal-root.tsx
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-12 18:07:30 +01:00
marcin mikołajczak 8e3a879841 Update en.json
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-12 18:06:36 +01:00
marcin mikołajczak 9ced32405e Update CHANGELOG.MD
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-12 17:59:53 +01:00
marcin mikołajczak 64c4847f9d Dashboard: Allow to create announcements
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-12 17:54:13 +01:00
Chewbacca f46086d52a Cleanup a few things 2023-02-10 14:43:41 -05:00
Chewbacca 04e5e06d26 Make sure DOM is ready for Portal 2023-02-10 13:49:59 -05:00
Chewbacca 21a525ba8d Fix dropdown-menu reducer test 2023-02-10 13:39:16 -05:00
Chewbacca 59ce093b31 Replace @reach/portal with custom Portal 2023-02-10 13:23:48 -05:00
Chewbacca 60d7ff8395 Re-build dropdown-menu using FloatingUI 2023-02-10 13:17:39 -05:00
Chewbacca 380d2b763f Merge branch 'improve-reactions' into 'develop'
Improve Emoji Reactions and add support for Chat Reactions

See merge request soapbox-pub/soapbox!2267
2023-02-09 21:37:57 +00:00
Alex Gleason 1dda90da10 Merge branch 'emoji-compat' into 'develop'
Invert features.emojiReactsRGI

See merge request soapbox-pub/soapbox!2266
2023-02-09 20:44:29 +00:00
Chewbacca 48eb42687a Disable chatEmojiReacts 2023-02-09 13:16:06 -05:00
Chewbacca 2def1d0170 Discard changes to 'emojiReactsRGI' feature 2023-02-09 13:13:01 -05:00
Chewbacca 9d08467b07 Update Changelog 2023-02-09 13:02:03 -05:00
Chewbacca 17684571af Update hoverable menu on Chat Messages 2023-02-09 12:42:00 -05:00
Alex Gleason 8bdebd229d Merge branch 'display-all-reactions' into 'develop'
Display all emoji reactions

See merge request soapbox-pub/soapbox!2270
2023-02-09 14:00:38 +00:00
Alex Gleason 78c52956ed
Merge remote-tracking branch 'origin/develop' into react-any-emoji 2023-02-08 21:06:15 -06:00
Alex Gleason 1461113f7f Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2269
2023-02-09 03:04:22 +00:00
Alex Gleason c95261fcf1
Display all emoji reactions 2023-02-08 21:00:17 -06:00
Alex Gleason cf487b901d
Display all emoji reactions 2023-02-08 20:59:26 -06:00
Tassoman 4ac6e66bbb
Translated using Weblate (Italian)
Currently translated at 100.0% (1447 of 1447 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/it/
2023-02-09 03:40:19 +01:00
Alex Gleason e2e3af4a8b
Don't allow reacting with any emoji to a chat for now 2023-02-08 20:28:44 -06:00
Alex Gleason 6f15b5f42f
StatusReactionWrapper: put the picker in a portal 2023-02-08 20:26:37 -06:00
Alex Gleason 06ea520e89
EmojiSelector: allow reacting from full picker 2023-02-08 20:23:26 -06:00
Alex Gleason aab6ee34c2
EmojiSelector: render full picker 2023-02-08 19:20:17 -06:00
marcin mikołajczak 0ae3cd853e Update CHANGELOG.md
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-08 23:45:03 +01:00
marcin mikołajczak 47403872fa Merge remote-tracking branch 'soapbox/develop' into filters 2023-02-08 23:40:40 +01:00
Alex Gleason f730897323
Fix instance tests 2023-02-08 14:41:10 -06:00
Alex Gleason 772c53a6ac Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2260
2023-02-08 19:46:26 +00:00
gallegonovato 861509baa5
Translated using Weblate (Spanish)
Currently translated at 100.0% (1447 of 1447 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/es/
2023-02-08 20:39:21 +01:00
Alex Gleason 50457d3b8d
Chats: disable adding media (and submitting) while media is uploading 2023-02-08 13:07:54 -06:00
Chewbacca 3ca491c03f classNames -> clsx 2023-02-08 14:06:41 -05:00
Alex Gleason 6eadaf2942
CHats: fix deleting a specific attachment 2023-02-08 13:02:48 -06:00
Alex Gleason 64f17ef013
ChatTextarea: add gaps between uploads, put pending upload at end of list 2023-02-08 12:53:07 -06:00
Alex Gleason 072e058764
ChatUploadPreview: support gif attachments 2023-02-08 12:50:18 -06:00
Alex Gleason ef5001d38b
Chats: support multiple attachments 2023-02-08 12:30:20 -06:00
Chewbacca e255bfac3d Improve Emoji Reactions and add support for Chat Reactions 2023-02-08 12:58:01 -05:00
Alex Gleason 81bb8b933a
Invert features.emojiReactsRGI 2023-02-08 11:57:23 -06:00
Poesty Li 7373a650f1
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1447 of 1447 strings)

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

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/es/
2023-02-07 23:53:30 +01:00
Poesty Li 8404be2745
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1446 of 1446 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-02-07 23:53:30 +01:00
Poesty Li ad8ad9cae8
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1443 of 1443 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-02-07 23:53:30 +01:00
forenta 4a3877d442
Translated using Weblate (German)
Currently translated at 100.0% (1443 of 1443 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/de/
2023-02-07 23:53:30 +01:00
marcin mikołajczak dbf2e53b93 Merge branch 'rss-button' into 'develop'
Add RSS link to account menu

See merge request soapbox-pub/soapbox!1881
2023-02-07 22:53:23 +00:00
marcin mikołajczak b19de058a1 Update changelog
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-07 22:24:58 +01:00
marcin mikołajczak 07b7d1ec2a Merge remote-tracking branch 'soapbox/develop' into rss-button 2023-02-07 22:24:15 +01:00
Chewbacca df19b4e4a3 Merge branch 'add-intl-to-storybook' into 'develop'
Add support for react-intl for Storybook

See merge request soapbox-pub/soapbox!2264
2023-02-07 21:16:20 +00:00
Chewbacca 674ff4aa65 Add support for react-intl for Storybook 2023-02-07 14:23:28 -05:00
Alex Gleason f68ce9c47b
Account: rip out calculations on display name, truncate with CSS 2023-02-07 12:03:12 -06:00
Alex Gleason 0631657278
ProfileDropdown: enforce a max width 2023-02-07 12:02:37 -06:00
Chewbacca 800b9e7742 Merge branch 'improve-tabs' into 'develop'
Update default border color for Tabs

See merge request soapbox-pub/soapbox!2263
2023-02-07 17:34:07 +00:00
Chewbacca 0cc4188cad Update default border color for Tabs 2023-02-07 12:00:14 -05:00
marcin mikołajczak 1bbbaf8f4b Update en.json
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-07 17:43:37 +01:00
marcin mikołajczak 49a7d40efb Fix filters, restyle filters page
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-07 15:38:31 +01:00
marcin mikołajczak 71a2e679a0 Update .eslintrc.cjs
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-07 09:42:08 +01:00
Alex Gleason 9ac2764bfa
CHANGELOG: profile dropdown 2023-02-06 17:19:12 -06:00
Alex Gleason dc597ac765
Add useClickOutside hook for Floating UI elements 2023-02-06 17:17:12 -06:00
Alex Gleason ec7f9b9950
ProfileDropdown: fix hover styles for menu items with `action` 2023-02-06 17:00:25 -06:00
Alex Gleason 53a930c75c
ProfileDropdown: dismiss when clicked outside 2023-02-06 16:53:56 -06:00
marcin mikołajczak bfe1401a34 Fix imports
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-06 23:48:44 +01:00
Alex Gleason 7f6b19aa4a
ProfileDropdown: refactor with Floating UI 2023-02-06 16:33:08 -06:00
Alex Gleason aa8f84d352
Menu: move <hr> styles to component 2023-02-06 16:15:00 -06:00
Alex Gleason f6f3973eac
Account: let avatar and display name be truncated 2023-02-06 16:09:59 -06:00
Alex Gleason a433d22ba3
Account: don't calculate max-width unnecessarily 2023-02-06 16:09:25 -06:00
Alex Gleason ab8d162f03
Account: useLayoutEffect, refactor function calls, fix types, prevent negative maxWidth 2023-02-06 15:53:58 -06:00
Alex Gleason cb74b0a37c
useOnScreen: memoize IntersectionObserver, fix types 2023-02-06 15:41:09 -06:00
Alex Gleason d44be7fbf8 Merge branch 'chat-composer' into 'develop'
Chats: move chat attachments into composer

See merge request soapbox-pub/soapbox!2229
2023-02-06 21:05:42 +00:00
marcin mikołajczak d62290f020 Merge branch 'events' into 'develop'
Add NewEventPanel to events list page

See merge request soapbox-pub/soapbox!2255
2023-02-06 20:53:49 +00:00
Alex Gleason e3f168f050
Merge remote-tracking branch 'origin/develop' into chat-composer 2023-02-06 14:25:37 -06:00
marcin mikołajczak 227f28d013 update eslint config
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-06 20:50:05 +01:00
Alex Gleason 76c76688e9 Merge branch 'renovate/react-sticky-box-2.x' into 'develop'
Update dependency react-sticky-box to v2

See merge request soapbox-pub/soapbox!2257
2023-02-06 19:38:33 +00:00
marcin mikołajczak 4721452986 Merge remote-tracking branch 'soapbox/develop' into cleanup
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-06 20:31:20 +01:00
marcin mikołajczak c56728b722 classNames() ==> clsx()
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-06 20:28:18 +01:00
marcin mikołajczak 75076abeac more styles cleanup
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-06 20:20:14 +01:00
Alex Gleason e5f90e4733 Merge branch 'clsx' into 'develop'
classNames() --> clsx(), lint

See merge request soapbox-pub/soapbox!2259
2023-02-06 19:15:43 +00:00
Chewbacca ea075c3799 Merge branch 'improve-logo-alignment' into 'develop'
Improve navbar alignment

See merge request soapbox-pub/soapbox!2253
2023-02-06 18:31:49 +00:00
Alex Gleason 785612691a
yarn lint:js --fix 2023-02-06 12:06:44 -06:00
Alex Gleason 701215d7bc
classNames() --> clsx() 2023-02-06 12:05:19 -06:00
Alex Gleason 89d55b1b70
ChatComposer: shrink "x" icon, fix pending upload jump 2023-02-06 11:30:36 -06:00
marcin mikołajczak adfbff858d remove comment
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-06 18:22:16 +01:00
Alex Gleason 6743439efd Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2254
2023-02-06 17:21:48 +00:00
marcin mikołajczak 49ba4c7a9d Fixes, styles improvements, cleanup, enforce classes order for classNames
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-06 18:18:49 +01:00
Soapbox Bot 8369648c4c Update dependency react-sticky-box to v2 2023-02-06 17:10:57 +00:00
Chewbacca 81d7d3a7a4 Merge branch 'develop' into 'improve-logo-alignment'
# Conflicts:
#   app/soapbox/features/ui/components/navbar.tsx
2023-02-06 15:38:14 +00:00
marcin mikołajczak 8c3f1eb412 Update en.json
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-06 14:48:09 +01:00
gallegonovato 9f97d575f5
Translated using Weblate (Spanish)
Currently translated at 100.0% (1443 of 1443 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/es/
2023-02-06 04:37:06 +01:00
Isabell De Inschnitzel 5e7745cbab
Translated using Weblate (German)
Currently translated at 94.7% (1367 of 1443 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/de/
2023-02-06 04:37:05 +01:00
marcin mikołajczak b529ec8a07 Add NewEventPanel to events list page
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-05 23:14:21 +01:00
Adrien Bourmault f2b042d473
Translated using Weblate (French)
Currently translated at 92.6% (1337 of 1443 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/fr/
2023-02-05 07:35:39 +01:00
Alex Gleason 8bd175e0e4 Merge branch 'storybook' into 'develop'
Add Storybook

See merge request soapbox-pub/soapbox!2252
2023-02-03 20:59:29 +00:00
Alex Gleason 25277b0b73
Merge remote-tracking branch 'origin/develop' into chat-composer 2023-02-03 12:03:45 -06:00
Alex Gleason 0ee8c8eba1 Merge branch 'tailwind-order' into 'develop'
Tailwind order

Closes #1349

See merge request soapbox-pub/soapbox!2244
2023-02-03 16:38:28 +00:00
Alex Gleason bb7caf93eb Merge branch 'renovate/node-18.x' into 'develop'
Update dependency node to v18.14.0

See merge request soapbox-pub/soapbox!2249
2023-02-03 16:38:15 +00:00
Chewbacca dadeb43c74 Improve navbar alignment 2023-02-03 11:01:25 -05:00
Alex Gleason d9d6708589
Storybook: improve Button story 2023-02-02 23:00:51 -06:00
Alex Gleason dd7b6af97d
Storybook: improve Button stories 2023-02-02 21:53:26 -06:00
Alex Gleason deb1920c03
Storybook: add hardcoded color variables, fix missing import 2023-02-02 21:24:58 -06:00
Alex Gleason f02a035911
Make Tailwind work with Storybook. Have it use our Button 2023-02-02 21:08:48 -06:00
Alex Gleason 398bfa879e
Lint storybook sample code 2023-02-02 20:23:47 -06:00
Alex Gleason b6df6149f4
Convert Storybook config to TypeScript 2023-02-02 20:21:13 -06:00
Alex Gleason accba58da1
Merge remote-tracking branch 'origin/develop' into storybook 2023-02-02 20:10:44 -06:00
Alex Gleason 716153fa31 Merge branch 'babel-deps' into 'develop'
Upgrade babel, simplify deps

See merge request soapbox-pub/soapbox!2251
2023-02-03 01:49:56 +00:00
Alex Gleason ae8dc786c2
Upgrade babel, simplify deps 2023-02-02 19:32:32 -06:00
Alex Gleason 1664f35150 Merge branch 'renovate/docker-23.x' into 'develop'
Update docker Docker tag to v23

See merge request soapbox-pub/soapbox!2250
2023-02-03 00:32:03 +00:00
Alex Gleason 6ea78e7d53
npx storybook init 2023-02-02 18:19:52 -06:00
Soapbox Bot 476a057781 Update docker Docker tag to v23 2023-02-03 00:12:36 +00:00
Alex Gleason 4c025bb2bc
Refactor ProgressBar 2023-02-02 18:03:22 -06:00
Alex Gleason e203e0d0d2
Chats: move uploading progress into the composer text box 2023-02-02 17:37:37 -06:00
Alex Gleason 6b1882d7a9
Merge remote-tracking branch 'origin/develop' into chat-composer 2023-02-02 15:19:54 -06:00
Alex Gleason b9474e61de
Test normalizeChatMessage 2023-02-02 15:17:06 -06:00
Alex Gleason 3df63e59d3
Submit `media_ids` when creating a message 2023-02-02 14:59:23 -06:00
Alex Gleason 1b8d118217
Chats: support displaying multiple attachments 2023-02-02 14:43:47 -06:00
Alex Gleason 7fe4b34e6f
Add type-aware UploadPreview component, fix ChatComposer bg on dark mode 2023-02-02 14:20:40 -06:00
Soapbox Bot ca018b8c19 Update dependency node to v18.14.0 2023-02-02 20:06:42 +00:00
Alex Gleason ec634f4fa1
ChatUpload: allow clicking upload to view in modal 2023-02-02 13:54:36 -06:00
Alex Gleason cb715f4f05
ChatUpload: ensure X icon is always white 2023-02-02 13:33:18 -06:00
Alex Gleason 747868edb3
ChatTextarea: fix focus border and ring styles 2023-02-02 13:27:38 -06:00
Alex Gleason fc1a547a2e Merge branch 'virtuoso-v4.0.8' into 'develop'
Upgrade Virtuoso to v4.0.8

See merge request soapbox-pub/soapbox!2248
2023-02-02 19:06:51 +00:00
Alex Gleason ea8561ca19
ChatUpload: add blurhash 2023-02-02 13:06:27 -06:00
Alex Gleason 9bec90106d
Upgrade Virtuoso to v4.0.8 2023-02-02 12:48:44 -06:00
Alex Gleason 6aa1d35120 Merge branch 'thread-muting' into 'develop'
Permit muting a thread as an option on any post in the thread

See merge request soapbox-pub/soapbox!2247
2023-02-02 18:23:27 +00:00
Alex Gleason 01aef5e89e
Remove withDismiss prop from status, update CHANGELOG 2023-02-02 12:06:39 -06:00
Mark Felder d0078e7f17 Permit muting a thread as an option on any post in the thread 2023-02-02 12:13:23 -05:00
Alex Gleason 0d99ae5daa
yarn lint:js --fix 2023-02-01 16:13:42 -06:00
Alex Gleason 56203b69ab
Add Tailwind eslint 2023-02-01 16:13:30 -06:00
marcin mikołajczak 0e66e230a7 Update en.json
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-02-01 23:00:19 +01:00
Alex Gleason 382bc6732d
Merge remote-tracking branch 'origin/develop' into chat-composer 2023-02-01 15:28:33 -06:00
Alex Gleason c4d7cbd907 Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2242
2023-01-31 18:43:21 +00:00
igeljaeger c774ec4296
Translated using Weblate (German)
Currently translated at 93.8% (1354 of 1443 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/de/
2023-01-31 19:42:21 +01:00
Alex Gleason 396652a75a Merge branch 'trs-iconbutton' into 'develop'
translate button component using soapobox's iconbutton

See merge request soapbox-pub/soapbox!2240
2023-01-30 22:53:44 +00:00
Tassoman 3b4df99788 translate button component using soapobox's iconbutton 2023-01-30 22:53:44 +00:00
marcin mikołajczak db15858b9f Merge remote-tracking branch 'soapbox/develop' into rss-button
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-30 23:16:25 +01:00
Alex Gleason cfd3ea9467 Merge branch 'status-font-size' into 'develop'
Increase font size of focused status in threads

See merge request soapbox-pub/soapbox!2232
2023-01-30 19:53:24 +00:00
Alex Gleason 747cc8c5b9
StatusContent: size --> textSize 2023-01-30 13:38:29 -06:00
Alex Gleason 7bdca9d192 Merge branch 'accounts-scss' into 'develop'
Delete accounts.scss

See merge request soapbox-pub/soapbox!2136
2023-01-30 18:33:59 +00:00
Chewbacca 352382cd05
Use Grid + Aspect to size MediaItem 2023-01-30 12:17:06 -06:00
Alex Gleason d64b8d9b16
Merge remote-tracking branch 'origin/develop' into accounts-scss 2023-01-30 12:14:51 -06:00
Alex Gleason d82c5508c0 Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2241
2023-01-30 15:54:42 +00:00
Poesty Li bf316483b0
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1443 of 1443 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-01-30 12:39:55 +01:00
Tassoman 9f11a21dc4
Translated using Weblate (Italian)
Currently translated at 100.0% (1443 of 1443 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/it/
2023-01-30 12:39:54 +01:00
Alex Gleason 8ab8647a84 Merge branch 'fix-warnings' into 'develop'
Fix a couple warnings

See merge request soapbox-pub/soapbox!2239
2023-01-29 23:17:09 +00:00
Chewbacca 44fce6fbf3
Add 'key' to Link to fix react console error 2023-01-29 16:42:12 -06:00
Alex Gleason 3dd4efdc14
Fix pointless relationships conditional 2023-01-29 16:41:48 -06:00
marcin mikołajczak 8763bdfa9f Merge branch 'notification-account' into 'develop'
Switch back to using account-container in notification list

Closes #1343

See merge request soapbox-pub/soapbox!2238
2023-01-29 22:31:13 +00:00
marcin mikołajczak bb4aac4c65 Switch back to using account-container in notification list
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-29 23:11:52 +01:00
Alex Gleason daaa3125a5 Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2237
2023-01-29 20:00:48 +00:00
Poesty Li 89340b3d55
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1443 of 1443 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-01-29 01:05:55 +01:00
Alex Gleason 41452409ca Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2236
2023-01-28 18:10:52 +00:00
Tassoman 5535fa9af2
Translated using Weblate (Italian)
Currently translated at 100.0% (1443 of 1443 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/it/
2023-01-28 18:34:05 +01:00
Alex Gleason a8b1ef49e6 Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2235
2023-01-28 16:06:03 +00:00
Poesty Li 3c5e37ea1a
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1348 of 1348 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-01-28 16:47:24 +01:00
marcin mikołajczak 81f92a0231 Merge branch 'mastodon-groups' into 'develop'
Mastodon groups

See merge request soapbox-pub/soapbox!1992
2023-01-28 15:47:13 +00:00
Alex Gleason 8d6784a4be Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2234
2023-01-28 15:30:31 +00:00
marcin mikołajczak 3422e966d4 Update en.json
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-28 15:29:02 +01:00
Poesty Li b0c62344e0
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1348 of 1348 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-01-28 10:11:18 +01:00
marcin mikołajczak 8f71096ad0 Update en.json
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-28 09:32:23 +01:00
Poesty Li a6a22f4b52
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1348 of 1348 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-01-28 09:01:32 +01:00
igeljaeger 289212c403
Translated using Weblate (German)
Currently translated at 100.0% (1348 of 1348 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/de/
2023-01-28 09:01:31 +01:00
marcin mikołajczak 8435a6dab7 Update en.json
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-27 23:58:34 +01:00
marcin mikołajczak 082092444b Update translation key
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-27 23:11:31 +01:00
marcin mikołajczak 1f39ddf0ec Merge remote-tracking branch 'soapbox/develop' into mastodon-groups
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-27 23:07:26 +01:00
Alex Gleason 4fe8cb6aa3 Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2233
2023-01-27 21:54:12 +00:00
Ryan Chiang 2d4b690206
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1348 of 1348 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-01-27 21:46:19 +01:00
Alex Gleason 82b6f55ac2 Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2231
2023-01-27 19:08:07 +00:00
Alex Gleason 1169149b83
Increase font size of focused status in threads 2023-01-27 12:36:49 -06:00
Ryan Chiang 0d057faf15
Translated using Weblate (Chinese (Simplified))
Currently translated at 99.7% (1345 of 1348 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-01-27 15:01:22 +01:00
Ryan Chiang 453a3d62b2
Translated using Weblate (Chinese (Simplified))
Currently translated at 98.8% (1333 of 1348 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-01-27 14:32:26 +01:00
Poesty Li 269f6d1f91
Translated using Weblate (Chinese (Simplified))
Currently translated at 98.8% (1333 of 1348 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-01-27 14:32:26 +01:00
Ryan Chiang 9cc17fe47c
Translated using Weblate (Chinese (Simplified))
Currently translated at 90.8% (1225 of 1348 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-01-27 09:37:38 +01:00
Tassoman bdc79be5b2
Translated using Weblate (Georgian)
Currently translated at 85.8% (1157 of 1348 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ka/
2023-01-27 01:39:43 +01:00
Tassoman 611f35e116
Translated using Weblate (Galician)
Currently translated at 85.8% (1157 of 1348 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/gl/
2023-01-27 01:39:43 +01:00
Ryan Chiang b0fdb6c9e0
Translated using Weblate (Chinese (Simplified))
Currently translated at 82.7% (1115 of 1348 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-01-27 01:39:43 +01:00
marcin mikołajczak 0d1ea0b6e8 Merge branch 'translate-icon' into 'develop'
Add icon to 'Translate' button

See merge request soapbox-pub/soapbox!2227
2023-01-27 00:39:36 +00:00
Alex Gleason cb4c6d7ccb Apply 1 suggestion(s) to 1 file(s) 2023-01-27 00:25:29 +00:00
marcin mikołajczak 83a500ee92 Add outline to translate button
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-27 00:23:55 +01:00
Alex Gleason 54b767ad38 Merge branch 'upgrade-virtuoso' into 'develop'
Upgrade Virtuoso to v4.0.6

See merge request soapbox-pub/soapbox!2230
2023-01-26 20:56:17 +00:00
Alex Gleason 1abf289d1b
Fix React 17 jsx-runtime module resolution bug 2023-01-26 14:33:29 -06:00
Alex Gleason edd453cc47
Upgrade Virtuoso to v4.0.6 2023-01-26 14:32:01 -06:00
Alex Gleason 54f6d49d48 Merge branch 'fix-external-scopes' into 'develop'
Fix external login scopes

See merge request soapbox-pub/soapbox!2226
2023-01-26 20:31:19 +00:00
Alex Gleason 7b32373694
Move chat attachments into composer 2023-01-26 12:30:26 -06:00
Alex Gleason 623ad077a6 Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2228
2023-01-26 16:37:00 +00:00
Ryan Chiang d8113bd111
Translated using Weblate (Chinese (Simplified))
Currently translated at 82.7% (1115 of 1348 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-01-26 17:34:38 +01:00
gallegonovato 613ec30d3f
Translated using Weblate (Spanish)
Currently translated at 100.0% (1348 of 1348 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/es/
2023-01-26 17:34:38 +01:00
igeljaeger 157c5385b8
Translated using Weblate (German)
Currently translated at 100.0% (1348 of 1348 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/de/
2023-01-26 17:34:38 +01:00
marcin mikołajczak a1dabbdee2 Add icon to 'Translate' button
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-26 14:44:20 +01:00
marcin mikołajczak da1510a089 Merge branch 'repost-events' into 'develop'
Add 'Repost event' to menu

Closes #1272

See merge request soapbox-pub/soapbox!2225
2023-01-25 23:33:32 +00:00
marcin mikołajczak fc379c399c Update en.json
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-26 00:20:37 +01:00
Alex Gleason a4addf9aee
Fix external login scopes 2023-01-25 16:32:59 -06:00
marcin mikołajczak 69b597d119 Add 'Repost event' to menu
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-25 23:16:03 +01:00
Alex Gleason 382e464390
Move chat attachments into the chat composer 2023-01-25 15:45:33 -06:00
Alex Gleason a68b794476 Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2224
2023-01-25 15:20:09 +00:00
igeljaeger 94276a84a6
Translated using Weblate (German)
Currently translated at 100.0% (1345 of 1345 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/de/
2023-01-25 16:16:40 +01:00
Tony 1682796043
Translated using Weblate (Croatian)
Currently translated at 99.4% (1337 of 1345 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/hr/
2023-01-25 08:50:59 +01:00
gallegonovato d2c60d0c09
Translated using Weblate (Spanish)
Currently translated at 100.0% (1345 of 1345 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/es/
2023-01-25 08:50:59 +01:00
igeljaeger 4dc754c65e
Translated using Weblate (German)
Currently translated at 100.0% (1345 of 1345 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/de/
2023-01-25 08:50:58 +01:00
Alex Gleason eb54e5c15c Merge branch 'polyfills' into 'develop'
Increase compatibility with older browsers

See merge request soapbox-pub/soapbox!2221
2023-01-24 18:48:24 +00:00
Alex Gleason 3bfc518599 Merge branch 'tokens-improvements' into 'develop'
Make OAuth tokens API more resilient

See merge request soapbox-pub/soapbox!2223
2023-01-24 18:44:48 +00:00
Alex Gleason ad6d03b4eb
Make OAuth tokens API more resilient 2023-01-24 12:00:34 -06:00
marcin mikołajczak 845ef1c4d4 Merge branch 'i18n' into 'develop'
i18n: handle plurals

See merge request soapbox-pub/soapbox!2222
2023-01-24 15:08:00 +00:00
Alex Gleason 70de5aea0f
Increase janky test timeout even more >:( 2023-01-23 17:53:06 -06:00
marcin mikołajczak 88e2c011a1 i18n: handle plurals
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-24 00:08:51 +01:00
Alex Gleason 2ba01c06a9
Move polyfills import to the top 2023-01-23 16:52:04 -06:00
Alex Gleason 672938a66e
Fix media modal on older browsers 2023-01-23 16:46:20 -06:00
Alex Gleason ce01b93a70
Replace occurrences of fetch() with axios 2023-01-23 16:09:45 -06:00
Alex Gleason f244bd3ce1
AutosuggestTextarea: bind `this`, fix crash in older browsers 2023-01-23 15:57:49 -06:00
Alex Gleason de375cdb15
CHANGELOG: browser support 2023-01-23 15:25:29 -06:00
Alex Gleason 9b65f04f57
Add report.html to sw ignore list 2023-01-23 15:24:28 -06:00
Alex Gleason fa892ff906
Upgrade core-js to v3.27.2 2023-01-23 15:22:10 -06:00
Alex Gleason 6f3adfbecd
Use a more generous browerlist with higher compatibility 2023-01-23 15:11:26 -06:00
Alex Gleason b2188016c2
Add back some polyfills not covered by core-js 2023-01-23 15:00:34 -06:00
Alex Gleason f61b2bb96c Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2220
2023-01-23 18:11:52 +00:00
Hosted Weblate f9701d1545
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-01-23 19:10:56 +01:00
Hosted Weblate 65cc4c4e30
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-01-23 19:10:48 +01:00
Tassoman fa72175740
Translated using Weblate (Italian)
Currently translated at 100.0% (1347 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/it/
2023-01-23 19:10:48 +01:00
igeljaeger ece913c58f
Translated using Weblate (German)
Currently translated at 99.7% (1344 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/de/
2023-01-23 19:10:48 +01:00
Alex Gleason 702c07d3e0 Merge branch 'alexgleason-develop-patch-05427' into 'develop'
Update CHANGELOG.md

See merge request soapbox-pub/soapbox!2219
2023-01-23 18:10:43 +00:00
Alex Gleason 71a7787364 Update CHANGELOG.md 2023-01-23 18:10:20 +00:00
Alex Gleason 5973c16839 Merge branch 'sw-network-first' into 'develop'
ServiceWorker: use network-first strategy

See merge request soapbox-pub/soapbox!2159
2023-01-23 18:09:37 +00:00
Alex Gleason 1950d79e9a Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2217
2023-01-23 15:25:28 +00:00
igeljaeger f955492ad1
Translated using Weblate (German)
Currently translated at 100.0% (1347 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/de/
2023-01-23 08:18:21 +01:00
Alex Gleason a37ae84d26 Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2204
2023-01-23 00:02:53 +00:00
Tassoman 78c2b5dd09
Translated using Weblate (Italian)
Currently translated at 100.0% (1347 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/it/
2023-01-22 23:44:57 +01:00
Tony b568c42e6f
Translated using Weblate (Croatian)
Currently translated at 99.7% (1343 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/hr/
2023-01-22 23:44:57 +01:00
Tassoman 93a848e23c
Translated using Weblate (Finnish)
Currently translated at 86.6% (1167 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/fi/
2023-01-22 23:44:57 +01:00
Tassoman c99db03812
Translated using Weblate (Estonian)
Currently translated at 86.6% (1167 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/et/
2023-01-22 23:44:57 +01:00
Tassoman 9a95180e90
Translated using Weblate (Esperanto)
Currently translated at 86.6% (1167 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/eo/
2023-01-22 23:44:56 +01:00
Tassoman d1c33bacec
Translated using Weblate (Dutch)
Currently translated at 86.6% (1167 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/nl/
2023-01-22 23:44:56 +01:00
Tassoman 58e5c9a987
Translated using Weblate (Danish)
Currently translated at 86.6% (1167 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/da/
2023-01-22 23:44:56 +01:00
Tassoman 039a5d2bfd
Translated using Weblate (Czech)
Currently translated at 86.6% (1167 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/cs/
2023-01-22 23:44:56 +01:00
Tassoman adfdb16731
Translated using Weblate (Corsican)
Currently translated at 86.6% (1167 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/co/
2023-01-22 23:44:56 +01:00
Tassoman e2a7219571
Translated using Weblate (Chinese (Traditional, Hong Kong))
Currently translated at 86.6% (1167 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hant_HK/
2023-01-22 23:44:56 +01:00
Tassoman 05b24ea83c
Translated using Weblate (Chinese (Traditional))
Currently translated at 86.6% (1167 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hant/
2023-01-22 23:44:56 +01:00
Tassoman 17c6c430ad
Translated using Weblate (Chinese (Simplified))
Currently translated at 86.6% (1167 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/zh_Hans/
2023-01-22 23:44:56 +01:00
Tassoman 3fafb8aee3
Translated using Weblate (Catalan)
Currently translated at 86.6% (1167 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ca/
2023-01-22 23:44:56 +01:00
Tassoman 042fd1aa0d
Translated using Weblate (Bulgarian)
Currently translated at 86.6% (1167 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/bg/
2023-01-22 23:44:56 +01:00
Tassoman d007a8d106
Translated using Weblate (Italian)
Currently translated at 100.0% (1347 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/it/
2023-01-22 23:44:56 +01:00
Tassoman fc19c73b5c
Translated using Weblate (Bengali)
Currently translated at 86.6% (1167 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/bn/
2023-01-22 23:44:56 +01:00
Tassoman 38d2445cbd
Translated using Weblate (Basque)
Currently translated at 86.6% (1167 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/eu/
2023-01-22 23:44:56 +01:00
Tassoman 9ae739bde9
Translated using Weblate (Asturian)
Currently translated at 86.6% (1167 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ast/
2023-01-22 23:44:56 +01:00
Tony d357ef7c0f
Translated using Weblate (Croatian)
Currently translated at 99.7% (1343 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/hr/
2023-01-22 23:44:56 +01:00
Tony ff4d9a7281
Translated using Weblate (Croatian)
Currently translated at 99.7% (1343 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/hr/
2023-01-22 23:44:56 +01:00
Tony c63b086fa9
Translated using Weblate (Croatian)
Currently translated at 99.7% (1343 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/hr/
2023-01-22 23:44:56 +01:00
Tony 2a228be0ad
Translated using Weblate (Croatian)
Currently translated at 99.7% (1343 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/hr/
2023-01-22 23:44:56 +01:00
Tony f9e9cb78fd
Translated using Weblate (Croatian)
Currently translated at 99.7% (1343 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/hr/
2023-01-22 23:44:56 +01:00
Tony fea5f36dbe
Translated using Weblate (Croatian)
Currently translated at 99.7% (1343 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/hr/
2023-01-22 23:44:56 +01:00
Tony 1fa1f7dcde
Translated using Weblate (Croatian)
Currently translated at 99.7% (1343 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/hr/
2023-01-22 23:44:56 +01:00
Tony d1884e6660
Translated using Weblate (Croatian)
Currently translated at 99.7% (1343 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/hr/
2023-01-22 23:44:56 +01:00
Tassoman 0c4584a086
Translated using Weblate (Italian)
Currently translated at 100.0% (1347 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/it/
2023-01-22 23:44:56 +01:00
Adrien Bourmault fc30389fa6
Translated using Weblate (French)
Currently translated at 100.0% (1347 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/fr/
2023-01-22 23:44:56 +01:00
gallegonovato 0c548730aa
Translated using Weblate (Spanish)
Currently translated at 100.0% (1347 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/es/
2023-01-22 23:44:56 +01:00
Tassoman ca6183b81d
Translated using Weblate (Armenian)
Currently translated at 86.6% (1167 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/hy/
2023-01-22 23:44:56 +01:00
Tassoman 499eb851ff
Translated using Weblate (Albanian)
Currently translated at 86.6% (1167 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/sq/
2023-01-22 23:44:56 +01:00
Adrien Bourmault 39826745fb
Translated using Weblate (French)
Currently translated at 100.0% (1347 of 1347 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/fr/
2023-01-22 23:44:56 +01:00
Adrien Bourmault 7dff487097
Translated using Weblate (French)
Currently translated at 100.0% (1346 of 1346 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/fr/
2023-01-22 23:44:56 +01:00
Tony 8ee459270e
Translated using Weblate (Croatian)
Currently translated at 99.7% (1343 of 1346 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/hr/
2023-01-22 23:44:55 +01:00
neox_ 6a98a72f80
Translated using Weblate (French)
Currently translated at 100.0% (1346 of 1346 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/fr/
2023-01-22 23:44:55 +01:00
Adrien Bourmault 0db77f26d5
Translated using Weblate (French)
Currently translated at 100.0% (1346 of 1346 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/fr/
2023-01-22 23:44:55 +01:00
marcin mikołajczak f945306990 Merge branch 'media-modal-fix' into 'develop'
Fix #1330

Closes #1330

See merge request soapbox-pub/soapbox!2216
2023-01-22 22:44:38 +00:00
marcin mikołajczak 901861d5b8 Fix #1330
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-22 23:29:44 +01:00
Alex Gleason fa86d1d5dd Merge branch 'i-1263' into 'develop'
transatable staff badges inside profile

Closes #1263

See merge request soapbox-pub/soapbox!2207
2023-01-21 16:15:17 +00:00
Tassoman cf677a610b transatable staff badges inside profile 2023-01-21 16:15:17 +00:00
Alex Gleason 53736197b3 Merge branch 'renovate/docker-20.x' into 'develop'
Update docker Docker tag to v20.10.23

See merge request soapbox-pub/soapbox!2209
2023-01-21 03:28:50 +00:00
Soapbox Bot 13511cc81f Update docker Docker tag to v20.10.23 2023-01-21 02:06:34 +00:00
marcin mikołajczak 33a8ab1611 Merge branch 'cleanup' into 'develop'
Remove unused styles

See merge request soapbox-pub/soapbox!2208
2023-01-20 22:36:12 +00:00
marcin mikołajczak 8d62e56c62 Remove unused styles
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-20 22:31:21 +01:00
Alex Gleason d9b5aedb7d Merge branch 'improve-chat-media' into 'develop'
Chats: improve design of attachments, fix sizing bug

See merge request soapbox-pub/soapbox!2188
2023-01-20 19:39:50 +00:00
Alex Gleason e2a4bfc632
Chats: fix bubble corner for other person's message 2023-01-20 13:08:10 -06:00
Alex Gleason 58cf71ceda
ChatMessageList: fix regression with links not wrapping 2023-01-20 11:56:50 -06:00
Alex Gleason ec0a3d6eea
Chats: actually, do use a paperclip 2023-01-20 11:53:10 -06:00
Alex Gleason af1ad92432
Chats: use plus icon to upload attachment 2023-01-20 11:29:40 -06:00
Alex Gleason f222491b3e
ChatMessageList: sharpen top-right corner of bubble when there's an attachment 2023-01-20 11:13:54 -06:00
Alex Gleason 11b48dbd55
Fix media gallery border-radius on Safari 2023-01-20 11:05:35 -06:00
Alex Gleason bab64a98af
Merge remote-tracking branch 'origin/develop' into improve-chat-media 2023-01-20 10:14:22 -06:00
Alex Gleason bc47a8986a Merge branch 'i-1322' into 'develop'
adding: bot badge inside timeline statuses

Closes #1322

See merge request soapbox-pub/soapbox!2206
2023-01-20 16:01:13 +00:00
Tassoman 6696cde093 adding: bot badge inside timeline statuses 2023-01-20 16:01:13 +00:00
marcin mikołajczak 3c7aa81be1 Merge branch 'awaiting-approval-message' into 'develop'
Show appropriate message when account is awaiting approval

See merge request soapbox-pub/soapbox!2205
2023-01-20 15:17:41 +00:00
marcin mikołajczak 3debf9afd4 Update en.json
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-20 14:07:48 +01:00
marcin mikołajczak e197cca02d Show appropriate message when account is awaiting approval
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-20 12:09:04 +01:00
Alex Gleason 3a1910fdd9 Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2203
2023-01-19 23:16:11 +00:00
neox_ 31151fc5a2
Translated using Weblate (French)
Currently translated at 100.0% (1346 of 1346 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/fr/
2023-01-20 00:11:55 +01:00
neox_ 44e3b59102
Translated using Weblate (French)
Currently translated at 100.0% (1346 of 1346 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/fr/
2023-01-20 00:11:34 +01:00
Adrien Bourmault caacddf361
Translated using Weblate (French)
Currently translated at 100.0% (1346 of 1346 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/fr/
2023-01-20 00:11:34 +01:00
gallegonovato 848b883fe8
Translated using Weblate (Spanish)
Currently translated at 100.0% (1346 of 1346 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/es/
2023-01-20 00:11:32 +01:00
Guillermo b2e47a7d21
Translated using Weblate (Spanish (Argentina))
Currently translated at 90.4% (1217 of 1346 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/es_AR/
2023-01-20 00:11:32 +01:00
marcin mikołajczak 39a921b2d0 Merge branch 'takahe-features' into 'develop'
Update features.ts

See merge request soapbox-pub/soapbox!2198
2023-01-19 22:46:25 +00:00
Alex Gleason 27c40b321b Merge branch 'revert-59f63eb4' into 'develop'
Revert "Merge branch 'remove-immutable-purecomponent' into 'develop'"

Closes #1332 and #1331

See merge request soapbox-pub/soapbox!2202
2023-01-19 19:24:22 +00:00
Alex Gleason f28886e77b Revert "Merge branch 'remove-immutable-purecomponent' into 'develop'"
This reverts merge request !2201
2023-01-19 19:23:54 +00:00
Alex Gleason 59f63eb4f0 Merge branch 'remove-immutable-purecomponent' into 'develop'
Remove react-immutable-pure-component

See merge request soapbox-pub/soapbox!2201
2023-01-19 18:32:44 +00:00
Alex Gleason 7f578ce44f
browserlists: remove "not IE11" since "not dead" already prevents targeting it 2023-01-19 11:31:33 -06:00
Alex Gleason 7035e00267
Remove react-immutable-pure-component 2023-01-19 11:30:00 -06:00
marcin mikołajczak cb5702db15 Merge branch 'friendica' into 'develop'
Friendica support

See merge request soapbox-pub/soapbox!1044
2023-01-18 23:25:50 +00:00
marcin mikołajczak 6963c44564 Update CHANGELOG.md
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-19 00:16:59 +01:00
marcin mikołajczak 8846fdaabc Merge remote-tracking branch 'soapbox/develop' into friendica 2023-01-19 00:16:16 +01:00
marcin mikołajczak 2aaac98cba Merge branch 'friendica' of https://gitlab.com/mkljczk/soapbox-fe into friendica 2023-01-19 00:15:52 +01:00
marcin mikołajczak afd4a39337 Friendica, version parsing fixes
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-19 00:15:32 +01:00
Alex Gleason 530ff3476e Merge branch 'referrer' into 'develop'
index.html: remove referrer meta tag

See merge request soapbox-pub/soapbox!2197
2023-01-18 22:01:02 +00:00
marcin mikołajczak 7d1e13c28d Update features.ts 2023-01-18 21:53:33 +00:00
marcin mikołajczak 66f48ca982 Friendica support
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-18 22:41:54 +01:00
marcin mikołajczak e7171cb2f0 Update features.ts 2023-01-18 21:21:13 +00:00
Alex Gleason 3e6798bd23
index.html: remove referrer meta tag 2023-01-18 12:16:59 -06:00
Alex Gleason f02e8cf282 Merge branch 'cjs' into 'develop'
Rename some files to .cjs, make the codebase aware of .cjs and .mjs extensions

See merge request soapbox-pub/soapbox!2190
2023-01-18 16:42:08 +00:00
Alex Gleason 66edd94057 Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2193
2023-01-18 14:14:34 +00:00
Tassoman 94f99061d0
Translated using Weblate (Italian)
Currently translated at 100.0% (1346 of 1346 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/it/
2023-01-18 15:09:03 +01:00
Alex Gleason c63b6315f3 Merge branch 'react-router-dom-v5-compat' into 'develop'
Setup react-router v5-v6 transitional package

See merge request soapbox-pub/soapbox!2180
2023-01-18 13:36:24 +00:00
Alex Gleason 17a5be7136 Merge branch 'tailwind-index' into 'develop'
Add tailwind.css

See merge request soapbox-pub/soapbox!2191
2023-01-18 13:35:50 +00:00
Alex Gleason 15ddf9ef36 Merge branch 'remove-marky' into 'develop'
Remove marky, mark-loader

See merge request soapbox-pub/soapbox!2192
2023-01-18 13:34:51 +00:00
marcin mikołajczak e41b35bfdc Merge branch 'compose-improvements' into 'develop'
Minor composer improvements

See merge request soapbox-pub/soapbox!2181
2023-01-18 06:48:22 +00:00
marcin mikołajczak 8b4df16f75 Merge branch 'wildebeest' into 'develop'
Support Wildebeest

See merge request soapbox-pub/soapbox!2152
2023-01-18 06:48:10 +00:00
Alex Gleason feeb80fe22
Remove marky, mark-loader 2023-01-17 21:40:23 -06:00
Alex Gleason 5712ec110a
Add tailwind.css 2023-01-17 21:29:52 -06:00
Alex Gleason 44c3ddb8a9
vscode: don't lint css through VSCode (rely on stylint and Tailwind extension) 2023-01-17 21:20:46 -06:00
Alex Gleason 842ada3930 Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2186
2023-01-18 02:47:34 +00:00
Alex Gleason 54eae01255
Rename some files to .cjs, make the codebase aware of .cjs and .mjs extensions 2023-01-17 18:34:11 -06:00
Guillermo 5115bdc565
Translated using Weblate (Spanish (Argentina))
Currently translated at 90.0% (1210 of 1343 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/es_AR/
2023-01-18 00:51:10 +01:00
marcin mikołajczak 2dcbc9a1e7 Merge branch 'mkljczk-develop-patch-08180' into 'develop'
Fix @ see in features.ts

See merge request soapbox-pub/soapbox!2189
2023-01-17 23:51:00 +00:00
marcin mikołajczak 06b040241c Fix @see in features.ts 2023-01-17 23:12:17 +00:00
Alex Gleason a4692f45ea
CHANGELOG: update for chat attachment improvements 2023-01-17 14:48:58 -06:00
Alex Gleason 42ab37ce7b Merge branch 'autoplay-embed' into 'develop'
Autoplay embedded videos after the play button is clicked

See merge request soapbox-pub/soapbox!2187
2023-01-17 20:45:11 +00:00
Alex Gleason f823690b7e
Chats: don't display "copy" button if there's no text to copy 2023-01-17 14:34:31 -06:00
Alex Gleason 687fcdc294
Chats: improve design of attachments, fix sizing bug 2023-01-17 14:33:04 -06:00
Alex Gleason ed8299892c
Autoplay embedded videos after the play button is clicked 2023-01-17 13:12:47 -06:00
Alex Gleason 988d466fcd Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2184
2023-01-17 04:40:35 +00:00
Hosted Weblate 4150cdb443
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-01-17 04:26:00 +01:00
Hosted Weblate cb6fc21a72
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-01-17 04:25:55 +01:00
Hosted Weblate fb160f85b6
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-01-17 04:25:51 +01:00
Hosted Weblate ab04f64881
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-01-17 04:25:47 +01:00
Hosted Weblate 911deae476
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-01-17 04:25:43 +01:00
Hosted Weblate a430ae6642
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-01-17 04:25:38 +01:00
Hosted Weblate 83c8d106cc
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-01-17 04:25:34 +01:00
Tassoman 5ebb8a7609
Translated using Weblate (Breton)
Currently translated at 86.8% (1167 of 1343 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/br/
2023-01-17 04:25:28 +01:00
marcin mikołajczak f018ffe813 Update en.json
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-16 23:20:02 +01:00
Alex Gleason 498752d300 Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2183
2023-01-16 20:55:27 +00:00
gallegonovato 79254c09ff
Translated using Weblate (Spanish)
Currently translated at 100.0% (1343 of 1343 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/es/
2023-01-16 21:54:56 +01:00
Alex Gleason 397bd3fa39 Merge branch 'font-imports' into 'develop'
Move external CSS imports to main.tsx

See merge request soapbox-pub/soapbox!2182
2023-01-16 20:54:51 +00:00
Alex Gleason c92dd8f555
Move external CSS imports to main.tsx 2023-01-16 14:08:40 -06:00
marcin mikołajczak 2527e2e3fb Merge branch 'sensitive-overlay' into 'develop'
Improvements for sensitive content overlay for too long posts

See merge request soapbox-pub/soapbox!2178
2023-01-16 20:05:11 +00:00
marcin mikołajczak 4ec90c031e Minor composer improvements
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-16 20:49:44 +01:00
Alex Gleason ed5af3d997
Setup react-router v5-v6 transitional package
https://github.com/remix-run/react-router/discussions/8753
2023-01-16 13:22:32 -06:00
Alex Gleason 9712962240 Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2179
2023-01-16 14:17:00 +00:00
Tony 384839e5a5
Translated using Weblate (Croatian)
Currently translated at 99.7% (1339 of 1343 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/hr/
2023-01-16 08:51:03 +01:00
Soapbox Spanisher aa012bbb71
Translated using Weblate (Spanish)
Currently translated at 99.8% (1341 of 1343 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/es/
2023-01-16 08:51:03 +01:00
marcin mikołajczak 9611509a7e Improvements for sensitive content overlay for too long posts
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-15 23:05:04 +01:00
Alex Gleason d481f3d7c6 Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2175
2023-01-15 20:34:50 +00:00
Hosted Weblate 63a6d6f03b
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-01-15 21:32:07 +01:00
Alex Gleason ed79beb216 Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2174
2023-01-15 20:31:54 +00:00
Hosted Weblate 9b1501002f
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-01-15 21:25:30 +01:00
Alex Gleason 6aa3974d49 Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2173
2023-01-15 20:25:16 +00:00
Hosted Weblate 4a66dd3f48
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-01-15 20:37:37 +01:00
Abid Nevesinjac c135bba465
Translated using Weblate (Bosnian)
Currently translated at 19.6% (264 of 1345 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/bs/
2023-01-15 20:37:27 +01:00
marcin mikołajczak 45a1d3e98d
Translated using Weblate (Polish)
Currently translated at 87.4% (1176 of 1345 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/pl/
2023-01-15 20:37:27 +01:00
Tony 8476d24b85
Translated using Weblate (Croatian)
Currently translated at 99.7% (1341 of 1345 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/hr/
2023-01-15 20:37:27 +01:00
Alex Gleason d86878e561 Merge branch 'redirect-root' into 'develop'
Redirect the homepage to any path

See merge request soapbox-pub/soapbox!2160
2023-01-15 19:37:19 +00:00
Alex Gleason d2855b2565
RegistrationForm: add @ icon 2023-01-15 13:25:42 -06:00
Alex Gleason e48e5a5652
Delete unnecessary placeholder locale 2023-01-15 13:23:28 -06:00
Alex Gleason 5f747fa703
SoapboxConfig: fix UX of homepage redirect input 2023-01-15 13:22:03 -06:00
Alex Gleason a81577bcf6
Test public layout header 2023-01-15 13:07:42 -06:00
Alex Gleason 300d3a0200
Refactor tests with mock stores 2023-01-15 12:50:14 -06:00
Alex Gleason 0a90c3c377
Add tests to components with signup CTAs 2023-01-15 12:35:34 -06:00
Alex Gleason 1b2fcec0d7
RedirectRoot: correctly upgrade singleUserModeProfile of a remote user 2023-01-14 19:29:34 -06:00
Alex Gleason 6f40c471c4
soapbox.tsx: simplify pepeEnabled variable 2023-01-14 19:21:30 -06:00
Alex Gleason f218496b82
Fix UnauthorizedModal and Navbar 2023-01-14 19:18:13 -06:00
Alex Gleason 05f104199e Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2171
2023-01-14 19:16:23 +00:00
Tassoman 7b83c74390
Added a translation using Weblate (Bosnian) 2023-01-14 19:58:07 +01:00
Alex Gleason 65dbd096f5 Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2170
2023-01-14 17:52:41 +00:00
Tassoman d0283c2be9
Translated using Weblate (Italian)
Currently translated at 99.8% (1343 of 1345 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/it/
2023-01-14 16:57:32 +01:00
Tassoman 208a38c173
Translated using Weblate (Italian)
Currently translated at 99.2% (1335 of 1345 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/it/
2023-01-14 16:57:32 +01:00
Ahmad Dakhlallah 7c8c7d74ce
Translated using Weblate (Arabic)
Currently translated at 97.0% (1305 of 1345 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/ar/
2023-01-14 16:57:32 +01:00
Alex Gleason e47352e377 Merge branch 'scopes' into 'develop'
Remove features.scopes, move to a getScopes function

See merge request soapbox-pub/soapbox!2169
2023-01-14 15:57:22 +00:00
Alex Gleason e3faadac3d
Fix CHANGELOG 2023-01-13 19:31:13 -06:00
Alex Gleason aba3be798d
Merge remote-tracking branch 'origin/develop' into redirect-root 2023-01-13 19:14:06 -06:00
Alex Gleason 9f689efa30
Merge branch 'redirect-root' of gitlab.com:soapbox-pub/soapbox into redirect-root 2023-01-13 19:14:00 -06:00
Alex Gleason 82981efe9a
Add useRegistrationStatus hook 2023-01-13 19:13:15 -06:00
Alex Gleason 29bf78d09b
Correctly normalize singleUserModeProfile if it has an @ 2023-01-13 18:54:25 -06:00
Alex Gleason 7ef45eaa73
Remove features.scopes, move to a getScopes function 2023-01-13 18:43:57 -06:00
Alex Gleason bb5d9c6f2e Merge branch 'bump-3.1' into 'develop'
Bump CHANGELOG to v3.1

See merge request soapbox-pub/soapbox!2167
2023-01-13 19:48:54 +00:00
Alex Gleason ccb4f54468
Bump CHANGELOG to v3.1 2023-01-13 13:48:10 -06:00
Alex Gleason 21f864c8a6 Merge branch 'backups' into 'develop'
Restore zip backups, export CSV, import CSV

Closes #1264

See merge request soapbox-pub/soapbox!2158
2023-01-13 19:41:01 +00:00
Alex Gleason 1215c99b61 Merge branch 'qrcode-border' into 'develop'
Upgrade qrcode.react, add white border

Closes #1321

See merge request soapbox-pub/soapbox!2166
2023-01-13 19:39:15 +00:00
Alex Gleason b1af21956e
Upgrade qrcode.react, add white border
Fixes https://gitlab.com/soapbox-pub/soapbox/-/issues/1321
2023-01-13 12:47:51 -06:00
Alex Gleason 8b50afc128 Merge branch 'types-react' into 'develop'
Upgrade @types/react to v18

See merge request soapbox-pub/soapbox!2147
2023-01-13 18:05:59 +00:00
Alex Gleason 613a0077d3 Merge branch 'compose-icon' into 'develop'
ComposeForm: fix publish icon

Closes #1319

See merge request soapbox-pub/soapbox!2165
2023-01-13 17:53:36 +00:00
Alex Gleason b28e80a1fe
ComposeForm: fix publish icon
Fixes https://gitlab.com/soapbox-pub/soapbox/-/issues/1319
2023-01-13 11:10:39 -06:00
Alex Gleason 36e9a88929 Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2164
2023-01-13 16:17:11 +00:00
Alex Gleason edfece4ac0
Merge remote-tracking branch 'origin/develop' into types-react 2023-01-13 09:56:20 -06:00
Dan 27dabda872
Translated using Weblate (Ukrainian)
Currently translated at 87.0% (1171 of 1345 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/uk/
2023-01-13 07:48:46 +01:00
Tassoman d5ac42b6d1
Translated using Weblate (Italian)
Currently translated at 94.9% (1277 of 1345 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/it/
2023-01-12 22:43:45 +01:00
Tassoman c8c0c2d4d8
Translated using Weblate (Italian)
Currently translated at 91.0% (1225 of 1345 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/it/
2023-01-12 22:10:29 +01:00
Alex Gleason 3e8137172c Merge branch 'status-content-18' into 'develop'
StatusContent: useLayoutEffect, fix "read more" button glitchiness on React 18

See merge request soapbox-pub/soapbox!2162
2023-01-12 21:07:07 +00:00
Alex Gleason c032c0bfea Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2163
2023-01-12 20:54:33 +00:00
Corné Dorrestijn 0531f8babf Apply 1 suggestion(s) to 1 file(s) 2023-01-12 20:05:04 +00:00
Tassoman 1b6c54348d
Translated using Weblate (Italian)
Currently translated at 87.2% (1174 of 1345 strings)

Translation: Soapbox/Soapbox
Translate-URL: https://hosted.weblate.org/projects/soapbox-pub/soapbox/it/
2023-01-12 20:26:01 +01:00
Alex Gleason d3f93d0325
Merge remote-tracking branch 'origin/develop' into accounts-scss 2023-01-12 11:38:56 -06:00
Alex Gleason 25a0730bf5
StatusContent: useLayoutEffect, fix "read more" button glitchiness on React 18 2023-01-12 10:57:39 -06:00
Alex Gleason 7e69eb2aa5 Merge branch 'gallery-18' into 'develop'
AccountGallery: fix crash in React 18

Closes #1318

See merge request soapbox-pub/soapbox!2161
2023-01-12 15:55:25 +00:00
Alex Gleason 8cbdc6019f
AccountGallery: fix crash in React 18
Fixes https://gitlab.com/soapbox-pub/soapbox/-/issues/1318
2023-01-12 09:41:11 -06:00
Alex Gleason d64f4edf61
Fix CtaBanner and UI tests 2023-01-11 19:38:05 -06:00
Alex Gleason 0bff56a9a8
redirectRootNoLogin: improve phrasing 2023-01-11 19:11:54 -06:00
Alex Gleason 3e2fe59bfd
Update en.json 2023-01-11 19:06:27 -06:00
Alex Gleason 5ab380f9bc
Update changelog 2023-01-11 19:04:26 -06:00
Alex Gleason e9a48b45e1
Remove redirect code from PublicLayout 2023-01-11 19:03:06 -06:00
Alex Gleason 6f0e398a78
Remove singleUserMode, upgrade to redirectRootNoLogin 2023-01-11 19:01:45 -06:00
Alex Gleason 1e07c03479
Merge remote-tracking branch 'origin/develop' into customize-redirect-from-root-when-not-logged-in-settings-input 2023-01-11 18:33:32 -06:00
Alex Gleason e9327c1883
ServiceWorker: use network-first strategy 2023-01-11 18:31:52 -06:00
Alex Gleason 658e336e5c
Fix export_data locale 2023-01-11 18:06:20 -06:00
Alex Gleason e50e4b8e60
Restore export data CSV (behind a feature flag) 2023-01-11 17:59:50 -06:00
Alex Gleason ebfd7bdc94
Move "Import data" under settings 2023-01-11 17:30:32 -06:00
Alex Gleason 98f311873c
Expose backups again 2023-01-11 17:25:55 -06:00
marcin mikołajczak c6700539f7 Merge branch 'hover-card-avatar' into 'develop'
Fix avatar size in profile hover card

See merge request soapbox-pub/soapbox!2157
2023-01-11 23:11:22 +00:00
marcin mikołajczak 6208ea8e43 Fix avatar size in profile hover card
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-11 23:45:43 +01:00
Alex Gleason 994d9ebd35 Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2156
2023-01-11 20:40:22 +00:00
Hosted Weblate e7331c4cdc
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-01-11 21:38:01 +01:00
Hosted Weblate ab56391c92
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-01-11 21:37:52 +01:00
Chewbacca 6a612a854a Merge branch 'improve-link-previews' into 'develop'
Remove 'file-icon' in empty link preview

See merge request soapbox-pub/soapbox!2041
2023-01-11 20:37:46 +00:00
Alex Gleason f6d86560ac Merge branch 'weblate-soapbox-pub-soapbox' into 'develop'
Translations update from Hosted Weblate

See merge request soapbox-pub/soapbox!2010
2023-01-11 20:31:18 +00:00
Hosted Weblate 65196d4ab4
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-01-11 21:07:01 +01:00
Chewbacca e1a38b9d41 Merge branch 'fix-undefined-bug' into 'develop'
Fix multiple bugs

See merge request soapbox-pub/soapbox!2142
2023-01-11 20:06:47 +00:00
Chewbacca cf9156b414 Refactor conditional 2023-01-11 14:55:52 -05:00
Alex Gleason 7607daf371 Merge branch 'fix-toast-test' into 'develop'
Fix toast test

See merge request soapbox-pub/soapbox!2153
2023-01-11 19:25:30 +00:00
Alex Gleason 5d0b10a5b8
Fix toast test 2023-01-11 13:13:27 -06:00
Alex Gleason 0d6cf4273d Merge branch 'fix/weblate1' into 'develop'
Weblate could not merge upstream changes while updating the repository.

See merge request soapbox-pub/soapbox!2107
2023-01-11 19:00:46 +00:00
Tassoman cfd5c1e927 Weblate could not merge upstream changes while updating the repository. 2023-01-11 19:00:46 +00:00
Chewbacca e36d26cb91 Merge branch 'use-api-error' into 'develop'
Use human-readable message from the API as the default

See merge request soapbox-pub/soapbox!2126
2023-01-11 17:36:25 +00:00
Chewbacca 375d135e65 Merge branch 'chats-jumpy-scrollbar' into 'develop'
Chats: fix jumpy scrollbar

Closes #1315

See merge request soapbox-pub/soapbox!2149
2023-01-11 16:45:50 +00:00
Chewbacca c3595ea15b Chats: fix jumpy scrollbar
Fixes: https://gitlab.com/soapbox-pub/soapbox/-/issues/1315

Co-authored-by: Alex Gleason <alex@alexgleason.me>
2023-01-11 11:13:56 -05:00
marcin mikołajczak 3bbfc716ad Support Wildebeest
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-11 14:21:35 +01:00
Alex Gleason f8be5ecdf4 Merge branch 'account-creation' into 'develop'
Expose Registration form to unknown backends

See merge request soapbox-pub/soapbox!2150
2023-01-11 04:24:16 +00:00
Alex Gleason e5f592bfaf
Expose Registration form to unknown backends 2023-01-10 22:10:27 -06:00
Alex Gleason ad18b0f1c9
Merge remote-tracking branch 'origin/develop' into types-react 2023-01-10 18:03:53 -06:00
Alex Gleason 87aa965069 Merge branch 'force-glob-parent' into 'develop'
Force a patched version of glob-parent

See merge request soapbox-pub/soapbox!2148
2023-01-10 23:32:10 +00:00
Alex Gleason 48fdc3882c
Force a patched version of glob-parent 2023-01-10 17:22:19 -06:00
Alex Gleason 5e22d1169f
Upgrade @types/react to v18 2023-01-10 17:03:15 -06:00
marcin mikołajczak 4ffaecbf32 Merge branch 'pending-status' into 'develop'
Set withLinkToProfile to false in PendingStatus

See merge request soapbox-pub/soapbox!2144
2023-01-10 22:22:02 +00:00
Alex Gleason c9bfc7d259 Merge branch 'remove-prop-types' into 'develop'
Remove prop-types

See merge request soapbox-pub/soapbox!2146
2023-01-10 21:55:00 +00:00
Alex Gleason edbbae2b48 Update babel.config.js 2023-01-10 21:36:35 +00:00
Alex Gleason 5de9afd18b
Remove prop-types 2023-01-10 15:06:26 -06:00
marcin mikołajczak 08742ea73d Set withLinkToProfile to false in PendingStatus
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-10 21:14:20 +01:00
Alex Gleason ead55d5c30 Merge branch 'jsonwebtoken' into 'develop'
Force jsonwebtoken to ^9.0.0

See merge request soapbox-pub/soapbox!2143
2023-01-10 19:36:47 +00:00
Alex Gleason f70c02e9cb
Force jsonwebtoken to ^9.0.0 2023-01-10 13:24:45 -06:00
Alex Gleason 5f2854571a
Fix order of en.json 2023-01-10 13:21:59 -06:00
Chewbacca a0e29ce3c8 Fix locale 2023-01-10 14:06:36 -05:00
Chewbacca ca3f9f9d8c Remove 'hasError' prop from FormGroup and Input 2023-01-10 13:41:32 -05:00
Chewbacca 4a345d7127 Ensure notifications are enabled 2023-01-10 13:21:29 -05:00
Chewbacca fedb17ba24 Fix console error 2023-01-10 13:17:57 -05:00
Alex Gleason bf159ad539 Merge branch 'remove-history' into 'develop'
Remove 'history' dep

See merge request soapbox-pub/soapbox!2138
2023-01-10 17:10:20 +00:00
Alex Gleason a4b9d7bbc3 Merge branch 'remove-polyfills' into 'develop'
Remove polyfills, delete application.ts

See merge request soapbox-pub/soapbox!2140
2023-01-10 17:09:09 +00:00
Alex Gleason 1c9cc9e0be Merge branch 'renovate/react-virtuoso-4.x' into 'develop'
Update dependency react-virtuoso to v4

See merge request soapbox-pub/soapbox!2119
2023-01-10 17:08:42 +00:00
Alex Gleason 5666121e2d
Increase timeout for intermittently failing test 2023-01-10 10:56:21 -06:00
Alex Gleason 14299ce62a
ScrollableList: update Virtuoso component types for v4 2023-01-10 10:36:28 -06:00
Soapbox Bot f5c6ea8fab Update dependency react-virtuoso to v4 2023-01-10 15:51:07 +00:00
Alex Gleason 37f0cde456
Merge remote-tracking branch 'origin/develop' into remove-polyfills 2023-01-10 09:30:42 -06:00
Alex Gleason 3c068568b0 Merge branch 'remove-dyslexic' into 'develop'
Remove Dyslexic mode code

See merge request soapbox-pub/soapbox!2137
2023-01-10 15:22:21 +00:00
Alex Gleason aea18d6086 Merge branch 'renovate/node-18.x' into 'develop'
Update dependency node to v18.13.0

See merge request soapbox-pub/soapbox!2141
2023-01-10 15:07:55 +00:00
Alex Gleason 72e8ae8d37 Merge branch 'renovate/major-react-monorepo' into 'develop'
fix(deps): update react monorepo to v18 (major)

See merge request soapbox-pub/soapbox!367
2023-01-10 15:06:54 +00:00
marcin mikołajczak 5131655e94 Merge branch 'icons' into 'develop'
I don't think it makes sense to have SvgIcon and ForkAwesomeIcon in a single component anymore

See merge request soapbox-pub/soapbox!2139
2023-01-10 13:15:07 +00:00
Soapbox Bot 457f866dfa Update dependency node to v18.13.0 2023-01-10 00:12:14 +00:00
Alex Gleason eafc92e275 Merge branch 'renovate/react-redux-8.x' into 'develop'
Update dependency react-redux to v8

See merge request soapbox-pub/soapbox!2082
2023-01-09 23:43:26 +00:00
Alex Gleason 578e30425e
Remove polyfills, delete application.ts 2023-01-09 17:40:29 -06:00
marcin mikołajczak 823cd3124e I don't think it makes sense to have SvgIcon and ForkAwesomeIcon in a single component anymore
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-10 00:11:39 +01:00
Alex Gleason 6f4f402848 Merge branch 'renovate/babel-loader-9.x' into 'develop'
Update dependency babel-loader to v9

See merge request soapbox-pub/soapbox!2063
2023-01-09 22:20:18 +00:00
Alex Gleason fd1c67753c
useDispatch --> useAppDispatch, fix types for react-redux v8 2023-01-09 16:13:12 -06:00
Alex Gleason 8a55f8416b
Remove 'history' dep 2023-01-09 15:43:41 -06:00
Alex Gleason 840be19ff4
Remove Dyslexic mode 2023-01-09 15:04:28 -06:00
Alex Gleason a4fcbb9872
Delete accounts.scss 2023-01-09 14:46:59 -06:00
Chewbacca 197a373401 Add Changelog entry 2023-01-09 12:50:29 -05:00
Chewbacca 0cc684d940 Allow null 2023-01-09 12:49:22 -05:00
Chewbacca cfc03f9a3f Remove 'file-icon' in empty link preview 2023-01-09 12:48:33 -05:00
Chewbacca 63201c4acf Merge branch 'redesign-repost' into 'develop'
Move status info to above Account

See merge request soapbox-pub/soapbox!2120
2023-01-09 17:42:52 +00:00
Chewbacca 52fbd743d1 Lint 2023-01-09 09:03:37 -05:00
Alex Gleason 9275d44bac Merge branch 'release-ci' into 'develop'
Automatically release when tag is pushed to CI

See merge request soapbox-pub/soapbox!2051
2023-01-09 02:53:48 +00:00
Alex Gleason ced6f544d7
Rework releases CI 2023-01-08 20:21:01 -06:00
marcin mikołajczak e46fad211c Merge branch 'translations' into 'develop'
Translations: Support allow_unauthenticated and allow_remote

See merge request soapbox-pub/soapbox!2132
2023-01-08 23:10:28 +00:00
marcin mikołajczak ad1e58c95c Merge branch 'modals-fix' into 'develop'
Fix links in modals

Closes #1240

See merge request soapbox-pub/soapbox!1974
2023-01-08 23:10:04 +00:00
Alex Gleason 039433988f
Merge remote-tracking branch 'origin/develop' into release-ci 2023-01-08 16:32:35 -06:00
marcin mikołajczak 9d0665b092 Translations: Support allow_unauthenticated and allow_remote
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-08 23:04:19 +01:00
Alex Gleason d117e6047b Merge branch 'external-auth-param' into 'develop'
ExternalLoginForm: accept `?server` param to redirect the login form to the specified instance

Closes #1313

See merge request soapbox-pub/soapbox!2131
2023-01-08 21:52:03 +00:00
Alex Gleason df9628c1fd
ExternalLoginForm: accept `?server` param to redirect the login form to the specified instance
Fixes https://gitlab.com/soapbox-pub/soapbox/-/issues/1313
2023-01-08 15:20:24 -06:00
marcin mikołajczak d6be8d08c5 Update changelog
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-08 21:55:34 +01:00
marcin mikołajczak 519c4fb252 Fix 'View context' button
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-08 21:37:20 +01:00
marcin mikołajczak e9a2b65963 Merge remote-tracking branch 'soapbox/develop' into modals-fix 2023-01-08 21:15:03 +01:00
Alex Gleason 7ac41b1bf1
Merge remote-tracking branch 'origin/develop' into renovate/major-react-monorepo 2023-01-07 14:34:06 -06:00
marcin mikołajczak c2e2c59d96 Merge branch 'editing-timeline-insert' into 'develop'
don't insert posts to timelines when editing a post

Closes #1300

See merge request soapbox-pub/soapbox!2128
2023-01-07 16:07:20 +00:00
marcin mikołajczak b290289871 Merge branch 'modals-truncate' into 'develop'
Truncate account names in modals

Closes #1306

See merge request soapbox-pub/soapbox!2129
2023-01-07 16:07:10 +00:00
marcin mikołajczak 9bfccc710d Update changelog
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-07 12:28:44 +01:00
marcin mikołajczak 22de6d28b5 Update changelog
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-07 12:26:56 +01:00
marcin mikołajczak b43ff634e7 Truncate account names in modals
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-07 12:24:18 +01:00
marcin mikołajczak 1c91850181 don't insert posts to timelines when editing a post
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-07 12:01:15 +01:00
Alex Gleason 52278ce519 Merge branch 'roboto-mono' into 'develop'
Fix monospace font in Markdown code blocks

See merge request soapbox-pub/soapbox!2127
2023-01-07 00:12:05 +00:00
Alex Gleason 3bd9be9247
Fix monospace font in Markdown code blocks 2023-01-06 13:24:59 -06:00
Alex Gleason 5083096d1f
ChatPage: useLayoutEffect 2023-01-06 11:51:47 -06:00
Alex Gleason 8730a276c7
Audio/Video: fix initial size with useLayoutEffect for React 18 2023-01-06 11:46:14 -06:00
Alex Gleason dbb745f38d
Fix loading of attachment dimensions for React 18 (useEffect --> useLayoutEffect) 2023-01-06 11:38:36 -06:00
Chewbacca 21c0a79cae Lint 2023-01-06 12:06:18 -05:00
Chewbacca cc0c07851e Refactor to remove unneeded const 2023-01-06 12:05:13 -05:00
Chewbacca d6c9952a8c Move timestamp back to Account 2023-01-06 12:03:57 -05:00
Chewbacca f13ca06569 Use human-readable message from the API as the default 2023-01-06 11:08:38 -05:00
Chewbacca 0a02ba99ed Merge branch 'fix-req-error' into 'develop'
Upgrade Axios to fix "req" error

See merge request soapbox-pub/soapbox!2124
2023-01-06 15:13:48 +00:00
Chewbacca 24f4737a91 Add Changelog entry 2023-01-06 10:01:12 -05:00
Chewbacca 024b161504 Move status info to above Account 2023-01-06 10:01:06 -05:00
Chewbacca 8ec805baad Upgrade axios to fix 'req' undefined error 2023-01-06 09:39:44 -05:00
Chewbacca 26c5214cee Merge branch 'improve-avatar-carousel' into 'develop'
Fix bug with Feed Carousel

See merge request soapbox-pub/soapbox!2113
2023-01-06 13:53:45 +00:00
Alex Gleason e83914482d
Fix useFetchRelationships tests 2023-01-05 18:05:55 -06:00
Alex Gleason edbaf60009
Fix FeedCarousel test 2023-01-05 17:58:01 -06:00
Alex Gleason 1e89efebae
Tests: wrap toast.remove() with act() 2023-01-05 17:45:48 -06:00
Alex Gleason 3fa9cbe211
Fix EmailVerification test 2023-01-05 17:36:02 -06:00
Alex Gleason 83c93a6d51
Fix Registration tests 2023-01-05 17:34:47 -06:00
Alex Gleason b98073ee8f
Fix ReportModal test 2023-01-05 17:32:04 -06:00
Alex Gleason fd542d1796
Fix SmsVerification tests 2023-01-05 17:30:00 -06:00
Alex Gleason bd9bad9a4c
Fix ChatPage tests 2023-01-05 17:22:59 -06:00
Alex Gleason 273266d9ac
useDimensions: don't return null 2023-01-05 16:56:05 -06:00
Alex Gleason 934f354f9c
Merge remote-tracking branch 'origin/renovate/testing-library-react-13.x' into renovate/major-react-monorepo 2023-01-05 16:45:51 -06:00
Alex Gleason 3521e5698f
Switch to React 18's createRoot API
https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html#updates-to-client-rendering-apis
2023-01-05 16:42:18 -06:00
Alex Gleason 85c25903f3
Merge remote-tracking branch 'origin/develop' into renovate/major-react-monorepo 2023-01-05 16:36:49 -06:00
Alex Gleason 7c75e8477f Merge branch 'renovate/uuid-9.x' into 'develop'
Update dependency uuid to v9

See merge request soapbox-pub/soapbox!2087
2023-01-05 22:16:51 +00:00
Alex Gleason 31ba2409be
Jest: remove unneeded moduleNameMapper for uuid 2023-01-05 15:49:11 -06:00
Alex Gleason 5297d8dde3
Remove uuid mock from Jest 2023-01-05 15:48:55 -06:00
Alex Gleason 301bf1d38b Merge branch 'renovate/stylelint-config-standard-29.x' into 'develop'
Update dependency stylelint-config-standard to v29

See merge request soapbox-pub/soapbox!2085
2023-01-05 21:25:56 +00:00
Alex Gleason 3dd1b40cc7
datepicker: fix accidentally removed icon from scss 2023-01-05 15:24:07 -06:00
Chewbacca acb959f680 Merge branch 'fix-carousel-arrows' into 'develop'
Fix button in Carousel

See merge request soapbox-pub/soapbox!2122
2023-01-05 21:23:35 +00:00
Alex Gleason 2abb290b02
Merge remote-tracking branch 'origin/develop' into renovate/stylelint-config-standard-29.x 2023-01-05 14:53:51 -06:00
Alex Gleason 64483d86a3
Conform scss to stylelint 2023-01-05 14:53:23 -06:00
Alex Gleason 106a3a9b6a
stylelint: disable some rules 2023-01-05 14:53:14 -06:00
Alex Gleason 17dbdc3e08
currentColor --> currentcolor 2023-01-05 14:18:58 -06:00
Alex Gleason 5fe5c0a7ba
Use stylelint-config-standard-scss, remove stylelint-config-standard and stylelint-scss 2023-01-05 14:18:12 -06:00
Soapbox Bot 42a6365a0d Update dependency react-redux to v8 2023-01-05 20:15:54 +00:00
Alex Gleason 0e5d7c3610
stylint: disable selector-class-pattern, remove reset.scss 2023-01-05 14:10:07 -06:00
Alex Gleason 6d17323c95 Merge branch 'renovate/eslint-plugin-promise-6.x' into 'develop'
Update dependency eslint-plugin-promise to v6

See merge request soapbox-pub/soapbox!2075
2023-01-05 19:58:29 +00:00
Corné Dorrestijn b325b8933e
Added a options in settings for redirect root no login 2023-01-05 20:52:37 +01:00
Alex Gleason 9557c2cf1b
Merge remote-tracking branch 'origin/develop' into renovate/stylelint-config-standard-29.x 2023-01-05 13:47:03 -06:00
Chewbacca f15988da3c Fix button in Carousel 2023-01-05 14:16:30 -05:00
Alex Gleason ac09ce5c6f Merge branch 'renovate/stylelint-14.x' into 'develop'
Update dependency stylelint to v14

See merge request soapbox-pub/soapbox!2084
2023-01-05 19:05:33 +00:00
Alex Gleason f4477f8ec1 Merge branch 'disable-lockfile-maintenance' into 'develop'
Renovate: disable lockFileMaintenance

See merge request soapbox-pub/soapbox!2121
2023-01-05 19:03:52 +00:00
Alex Gleason 439946f91f Renovate: disable lockFileMaintenance 2023-01-05 19:01:25 +00:00
Soapbox Bot 9b56288e2c Update dependency stylelint-config-standard to v29 2023-01-05 18:46:53 +00:00
Soapbox Bot 4a12a6c0c8 Update dependency stylelint to v14 2023-01-05 18:46:09 +00:00
Alex Gleason d2b4b10e6b Merge branch 'renovate/husky-8.x' into 'develop'
Update dependency husky to v8

See merge request soapbox-pub/soapbox!2078
2023-01-05 18:44:00 +00:00
Alex Gleason 3c71ca928e Merge branch 'renovate/eslint-8.x' into 'develop'
Update dependency eslint to v8

See merge request soapbox-pub/soapbox!2074
2023-01-05 18:39:44 +00:00
Soapbox Bot ceec48a709 Update react monorepo to v18 2023-01-05 18:34:21 +00:00
Soapbox Bot 96e320e478 Update dependency uuid to v9 2023-01-05 18:32:41 +00:00
Soapbox Bot 9f88415300 Update dependency husky to v8 2023-01-05 18:22:40 +00:00
Soapbox Bot 6e77bcdaae Update dependency eslint-plugin-promise to v6 2023-01-05 18:21:00 +00:00
Soapbox Bot 0b5162b29b Update dependency babel-loader to v9 2023-01-05 18:19:29 +00:00
Soapbox Bot c87bd2b2e7 Update dependency @testing-library/react to v13 2023-01-05 18:18:42 +00:00
Alex Gleason 725be075d9
ServiceWorker: console.error on empty push event 2023-01-05 12:11:04 -06:00
Alex Gleason 7a14d56f9f
ServiceWorker: drop empty push events 2023-01-05 11:57:44 -06:00
Alex Gleason 35c916293e
yarn lint:js --fix 2023-01-05 11:55:08 -06:00
Alex Gleason e8ead6e960
babel-eslint --> @babel/eslint-parser 2023-01-05 11:54:20 -06:00
Alex Gleason bce33db154
Merge remote-tracking branch 'origin/develop' into renovate/eslint-8.x 2023-01-05 11:48:29 -06:00
Alex Gleason 82e36c1f30 Merge branch 'events' into 'develop'
Fix events location search crash

Closes #1308

See merge request soapbox-pub/soapbox!2117
2023-01-05 16:28:47 +00:00
Alex Gleason 8036afc6bb
CHANGELOG: fix events crash 2023-01-05 10:20:57 -06:00
marcin mikołajczak 91cdf1eb5a Fix events location search crash
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-05 17:14:18 +01:00
marcin mikołajczak 1412385382 Merge branch 'takahe-features' into 'develop'
Update features.ts for Takahē

See merge request soapbox-pub/soapbox!2116
2023-01-03 23:02:50 +00:00
marcin mikołajczak c6e5f746da Update features.ts for Takahē
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-03 23:42:15 +01:00
marcin mikołajczak 02509cb40d Merge branch 'cleanup' into 'develop'
TSX, functional, remove unused styles

See merge request soapbox-pub/soapbox!2040
2023-01-03 21:35:06 +00:00
Alex Gleason ccf3ac31c4 Merge branch 'renovate/stylelint-scss-4.x' into 'develop'
Update dependency stylelint-scss to v4

See merge request soapbox-pub/soapbox!2086
2023-01-03 20:58:55 +00:00
Alex Gleason 683d82937c Merge branch 'renovate/blurhash-2.x' into 'develop'
fix(deps): update dependency blurhash to v2

See merge request soapbox-pub/soapbox!2065
2023-01-03 20:52:20 +00:00
Alex Gleason e001914222 Merge branch 'renovate/metamask-providers-10.x' into 'develop'
Update dependency @metamask/providers to v10

See merge request soapbox-pub/soapbox!2061
2023-01-03 20:52:01 +00:00
Alex Gleason 8b993e1c98 Merge branch 'renovate/dotenv-16.x' into 'develop'
Update dependency dotenv to v16

See merge request soapbox-pub/soapbox!2071
2023-01-03 20:50:52 +00:00
marcin mikołajczak 08a47bed5d Merge remote-tracking branch 'soapbox/develop' into cleanup
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-03 21:09:43 +01:00
Soapbox Bot ae3e122cbb Update dependency stylelint-scss to v4 2023-01-03 18:14:47 +00:00
Soapbox Bot 530a02a22b Update dependency eslint to v8 2023-01-03 18:11:28 +00:00
Chewbacca 0a4d113d50 Fix bug with Feed Carousel 2023-01-03 12:12:50 -05:00
Alex Gleason a700461cbf Merge branch 'renovate/docker-20.x' into 'develop'
Update docker Docker tag to v20.10.22

See merge request soapbox-pub/soapbox!2058
2023-01-03 16:06:05 +00:00
Alex Gleason 4b466b348d Merge branch 'renovate/node-18.x' into 'develop'
Update dependency node to v18.12.1

See merge request soapbox-pub/soapbox!2059
2023-01-03 16:04:38 +00:00
Alex Gleason b655456b6e Merge branch 'renovate/major-jest-monorepo' into 'develop'
Update jest monorepo to v29 (major)

See merge request soapbox-pub/soapbox!2090
2023-01-03 15:55:57 +00:00
Chewbacca daf395009b Merge branch 'improve-avatar-carousel' into 'develop'
Improve UI/UX of the Feed Carousel

See merge request soapbox-pub/soapbox!2112
2023-01-03 15:13:07 +00:00
Chewbacca 189423b415 Improve UI/UX of the Feed Carousel 2023-01-03 09:22:26 -05:00
Alex Gleason 833801cbd2 Merge branch 'enable-hmr' into 'develop'
Webpack: enable hot module replacement (HMR)

See merge request soapbox-pub/soapbox!2102
2023-01-02 18:55:13 +00:00
Alex Gleason 92942fe52d Merge branch 'image-preview-i18n' into 'develop'
Add missing locale strings from mediaPreview settings

See merge request soapbox-pub/soapbox!2111
2023-01-02 18:16:42 +00:00
Alex Gleason 8b2889b4af
Add missing locale strings from mediaPreview settings
Whoops https://gitlab.com/soapbox-pub/soapbox/-/merge_requests/2110
2023-01-02 12:15:45 -06:00
Alex Gleason bd708a5121 Merge branch 'fix/image-previews' into 'develop'
Fix images in timelines not using the preview URL which can leverage Pleroma Media Preview Proxy

See merge request soapbox-pub/soapbox!2110
2023-01-02 17:58:37 +00:00
Alex Gleason 5c9c75e2d7
CHANGELOG: media preview configuration 2023-01-02 11:53:50 -06:00
Alex Gleason 444754e1c8
Merge remote-tracking branch 'origin/develop' into fix/image-previews 2023-01-02 11:52:18 -06:00
Alex Gleason 02188118e7
Let media preview be configurable 2023-01-02 11:52:05 -06:00
Mark Felder 6b56e72f24 Fix images in timelines not using the preview URL which can leverage Pleroma Media Preview Proxy 2023-01-02 12:20:53 -05:00
marcin mikołajczak 690621e0a3 Merge remote-tracking branch 'soapbox/develop' into cleanup 2023-01-02 17:49:02 +01:00
Soapbox Bot a9e013b525 Update jest monorepo to v29 2023-01-02 16:09:56 +00:00
Alex Gleason 4f817a0645 Merge branch 'remove-entities' into 'develop'
Remove 'entities' dep

See merge request soapbox-pub/soapbox!2105
2023-01-02 14:41:30 +00:00
Alex Gleason 55a240a697 Merge branch 'modal-blur' into 'develop'
Add backdrop-blur behind modals

See merge request soapbox-pub/soapbox!2101
2023-01-02 14:39:07 +00:00
marcin mikołajczak 3491d09485 Fix test
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-02 10:35:37 +01:00
marcin mikołajczak 48010e6aa8 Merge branch 'scheduled-posts' into 'develop'
Scheduled posts fixes and improvements

See merge request soapbox-pub/soapbox!2106
2023-01-01 23:46:57 +00:00
marcin mikołajczak 135b3c7ade Update file CHANGELOG.md 2023-01-01 23:31:31 +00:00
marcin mikołajczak 0001ea47df Set scheduled post date to 10 minutes after current time
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-01 23:50:55 +01:00
marcin mikołajczak c7e140bf3f Append scheduled statuses to status list
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-01 23:46:47 +01:00
marcin mikołajczak ea2bb53379 Fix scheduled statuses page crashing on delete
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2023-01-01 23:21:05 +01:00
Alex Gleason 90479e0bca
Remove 'entities' dep 2023-01-01 00:53:34 -06:00
Alex Gleason b31c5ff06c
Jest: transform blurhash with babel 2023-01-01 00:46:52 -06:00
Alex Gleason fdf4abd10f
Merge remote-tracking branch 'origin/develop' into renovate/blurhash-2.x 2023-01-01 00:45:05 -06:00
Alex Gleason 393928a5c7 Merge branch 'fix-datepicker' into 'develop'
Datepicker: correctly default to the current year

See merge request soapbox-pub/soapbox!2104
2023-01-01 06:28:06 +00:00
Alex Gleason 1f616c0a44
Datepicker: correctly default to the current year 2023-01-01 00:27:06 -06:00
Alex Gleason d842c187fb Merge branch 'default-branch-fix' into 'develop'
GitLab CI: fix default branch rules

See merge request soapbox-pub/soapbox!2103
2023-01-01 06:17:17 +00:00
Alex Gleason 675f599072
GitLab CI: fix default branch rules 2022-12-31 20:50:05 -06:00
marcin mikołajczak 1cc0b16274 Merge remote-tracking branch 'soapbox/cleanup' into cleanup 2022-12-31 19:52:20 +01:00
marcin mikołajczak 03349abc37 Merge remote-tracking branch 'soapbox/develop' into cleanup 2022-12-31 19:52:03 +01:00
marcin mikołajczak 674ffed6a5 These params should never be null, actually
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-31 19:48:31 +01:00
marcin mikołajczak cbd06926f3 Restore removed styles
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-31 19:40:23 +01:00
Alex Gleason 6f04097cb0
yarn manage:translations en 2022-12-31 11:32:09 -06:00
Chewbacca 2bc620016e Merge branch 'fix-responsive-form' into 'develop'
Fix responsive nature of Select component

See merge request soapbox-pub/soapbox!2048
2022-12-31 17:10:02 +00:00
Alex Gleason 58b7d7607c
Merge remote-tracking branch 'origin/develop' into cleanup 2022-12-31 11:05:21 -06:00
marcin mikołajczak 3cab6436e0 Remove feather-icons
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-31 16:08:23 +01:00
Alex Gleason e1e70c6715
Webpack: only load react-refresh/babel in development 2022-12-30 19:13:58 -06:00
Alex Gleason 2ddd3ef2ac
Webpack: enable hot module replacement (HMR) 2022-12-30 18:53:21 -06:00
Alex Gleason 2808773a80
Add backdrop-blur behind modals 2022-12-30 17:29:04 -06:00
marcin mikołajczak e167ec8b6e Mark some strings as translatable
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-30 22:49:29 +01:00
marcin mikołajczak 925087024c back to use AccountContainer in Notification component
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-30 22:43:58 +01:00
marcin mikołajczak b4601d13cf ok, this works
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-30 22:25:03 +01:00
Soapbox Bot 5c262f79ad fix(deps): update dependency blurhash to v2 2022-12-30 21:17:00 +00:00
Alex Gleason 6034864199 Merge branch 'remove-jsdoc' into 'develop'
Remove JSDoc, upgrade json5

See merge request soapbox-pub/soapbox!2100
2022-12-30 21:02:47 +00:00
Alex Gleason 9d79d1c14b
Upgrade json5 to patched version 2022-12-30 14:02:53 -06:00
Alex Gleason 4d4bca1a6a
Remove JSDoc 2022-12-30 13:51:00 -06:00
Alex Gleason eaf062996e Merge branch 'remove-postcss-object-fit-images' into 'develop'
Remove object-fit-images

See merge request soapbox-pub/soapbox!2099
2022-12-30 19:49:23 +00:00
Alex Gleason 2737d41019
Remove object-fit-images 2022-12-30 12:32:53 -06:00
Alex Gleason 3dee22a3ff
Remove postcss-object-fit-images 2022-12-30 12:13:53 -06:00
Alex Gleason 1697eb7f32 Merge branch 'ci-default-branch' into 'develop'
GitLab CI: use $CI_DEFAULT_BRANCH, don't run danger on develop

See merge request soapbox-pub/soapbox!2097
2022-12-30 17:56:48 +00:00
Alex Gleason a8ff985135 Merge branch 'schema' into 'develop'
vscode autocompletion improvements, make renovate not rebase so often

See merge request soapbox-pub/soapbox!2096
2022-12-30 17:56:31 +00:00
Alex Gleason 7c46c8da52
GitLab CI: make jobs interruptible by default 2022-12-30 11:39:08 -06:00
Alex Gleason 178c41b3c3
Danger: don't run on develop 2022-12-30 11:26:16 -06:00
Alex Gleason 803b09f970
GitLab CI: fix before_script type 2022-12-30 11:25:18 -06:00
Alex Gleason 1d31ac01aa
GitLab CI: use $CI_DEFAULT_BRANCH 2022-12-30 11:23:44 -06:00
Alex Gleason ef82876522
renovate: rebase only on conflict 2022-12-30 11:08:49 -06:00
Alex Gleason bd923d4ba2
vscode: add schemas to renovate.json, .lintstagedrc.json 2022-12-30 11:08:24 -06:00
Alex Gleason bdde3f4fe8
vscode: recommend `redhat.vscode-yaml` extension 2022-12-30 11:07:57 -06:00
Alex Gleason a49d37df6e Merge branch 'audit-fix' into 'develop'
npx yarn-audit-fix

See merge request soapbox-pub/soapbox!2093
2022-12-30 17:06:29 +00:00
Alex Gleason 8370e40361 Merge branch 'browserlist' into 'develop'
npx browserslist@latest --update-db

See merge request soapbox-pub/soapbox!2095
2022-12-30 17:06:20 +00:00
Alex Gleason f19e3fb21d Merge branch 'include-interruptible' into 'develop'
GitLab CI: let included jobs be interrupted

See merge request soapbox-pub/soapbox!2094
2022-12-30 16:47:05 +00:00
Alex Gleason c5874ce44b
npx browserslist@latest --update-db 2022-12-30 10:26:14 -06:00
Alex Gleason 337fa4895b
GitLab CI: let included jobs be interrupted 2022-12-30 10:23:48 -06:00
Alex Gleason 85f2294bc6
Force loader-utils ^2.0.3 2022-12-30 10:13:59 -06:00
Alex Gleason b04d102a8e
Add `yarn audit:fix` command 2022-12-30 10:10:13 -06:00
Alex Gleason 3de548d522
npx yarn-audit-fix
https://dev.to/antongolub/yarn-audit-fix-workaround-i2a
2022-12-30 10:07:14 -06:00
Alex Gleason 51e23c0177 Merge branch 'renovate/jest-junit-15.x' into 'develop'
Update dependency jest-junit to v15

See merge request soapbox-pub/soapbox!2079
2022-12-30 15:16:53 +00:00
Alex Gleason 50dfce7aca Merge branch 'renovate/jsdoc-4.x' into 'develop'
Update dependency jsdoc to v4

See merge request soapbox-pub/soapbox!2080
2022-12-30 15:10:53 +00:00
Alex Gleason e3347a0b5e Merge branch 'renovate/webpack-cli-5.x' into 'develop'
Update dependency webpack-cli to v5

See merge request soapbox-pub/soapbox!2088
2022-12-30 15:05:41 +00:00
Alex Gleason 581006f6b8 Merge branch 'renovate/fake-indexeddb-4.x' into 'develop'
Update dependency fake-indexeddb to v4

See merge request soapbox-pub/soapbox!2076
2022-12-30 15:00:33 +00:00
Soapbox Bot a094984847 Update dependency webpack-cli to v5 2022-12-30 02:46:07 +00:00
Soapbox Bot aa48cd2bae Update dependency jsdoc to v4 2022-12-30 02:34:05 +00:00
Soapbox Bot fe3654a8aa Update dependency jest-junit to v15 2022-12-30 02:33:12 +00:00
Soapbox Bot bc1a05d42c Update dependency fake-indexeddb to v4 2022-12-30 02:24:45 +00:00
Soapbox Bot fb7487c759 Update dependency dotenv to v16 2022-12-30 02:20:53 +00:00
Soapbox Bot 28e15bdfe8 Update dependency @metamask/providers to v10 2022-12-30 02:16:06 +00:00
Soapbox Bot bbfd0ee170 Update dependency node to v18.12.1 2022-12-30 02:12:28 +00:00
Soapbox Bot d16cd7b993 Update docker Docker tag to v20.10.22 2022-12-30 02:12:22 +00:00
Alex Gleason 6afdb4f4b2 Merge branch 'renovate/emoji-datasource-5.x' into 'develop'
Update dependency emoji-datasource to v5.0.1

See merge request soapbox-pub/soapbox!2056
2022-12-30 01:58:34 +00:00
Alex Gleason b718a3d50a Merge branch 'renovate/react-motion-0.x' into 'develop'
Update dependency @types/react-motion to ^0.0.33

See merge request soapbox-pub/soapbox!2055
2022-12-30 01:46:49 +00:00
Soapbox Bot fbb591a15f Update dependency emoji-datasource to v5.0.1 2022-12-30 01:26:34 +00:00
Soapbox Bot e4a15367c1 Update dependency @types/react-motion to ^0.0.33 2022-12-30 01:26:08 +00:00
Alex Gleason a8f05c2bb9 Merge branch 'i18n-ci' into 'develop'
GitLab CI: fail the CI if en.json isn't updated with the codebase

See merge request soapbox-pub/soapbox!2053
2022-12-30 00:22:02 +00:00
Alex Gleason 91ad155fcb Merge branch 'license-scanning' into 'develop'
GitLab CI: add license scanning

See merge request soapbox-pub/soapbox!2068
2022-12-29 22:51:22 +00:00
Alex Gleason f50379bdbd Merge branch 'revert-622b90da' into 'develop'
Revert "Merge branch 'square' into 'develop'"

Closes #1284

See merge request soapbox-pub/soapbox!2070
2022-12-29 22:37:50 +00:00
Alex Gleason 2a008c0b5e
CHANGELOG: letterboxing changes 2022-12-29 16:27:08 -06:00
Alex Gleason f20a8ab6fe Revert "Merge branch 'square' into 'develop'"
This reverts merge request !2027
2022-12-29 22:23:27 +00:00
Corné Dorrestijn 41b3d409fd
Allow configuration from root URL path 2022-12-29 18:05:44 +01:00
Chewbacca 2495dd2b9e Merge branch 'fix-req-error' into 'develop'
Fix 'req not defined' error

See merge request soapbox-pub/soapbox!2067
2022-12-29 15:58:56 +00:00
Alex Gleason edc5ce6b12
GitLab CI: add license scanning 2022-12-29 09:49:39 -06:00
Chewbacca 7b5f61503f Fix test 2022-12-29 10:39:43 -05:00
Chewbacca 970cd60c84 Merge branch 'fix-sidebar-close-button' into 'develop'
Sidebar improvements

See merge request soapbox-pub/soapbox!2047
2022-12-29 15:22:57 +00:00
Chewbacca 92e94ae4a5 Merge branch 'fix-undefined-bug' into 'develop'
Fix undefined bug with MediaModal

See merge request soapbox-pub/soapbox!2066
2022-12-29 15:17:35 +00:00
marcin mikołajczak 191cf7e19a Merge branch 'chats-query' into 'develop'
Do not make requests to chats endpoint from profile page if chats are not supported

See merge request soapbox-pub/soapbox!2046
2022-12-29 14:59:01 +00:00
Chewbacca 5e7093d3a2 Merge branch 'update-lock-file' into 'develop'
Ensure Renovate updates the Yarn.lock file

See merge request soapbox-pub/soapbox!2064
2022-12-29 14:54:40 +00:00
Chewbacca e6dbb4d19f Lint 2022-12-29 09:53:55 -05:00
Chewbacca 4ea1562185 Fix 'req not defined' error 2022-12-29 09:51:48 -05:00
Chewbacca e1e5051951 Fix undefined bug with MediaModal 2022-12-29 09:17:19 -05:00
Chewbacca 1b7fec2fec Merge branch 'add-before-after-template' into 'develop'
Add template for easy before/after screenshots

See merge request soapbox-pub/soapbox!2049
2022-12-29 13:53:59 +00:00
Chewbacca 173d31ad99 Ensure Renovate updates the Yarn.lock file 2022-12-29 08:53:16 -05:00
marcin mikołajczak b6bd46d417 Do not make requests to chats endpoint from profile page if chats are not supported
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-29 14:33:50 +01:00
marcin mikołajczak 7d3ad8ac33 remove unused styles
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-29 14:13:10 +01:00
Alex Gleason 4ce46ec83a Merge branch 'alexgleason-develop-patch-78475' into 'develop'
renovate.json: delete github access token

See merge request soapbox-pub/soapbox!2057
2022-12-29 07:43:58 +00:00
Alex Gleason 8e2d530a26 renovate.json: delete github access token 2022-12-29 07:43:15 +00:00
Alex Gleason 3093a4659c Merge branch 'deps-scan' into 'develop'
GitLab CI: enable dependency scanning

See merge request soapbox-pub/soapbox!2054
2022-12-29 06:38:10 +00:00
Alex Gleason a97278c5f0
Delete defaultMessages.json 2022-12-29 00:35:09 -06:00
Alex Gleason 5c449bdb16
yarn manage:translations en 2022-12-29 00:34:25 -06:00
Alex Gleason 1e03349cc0
Move i18n into build job 2022-12-29 00:17:29 -06:00
Alex Gleason 8567cd91fc
GitLab CI: enable dependency scanning 2022-12-29 00:04:02 -06:00
Alex Gleason 1af36da927
GitLab CI: fail the CI if en.json isn't updated with the codebase 2022-12-28 23:47:17 -06:00
Alex Gleason 73315e4095
trnaslationRunner: import yargs 2022-12-28 23:21:28 -06:00
Alex Gleason 141241ab2c
Upgrade yargs to 17.x 2022-12-28 23:21:13 -06:00
Alex Gleason 0540b627e1
Move translationRunner under scripts/ 2022-12-28 22:59:39 -06:00
Alex Gleason 3f95b131c1 Merge branch 'chg-update' into 'develop'
CHANGELOG: add Takahē, sw.js whitelist

See merge request soapbox-pub/soapbox!2052
2022-12-29 02:31:08 +00:00
Alex Gleason dc1a5c7189
CHANGELOG: add Takahē, sw.js whitelist 2022-12-28 20:30:24 -06:00
Alex Gleason 44901a5e3e
Automatically release when tag is pushed to CI 2022-12-28 19:51:28 -06:00
Alex Gleason fe1135eb9c
Add changelog script 2022-12-28 19:38:19 -06:00
Chewbacca 637e32c810 Add template for easy before/after screenshots 2022-12-28 11:53:09 -05:00
Chewbacca 515c67d011 Add 'truncate' class to Select 2022-12-28 11:48:16 -05:00
Chewbacca 9e321ac4c4 Refactor sidebar to fix position of close (X) icon 2022-12-28 11:26:58 -05:00
Alex Gleason e77c309e8a Merge branch 'fab-accent' into 'develop'
Use accent color for "floating action button" (mobile compose button).

See merge request soapbox-pub/soapbox!2044
2022-12-28 03:41:48 +00:00
Alex Gleason 85bc891dbb
Use accent color for "floating action button" (mobile compose button). 2022-12-27 21:40:39 -06:00
marcin mikołajczak 5c5bfccea6 Merge branch 'takahe' into 'develop'
Support Takahē

See merge request soapbox-pub/soapbox!2043
2022-12-27 23:18:16 +00:00
marcin mikołajczak 3f430ee5d5 use capitalized name
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-27 23:56:33 +01:00
marcin mikołajczak 81e1e2d6ad Support Takahē
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-27 21:43:13 +01:00
marcin mikołajczak 8d95a4040b Merge remote-tracking branch 'soapbox/develop' into cleanup 2022-12-27 21:13:06 +01:00
marcin mikołajczak d70827d481 restore style
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-27 21:13:02 +01:00
Alex Gleason 35d9863f42 Merge branch 'sw-favicon' into 'develop'
Don't serve favicon.png with ServiceWorker

See merge request soapbox-pub/soapbox!2042
2022-12-27 17:55:14 +00:00
Alex Gleason 6d46abadc1
Don't serve favicon.png with ServiceWorker 2022-12-27 11:41:41 -06:00
Chewbacca 5c8cc86b9e Merge branch 'pin-avatar' into 'develop'
Add support for pinning an avatar in the Carousel

See merge request soapbox-pub/soapbox!2024
2022-12-27 15:37:38 +00:00
marcin mikołajczak af2d0749a1 Remove legacy avatar component, convert AccountContainer to TS/FC
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-27 12:29:01 +01:00
marcin mikołajczak a990b859ef Remove unused styles
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-26 17:50:03 +01:00
marcin mikołajczak 82d3e3c5f4 Remove unused styles
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-26 17:34:55 +01:00
marcin mikołajczak 6316da5332 fix auth state persistence
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-26 14:32:58 +01:00
marcin mikołajczak a7653403e7 Update immutable-js, fix tests, fix reducers/auth
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-26 14:09:09 +01:00
Alex Gleason 4a44085a1a Merge branch 'sb_backend_route_fixes' into 'develop'
Add additional backend URIs.

See merge request soapbox-pub/soapbox!2039
2022-12-26 02:01:56 +00:00
Ryle b314bb7af1
Add additional backend URIs. /images is used by manifest.json, /favicon.ico is used by browsers to set favicons, but some bug out for bookmarks if this isn't route excepted, /apple-touch-icon.png is the default iOS/iPad file for specifying icons, /browserconfig.xml is used by Windows for metro tiles for added pages, /robots.txt is used by bots to determine if access is permitted to pages. Some bots that use Selenium break when the routing isn't exempt. 2022-12-26 01:36:13 +00:00
marcin mikołajczak d1071a109b Remove unused styles/components
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-26 00:52:06 +01:00
marcin mikołajczak 4b3f03353d WIP TypeScript convertions
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-26 00:31:07 +01:00
Alex Gleason f635d71350 Merge branch 'post-3.0' into 'develop'
Prepare for 3.1.x

See merge request soapbox-pub/soapbox!2038
2022-12-25 14:43:12 +00:00
Alex Gleason d1223e4874
Prepare for 3.1.x 2022-12-25 08:16:04 -06:00
Alex Gleason a37a2d7fff Merge branch 'soapbox-3.0' into 'develop'
Prepare for v3.0.0

See merge request soapbox-pub/soapbox!2037
2022-12-25 14:07:49 +00:00
marcin mikołajczak c692265249 Convert (legacy?) IconButton to tsx, remove unused code/styles
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-25 13:51:11 +01:00
Alex Gleason 70f7c4ea5d
Prepare for v3.0.0 2022-12-24 17:04:29 -06:00
Alex Gleason 27ad8dee64 Merge branch 'events-features' into 'develop'
Gate events with `features.includes('events')`

See merge request soapbox-pub/soapbox!2036
2022-12-24 20:44:58 +00:00
Alex Gleason 6ac5845deb
Gate events with `features.includes('events')` 2022-12-24 14:42:43 -06:00
Alex Gleason eb4e4c4341 Merge branch 'rtl-mentions' into 'develop'
Fix mentions in RTL

See merge request soapbox-pub/soapbox!2033
2022-12-23 23:48:31 +00:00
Alex Gleason fa1d7937a7
Fix mentions in RTL 2022-12-23 17:34:14 -06:00
Alex Gleason b88026df5e Merge branch 'threads-rtl' into 'develop'
Fix threads in RTL (and other small fixes)

See merge request soapbox-pub/soapbox!2032
2022-12-23 22:49:02 +00:00
Alex Gleason f174d0e973
Merge remote-tracking branch 'origin/develop' into threads-rtl 2022-12-23 16:33:30 -06:00
Alex Gleason c788916644
AutosuggestInput/AutosuggestTextarea: short-circuit RTL check earlier 2022-12-23 16:26:07 -06:00
Alex Gleason 8fde7f267d
Search: prevent overflow of text into icon 2022-12-23 16:24:04 -06:00
Alex Gleason bedd181f4c
AutosuggestInput/AutosuggestTextarea: fix RTL detection with placeholder 2022-12-23 16:14:50 -06:00
Alex Gleason c4270a0512
Revert "AutosuggestInput/AutosuggestTextarea: actually, just remove RTL checking. The browser should handle it"
This reverts commit ee9908aab2.
2022-12-23 16:11:30 -06:00
Alex Gleason 89292203d1 Merge branch 'fab-rtl' into 'develop'
Refactor ComposeButton and FAB

See merge request soapbox-pub/soapbox!2031
2022-12-23 22:04:04 +00:00
Alex Gleason ea70f48023
Navbar: fix position of avatar in RTL on mobile 2022-12-23 16:02:39 -06:00
Alex Gleason 78a9dc519c
Status: fix reblogElement in RTL 2022-12-23 16:01:12 -06:00
Alex Gleason 59cf263960
SidebarMenu: fix RTL 2022-12-23 15:55:17 -06:00
Alex Gleason dfe5079058
StatusActionButton: fix spacing in RTL 2022-12-23 15:48:07 -06:00
Alex Gleason d4b5c368f8
Fix threads in RTL 2022-12-23 15:46:24 -06:00
Alex Gleason 01d7aa6307
Move FAB to the left in RTL 2022-12-23 15:37:45 -06:00
Alex Gleason ab7ec4babd
Refactor ComposeButton, FAB, and sidebar nav spacing 2022-12-23 15:22:41 -06:00
Alex Gleason 7a6126b978
Move FloatingActionButton to its own component 2022-12-23 14:57:16 -06:00
Alex Gleason 472af420c0 Merge branch 'feed-settings' into 'develop'
Make all timelines use "home" timeline settings

Closes #1230

See merge request soapbox-pub/soapbox!2030
2022-12-23 19:23:30 +00:00
Alex Gleason a4615296e8
Make all timelines use "home" timeline settings
Fixes https://gitlab.com/soapbox-pub/soapbox/-/issues/1230
2022-12-23 12:21:28 -06:00
Alex Gleason b2676dec0d Merge branch 'rtl-improvements' into 'develop'
RTL improvments

Closes #1246

See merge request soapbox-pub/soapbox!2028
2022-12-23 18:07:50 +00:00
Alex Gleason ee9908aab2
AutosuggestInput/AutosuggestTextarea: actually, just remove RTL checking. The browser should handle it 2022-12-23 11:38:42 -06:00
Alex Gleason 95f7761fb4
Toast: remove unnecessary outer div 2022-12-23 11:33:10 -06:00
Alex Gleason 69328ade8b
Toast: use HStack, RTL support 2022-12-23 11:31:53 -06:00
Alex Gleason 140c0b3037
AutosuggestInput/AutosuggestTextarea: determine RTL by placeholder value as well (hotfix) 2022-12-23 11:18:23 -06:00
Alex Gleason 058a75deec
useLocale(): refactor to return direction 2022-12-23 11:12:48 -06:00
Alex Gleason 87728876d3
RTL: fix "x" in birthday input 2022-12-23 10:51:50 -06:00
Alex Gleason 6dc16911f3 Merge branch 'rtl-arrows' into 'develop'
Rotate arrows for RTL

See merge request soapbox-pub/soapbox!1977
2022-12-23 16:31:17 +00:00
Alex Gleason 622b90daee Merge branch 'square' into 'develop'
Letterbox images taller than 1:1

See merge request soapbox-pub/soapbox!2027
2022-12-23 16:26:59 +00:00
Alex Gleason 0356b014b0
Letterbox images taller than 1:1 2022-12-22 21:06:27 -06:00
Alex Gleason 4b0e154af6 Merge branch 'readme-changelog' into 'develop'
Small changelog & readme additions

See merge request soapbox-pub/soapbox!2026
2022-12-23 00:34:41 +00:00
Alex Gleason 2ca1b464c6
README: add TMTG 2022-12-22 18:32:55 -06:00
Alex Gleason a31bac6489
CHANGELOG: add timeline suggestions 2022-12-22 18:17:14 -06:00
Alex Gleason e67589a109 Merge branch 'max-id-undefined' into 'develop'
Timelines: prevent max_id=undefined in home timeline requests

See merge request soapbox-pub/soapbox!2025
2022-12-22 23:05:35 +00:00
Alex Gleason 622df27e41
Timelines: prevent max_id=undefined in home timeline requests 2022-12-22 16:38:20 -06:00
marcin mikołajczak c792cc2549 Do not include link to profile in ReplyMentionsModal
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-22 19:58:20 +01:00
marcin mikołajczak bcf82e4312 Merge remote-tracking branch 'soapbox/develop' into modals-fix 2022-12-22 19:52:40 +01:00
Chewbacca 51146574d4 Fix tests 2022-12-22 12:02:17 -05:00
Chewbacca b6afb8ae01 Add support for pinning an avatar in the Carousel 2022-12-22 11:23:18 -05:00
marcin mikołajczak dba963a6ce styles cleanup
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-21 21:01:57 +01:00
Chewbacca a9e05859d1 Merge branch 'improve-toasts' into 'develop'
Introduce Toast module as Snackbar replacement

See merge request soapbox-pub/soapbox!2023
2022-12-21 19:47:35 +00:00
Chewbacca 8d28c37a7f Merge branch 'tab-continuation' into 'develop'
Allow tab continuation on Email confirmation

See merge request soapbox-pub/soapbox!1847
2022-12-21 19:26:52 +00:00
Chewbacca e3026f16cc Add Changelog entry 2022-12-21 14:15:56 -05:00
Chewbacca a3c7164147 Move Toast to components/ui 2022-12-21 14:14:31 -05:00
Chewbacca c4e56e854d Remove 'react-notification' 2022-12-21 14:04:03 -05:00
marcin mikołajczak 8c81040aec Remove unused variables
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-21 13:15:32 +01:00
marcin mikołajczak bd247797bb Merge remote-tracking branch 'soapbox/develop' into mastodon-groups
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-21 13:02:19 +01:00
marcin mikołajczak 23b1052a1d Remove unused styles
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-21 13:01:34 +01:00
Chewbacca 90fcc8ad05 Fix tests 2022-12-20 17:45:29 -05:00
Chewbacca 3dceaacc16 Improve UI of toast 2022-12-20 17:12:17 -05:00
Chewbacca bffe5318a9 Fix tests 2022-12-20 13:14:38 -05:00
Chewbacca f504d17abe Remove usage of 'snackbar' 2022-12-20 12:46:06 -05:00
Chewbacca 3c38a57560 Convert 'show' usage to Toast 2022-12-20 12:46:06 -05:00
Chewbacca 642d1d8b3e Convert 'info' usage to Toast 2022-12-20 12:46:06 -05:00
Chewbacca b348ca71b9 Convert 'error' usage to Toast 2022-12-20 12:46:06 -05:00
Chewbacca b7d0b4abe8 Convert 'success' usage to Toast 2022-12-20 12:46:06 -05:00
Chewbacca 01eccc897b Introduce new Toast module 2022-12-20 12:46:03 -05:00
Chewbacca 778b63ab56 Merge branch 'fix-scroll-issue-on-mobile' into 'develop'
Fix overflow issue on mobile

See merge request soapbox-pub/soapbox!2021
2022-12-19 16:50:28 +00:00
Chewbacca 397d79f73f Fix overflow issue on mobile 2022-12-19 10:33:37 -05:00
marcin mikołajczak 0879222aa2 Improve permissions check
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-19 14:10:13 +01:00
Alex Gleason 6b5c214b9a Merge branch 'dm-fixes' into 'develop'
Small chats fixes

Closes #1258

See merge request soapbox-pub/soapbox!2018
2022-12-19 00:04:32 +00:00
Alex Gleason 3db7dfd038 Merge branch 'mkljczk-develop-patch-90203' into 'develop'
Remove my instance from README.md

See merge request soapbox-pub/soapbox!2020
2022-12-18 23:52:14 +00:00
marcin mikołajczak 70ba701a5d Remove my instance from the list 2022-12-18 23:45:15 +00:00
Alex Gleason 186b1d0daf Merge branch 'overhaul-readme' into 'develop'
Overhaul README

See merge request soapbox-pub/soapbox!2019
2022-12-18 23:15:59 +00:00
Alex Gleason 6825082475
README: clean up copyright, move sounds licenses to a separate file 2022-12-18 17:14:34 -06:00
Alex Gleason c64b7d8ba9
Overhaul README 2022-12-18 17:03:11 -06:00
marcin mikołajczak fa18698cd3 Groups: Status action bar actions
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-18 21:19:44 +01:00
Alex Gleason 34ae2e36d6 Merge branch 'demo' into 'develop'
Fix demo mode

See merge request soapbox-pub/soapbox!2017
2022-12-18 19:00:46 +00:00
Alex Gleason 26cb4b1029
Hide button to chat with yourself
Fixes https://gitlab.com/soapbox-pub/soapbox/-/issues/1258
2022-12-18 12:58:19 -06:00
Alex Gleason f955691d01
Settings: Messages --> Chats, reword follow criteria 2022-12-18 12:56:35 -06:00
Alex Gleason 1334241873
CHANGELOG: add i18n notes 2022-12-18 12:37:07 -06:00
Alex Gleason 1c71989432
CHANGELOG: mention RTL support 2022-12-18 12:31:45 -06:00
Alex Gleason fed6a7aa51
Fix demo mode 2022-12-18 12:29:31 -06:00
marcin mikołajczak 3fab582627 List groups-related endpoints
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-18 18:26:22 +01:00
marcin mikołajczak f6f056e0fe Support Mastodon permissions system(?)
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-18 18:18:26 +01:00
marcin mikołajczak 6b92d5f3a5 Manage group pages
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-18 18:03:41 +01:00
marcin mikołajczak 18b297ad63 Improve media panel styles
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-18 13:34:03 +01:00
marcin mikołajczak 96d39a9d1a Groups: Hide ComposeForm if not a member, add Media panel
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-18 13:17:45 +01:00
Alex Gleason 493d608076 Merge branch 'theme-editor' into 'develop'
Theme editor

See merge request soapbox-pub/soapbox!1895
2022-12-18 05:37:26 +00:00
Alex Gleason fa73c8ebc9
changelog: theme editor 2022-12-17 23:18:19 -06:00
Alex Gleason 34ebe9bd57
ThemeEditor: improve layout, improve color of slider 2022-12-17 21:25:20 -06:00
Alex Gleason b71bb3966a
ThemeEditor: configure single-color items 2022-12-17 21:13:30 -06:00
Alex Gleason ab70af31cd
ThemeEditor: restore default theme 2022-12-17 20:48:02 -06:00
Alex Gleason 716cc311c7
ThemeEditor: allow importing a theme 2022-12-17 20:36:54 -06:00
Alex Gleason c624fbcba3
ThemeEditor: allow exporting a theme 2022-12-17 20:16:05 -06:00
Alex Gleason b15871aaa8
utils/download: take a string instead of AxiosResponse 2022-12-17 20:15:40 -06:00
Alex Gleason 69a9748b3d
ThemeEditor: allow resetting the theme
(that was harder than I expected)
2022-12-17 19:39:54 -06:00
Alex Gleason 2505f622e2
ThemeEditor: add hue sliders 2022-12-17 19:02:02 -06:00
Alex Gleason faf513c049
Add Slider component (based on video volume slider) 2022-12-17 18:31:56 -06:00
Alex Gleason 8a14dfefe7
Merge remote-tracking branch 'origin/develop' into theme-editor 2022-12-17 17:57:43 -06:00
Alex Gleason eb63ec4d46 Merge branch 'admin-ui-reorganize' into 'develop'
Admin UI improvements

See merge request soapbox-pub/soapbox!2015
2022-12-17 22:37:48 +00:00
Alex Gleason b00a189209
GitLab CI: let deps job be interrupted 2022-12-17 16:25:28 -06:00
Alex Gleason b4d2c61d15
changelog typofix 2022-12-17 16:22:14 -06:00
Alex Gleason 8f78336a4b
Dashboard: include link to repo for the current commit 2022-12-17 16:14:57 -06:00
Alex Gleason 523820fda6
CHANGELOG: 3-column layout 2022-12-17 15:50:14 -06:00
Alex Gleason dc7aea6466
Admin: restyle unapproved account, delete admin.scss 2022-12-17 15:48:45 -06:00
Alex Gleason 6c232d70a8
Admin: improve design of Moderation Logs 2022-12-17 15:23:18 -06:00
Alex Gleason 60f54f80b0
Dashboard: add quick links to Soapbox Config and Moderation Log 2022-12-17 15:08:59 -06:00
Alex Gleason 4fde647aa8
Admin: redesign registration picker 2022-12-17 14:53:21 -06:00
Alex Gleason 52bdb48bfb
Admin: refactor email list downloads into List, get rid of .dashwidget css 2022-12-17 14:23:52 -06:00
Alex Gleason ee443158b6
Admin: refactor counters with DashCounter component 2022-12-17 14:04:37 -06:00
Alex Gleason 819e03073b
SoapboxConfig: link to theme editor 2022-12-17 13:10:59 -06:00
Alex Gleason f906558dba
Theme editor: allow saving theme 2022-12-17 13:05:50 -06:00
Alex Gleason ed12246ae4
Remove unused sea-blue color 2022-12-17 11:47:18 -06:00
Alex Gleason 5f08091856 Merge branch 'rename-unsafe-lifecycles' into 'develop'
Bundle: componentWillReceiveProps --> UNSAFE_componentWillReceiveProps

See merge request soapbox-pub/soapbox!2013
2022-12-17 17:29:56 +00:00
Alex Gleason b481b70458 Merge branch 'more-changelog' into 'develop'
changelog: ability to see quotes, redesigned interactions

See merge request soapbox-pub/soapbox!2014
2022-12-17 17:23:30 +00:00
Alex Gleason 82248ac239
changelog: ability to see quotes, redesigned interactions 2022-12-17 11:22:37 -06:00
Alex Gleason 63ee2ba2ba
Bundle: componentWillReceiveProps --> UNSAFE_componentWillReceiveProps 2022-12-17 11:01:43 -06:00
Alex Gleason d78659924c Merge branch 'danger-changelog' into 'develop'
Danger: don't warn about changelog for docs, CI, etc

See merge request soapbox-pub/soapbox!2012
2022-12-17 17:00:57 +00:00
marcin mikołajczak 7711553fd8 Groups: allow simple moderation
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-17 17:57:43 +01:00
Alex Gleason 8f2a1fb6ef
Danger: don't warn about changelog for docs, CI, etc 2022-12-17 10:42:05 -06:00
marcin mikołajczak b6b9fdb035 Groups: fix DetailsStep
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-17 15:59:11 +01:00
marcin mikołajczak f829440104 Add groups link to sidebar
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-17 14:37:08 +01:00
marcin mikołajczak 0e730cf762 Groups: add key to group links
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-17 14:33:40 +01:00
marcin mikołajczak 7d48c40b89 Placeholder group cards
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-17 14:31:23 +01:00
marcin mikołajczak c1663d743a Groups: compose form improvements
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-17 13:41:53 +01:00
marcin mikołajczak be30cdbcb2 Groups: use isDefaultHeader
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-17 13:38:41 +01:00
marcin mikołajczak bed8619cf0 Groups: Snackbar messages, timelines handling
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-17 13:35:52 +01:00
Alex Gleason af4e8765fd Merge branch 'weblate-installation' into 'develop'
Adding a link to Weblate in our project's homepage

See merge request soapbox-pub/soapbox!2011
2022-12-17 03:05:47 +00:00
Tassoman 9bd82252f4 Adding a link to Weblate in our project's homepage 2022-12-17 03:05:47 +00:00
Alex Gleason 636abf6400 Merge branch 'ci-interruptable' into 'develop'
GitLab CI: let jobs auto-cancel when a new commit is pushed to the same branch

See merge request soapbox-pub/soapbox!2009
2022-12-17 02:19:35 +00:00
Alex Gleason 16eeb89a37
GitLab CI: let jobs auto-cancel when a new commit is pushed to the same branch 2022-12-16 19:26:39 -06:00
Alex Gleason 62accd5559
Fix import paths 2022-12-16 19:22:59 -06:00
Alex Gleason 48bd830349
Merge remote-tracking branch 'origin/develop' into theme-editor 2022-12-16 18:39:20 -06:00
marcin mikołajczak d299512694 Remove unused styles
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-17 00:48:40 +01:00
marcin mikołajczak 25b2f167f2 Groups: Lint, use PlaceholderAccount for GroupMembers
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-17 00:43:40 +01:00
marcin mikołajczak fd6e3f4032 Groups: Make strings localizable
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-17 00:33:07 +01:00
marcin mikołajczak 0d617d4de8 Groups: simple member list
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-17 00:07:35 +01:00
Alex Gleason e24a62d203 Merge branch 'delete-locale-data' into 'develop'
Delete custom locale-data

See merge request soapbox-pub/soapbox!2007
2022-12-16 23:04:59 +00:00
Alex Gleason 05514275c6 Merge branch 'changelogging' into 'develop'
Prevent conflicts to CHANGELOG.md, warn if not updated with Danger

See merge request soapbox-pub/soapbox!2006
2022-12-16 23:04:40 +00:00
marcin mikołajczak 0256c34406 Remove unused import
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-16 21:44:55 +01:00
marcin mikołajczak ecaf3af364 Groups: utilize isDefaultAvatar, isDefaultHeader
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-16 21:35:09 +01:00
marcin mikołajczak d4024e927d Merge remote-tracking branch 'soapbox/develop' into mastodon-groups 2022-12-16 21:33:23 +01:00
marcin mikołajczak 36350f1cc4 More group actions, allow to edit groups, visuals
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-16 21:33:17 +01:00
Alex Gleason 9c00fe2f00 Merge branch 'status-short-numbers' into 'develop'
InteractionCounter: use shortNumberFormat

See merge request soapbox-pub/soapbox!2008
2022-12-16 17:44:58 +00:00
Alex Gleason 3590b75b6b
InteractionCounter: use shortNumberFormat 2022-12-15 18:40:21 -06:00
marcin mikołajczak d524a7c700 Groups: UI improvements
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-15 23:51:30 +01:00
Alex Gleason 64a2566ddb
Delete custom locale-data 2022-12-15 14:57:19 -06:00
Alex Gleason cbb027f09c
CHANGELOG: fill out changes for Soapbox v2.0, and Unreleased 2022-12-15 14:23:49 -06:00
marcin mikołajczak e8d6c7d4b6 Merge branch 'profile-header' into 'develop'
Default header should not be clickable

See merge request soapbox-pub/soapbox!1994
2022-12-15 11:52:16 +00:00
Alex Gleason 71bad449a4 Merge branch 'gate-events' into 'develop'
Feature-gate event routes

See merge request soapbox-pub/soapbox!2005
2022-12-15 02:06:20 +00:00
Alex Gleason a494d42fb6 Merge branch 'fix/1231' into 'develop'
Feeding hide network checkbox

Closes #1231

See merge request soapbox-pub/soapbox!1989
2022-12-15 00:52:57 +00:00
Tassoman d3e9b283eb Feeding hide network checkbox 2022-12-15 00:52:56 +00:00
Alex Gleason 5bfe3d8f99
Danger: improve phrasing of changelog warning 2022-12-14 18:19:34 -06:00
Alex Gleason 5b79f91c53
CHANGELOG: add missing release, boilerplate [Unreleased] section 2022-12-14 18:09:33 -06:00
Alex Gleason b030c15583
Danger: warn when CHANGELOG.md isn't updated 2022-12-14 18:06:44 -06:00
marcin mikołajczak 255f9cd6d1 Merge branch 'i18n-pl' into 'develop'
Update Polish translation

See merge request soapbox-pub/soapbox!2004
2022-12-14 23:46:17 +00:00
Alex Gleason 4a1ae9798a
Add .gitattributes, prevent conflicts on CHANGELOG.md 2022-12-14 17:44:16 -06:00
Alex Gleason 7ae1b197d5
Feature-gate event routes 2022-12-14 17:38:57 -06:00
marcin mikołajczak 1bc30cb694 Update Polish translation
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-15 00:37:12 +01:00
marcin mikołajczak 683504c997 Allow creating events, events list
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-14 22:59:59 +01:00
Alex Gleason 9c3bd08f8d Merge branch 'fix-avatar-ring' into 'develop'
Fix avatar ring

See merge request soapbox-pub/soapbox!1995
2022-12-14 20:55:42 +00:00
Alex Gleason 7138bec3b0
Merge remote-tracking branch 'origin/develop' into fix-avatar-ring 2022-12-14 14:41:14 -06:00
Alex Gleason 9fb1f69cd2 Merge branch 'edit-profile-top' into 'develop'
EditProfile: move profile preview (avatar/banner) to the top

See merge request soapbox-pub/soapbox!2002
2022-12-14 20:31:27 +00:00
Alex Gleason 5499696915
EditProfile: move profile preview (avatar/banner) to the top 2022-12-14 13:53:59 -06:00
Alex Gleason 450119da99 Merge branch 'issue/1262' into 'develop'
file fields inverted position

Closes #1262

See merge request soapbox-pub/soapbox!1990
2022-12-14 19:50:50 +00:00
Alex Gleason e2c7933513 Merge branch 'carousel-seen-feature' into 'develop'
Carousel: make `seen` optional, only hit the API if features.carouselSeen is supported

See merge request soapbox-pub/soapbox!2001
2022-12-14 19:46:30 +00:00
Alex Gleason b5f829cdb3
Carousel: add mock for seen API 2022-12-14 13:28:41 -06:00
Alex Gleason e2b6a7af84
Carousel: don't set unseen unless it's explicitly `false` (backwards-compat) 2022-12-14 13:23:11 -06:00
Alex Gleason 8f3c0a1071
Carousel: make `seen` optional, only hit the API if features.carouselSeen is supported 2022-12-14 13:06:41 -06:00
Alex Gleason 30abdab924
features.feedUserFiltering --> features.carousel 2022-12-14 12:54:42 -06:00
Chewbacca 113de75355 Merge branch 'fix-centering-of-compose-form' into 'develop'
Add spacing above textarea

See merge request soapbox-pub/soapbox!2000
2022-12-14 18:37:35 +00:00
Chewbacca fa4bd20d11 Merge branch 'carousel-v2' into 'develop'
Support 'seen' property in the Feed Carousel

See merge request soapbox-pub/soapbox!1978
2022-12-14 18:36:50 +00:00
Alex Gleason 15b9e0e355
HomePage: shift the ComposeForm with translate-y instead of pt 2022-12-14 12:04:59 -06:00
Chewbacca 07d24c91d8 Allow tab continuation on Email confirmation 2022-12-14 12:59:21 -05:00
Alex Gleason 55cf6d6041
Merge remote-tracking branch 'origin/develop' into fix-centering-of-compose-form 2022-12-14 11:41:05 -06:00
Chewbacca c54b50c562 Add spacing above textarea 2022-12-14 12:26:44 -05:00
Alex Gleason dd5056cfb3 Merge branch 'bio-wrap' into 'develop'
Markup: use whitespace-pre-wrap (fix multiline bios on Mastodon)

See merge request soapbox-pub/soapbox!1999
2022-12-14 17:18:24 +00:00
Alex Gleason eef7fdb78e
Markup: use whitespace-pre-wrap (fix multiline bios on Mastodon) 2022-12-14 11:01:09 -06:00
Alex Gleason 5a38f7fb09 Merge branch 'chats-font-fix' into 'develop'
Add Inter 600, fix ChatPaneHeader font weight

See merge request soapbox-pub/soapbox!1998
2022-12-14 16:34:09 +00:00
Alex Gleason 463504346c
Add Inter 600, fix ChatPaneHeader font weight 2022-12-14 10:12:24 -06:00
Alex Gleason 5418e49234 Merge branch 'chat-fixes' into 'develop'
Push chat to top of the list after sending a message

See merge request soapbox-pub/soapbox!1997
2022-12-14 13:59:58 +00:00
Chewbacca 4204b48a40 Remove mocks 2022-12-14 08:44:04 -05:00
Alex Gleason 8f99d549f0 Merge branch 'ita-patch1' into 'develop'
ita mobile patch

See merge request soapbox-pub/soapbox!1985
2022-12-14 03:44:40 +00:00
Tassoman 2adf8f1886 ita mobile patch 2022-12-14 03:44:40 +00:00
marcin mikołajczak 7c4aca51dc some basic groups ui
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-13 23:03:01 +01:00
Alex Gleason 5de1c3a61d
Revert flattenPages order changes 2022-12-13 15:17:58 -06:00
Chewbacca b3a0f785d8
Fix sorting of Chat List 2022-12-13 15:08:25 -06:00
Chewbacca 8aa171fede
Re-order chat-list after sending messaging 2022-12-13 15:07:13 -06:00
Alex Gleason ff878e1b49 Merge branch 'reduce-timestamp-size' into 'develop'
Chats: Reduce size of timestamp

See merge request soapbox-pub/soapbox!1996
2022-12-13 17:00:37 +00:00
Chewbacca f0a057d685
Reduce size of timestamp 2022-12-13 10:48:12 -06:00
Chewbacca 84d0717f44 Fix avatar ring 2022-12-13 11:46:07 -05:00
marcin mikołajczak 6900b59697 Move isDefaultHeader and isDefaultAvatar to utils/accounts
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-13 00:09:00 +01:00
marcin mikołajczak 761061c9a8 Default header should not be clickable
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-13 00:00:13 +01:00
Alex Gleason 90513f1807 Merge branch 'chat-search-pagination' into 'develop'
Improve Chats search

See merge request soapbox-pub/soapbox!1993
2022-12-12 19:27:17 +00:00
Chewbacca 61cd1d2227
Fix expiration values 2022-12-12 12:13:41 -06:00
Chewbacca e8427b3081
Remove 2 minute expiration 2022-12-12 12:13:32 -06:00
Chewbacca af19c1bd44
Fix spacing bug 2022-12-12 12:12:06 -06:00
Alex Gleason 502f9d9f47
queries/search: use flattenPages util 2022-12-12 12:10:39 -06:00
Chewbacca 15594df644
Fix tests 2022-12-12 12:01:10 -06:00
Chewbacca 6bae81a758
Reduce size of ellipsis icon 2022-12-12 12:01:04 -06:00
Chewbacca 9657598d33
Remove unneeded code from AccountSearch 2022-12-12 12:00:53 -06:00
Chewbacca 5a30509fa6
Add support for pagination in Chat Search 2022-12-12 11:59:37 -06:00
marcin mikołajczak 12825f9350 Groups: actions, normalizers, reducers
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-11 22:24:01 +01:00
marcin mikołajczak 5a2d082437 Merge branch 'supported-languages' into 'develop'
Support source_languages and target_languages

See merge request soapbox-pub/soapbox!1991
2022-12-11 12:13:31 +00:00
marcin mikołajczak 2f2ae8237d Support source_languages and target_languages
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-10 23:16:06 +01:00
tassoman 6c00d4e0e1 file fields inverted position 2022-12-10 18:55:04 +01:00
marcin mikołajczak 14b015a025 Merge branch 'events' into 'develop'
ComposeEventModal: Set is_uploading to false after successsfully uploading banner

See merge request soapbox-pub/soapbox!1987
2022-12-09 19:04:21 +00:00
marcin mikołajczak 24b5f0bf28 ComposeEventModal: Set is_uploading to false after successsfully uploading banner
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-09 19:54:25 +01:00
marcin mikołajczak fc728f4b1a Merge branch 'domain-blocks' into 'develop'
this wasn't meant to be merged

See merge request soapbox-pub/soapbox!1986
2022-12-09 16:29:48 +00:00
marcin mikołajczak aea7016123 this wasn't meant to be merged
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-09 17:07:38 +01:00
Alex Gleason 5998400a75 Merge branch 'chats-deletion' into 'develop'
Enable Chats deletion for Rebased

Closes #608

See merge request soapbox-pub/soapbox!1984
2022-12-09 02:13:49 +00:00
Alex Gleason 889d598027
Enable Chats deletion for Rebased 2022-12-08 19:48:34 -06:00
Alex Gleason 9dd791eeed Merge branch 'it-lang-patch' into 'develop'
small ita patch

See merge request soapbox-pub/soapbox!1983
2022-12-09 00:24:00 +00:00
Tassoman Pigi 321e347b32 small ita patch 2022-12-09 00:24:00 +00:00
marcin mikołajczak 523e573fd7 Merge branch 'events' into 'develop'
Revert "Remove 'show on map' for now"

See merge request soapbox-pub/soapbox!1982
2022-12-08 16:45:29 +00:00
marcin mikołajczak 24b790c2d1 Set tile server to empty by default
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-08 16:45:33 +01:00
marcin mikołajczak 47b8f5fe64 Specify description format as markdown
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-08 16:40:14 +01:00
marcin mikołajczak 2137193935 Revert "Remove 'show on map' for now"
This reverts commit 46cb676822.
2022-12-08 16:30:48 +01:00
marcin mikołajczak 41746b84d9 Merge branch 'events' into 'develop'
Show Unauthorized modal for 'X people going'

See merge request soapbox-pub/soapbox!1979
2022-12-08 14:28:13 +00:00
Alex Gleason 0fd931aa6e Merge branch 'it-develop' into 'develop'
italian translation

See merge request soapbox-pub/soapbox!1980
2022-12-07 23:19:33 +00:00
Tassoman Pigi 10a1a3b74e italian translation 2022-12-07 23:19:33 +00:00
Alex Gleason 7fe2b52b84 Merge branch 'chats-small-changes' into 'develop'
Chats small changes

See merge request soapbox-pub/soapbox!1981
2022-12-07 22:45:11 +00:00
Alex Gleason 3acc95447f
Fix order of optimistic chat messages 2022-12-07 16:18:17 -06:00
Alex Gleason dad6244c7d
Chats: remove language around followers 2022-12-07 15:56:22 -06:00
Alex Gleason d6d327c760
Helmet: add unread chats count 2022-12-07 15:56:22 -06:00
Alex Gleason dc556248f0
private --> direct 2022-12-07 15:56:22 -06:00
Alex Gleason b42b8fced4
Chats: fix mention styling 2022-12-07 15:56:17 -06:00
Alex Gleason ebd126ac3c Merge branch 'chats' into 'develop'
Chats redesign

Closes #1227, #360, #1196, #495, and #380

See merge request soapbox-pub/soapbox!1795
2022-12-07 15:12:31 +00:00
Alex Gleason 8b013cbf1c
Chats: fix message from profile button 2022-12-07 08:25:56 -06:00
Alex Gleason df3a64a4af
Chats: simplify Welcome screen 2022-12-07 08:14:22 -06:00
Alex Gleason fbd2471dc6
Move StatProvider above UI, increment chats unread counter from streaming events 2022-12-07 00:45:10 -06:00
Alex Gleason d811500812
Chats: enable autocomplete 2022-12-07 00:18:47 -06:00
Alex Gleason d4419bf71f
Chats: hide read receipts for unsupported servers 2022-12-06 22:32:35 -06:00
Alex Gleason 2986f00728
appendPageItem: fix order 2022-12-06 22:30:03 -06:00
Alex Gleason ef4e738625
Load chats even on small screen sizes 2022-12-06 22:22:25 -06:00
Alex Gleason 2ffce5b68f
Chats: delete failing tests 2022-12-06 17:44:50 -06:00
Alex Gleason acc2da252f
Chats: allow toggling sound 2022-12-06 17:24:24 -06:00
Alex Gleason ac4ffaa41f
Streaming: play chat sounds if enabled 2022-12-06 17:19:09 -06:00
Alex Gleason 6c22a3841b
ChatPaneHeader: i18n title 2022-12-06 17:10:16 -06:00
Alex Gleason e1edc9796b
Make .compose-form__upload more widely available 2022-12-06 17:08:00 -06:00
Alex Gleason 6a27670271
Break composer upload into a generic component 2022-12-06 17:01:06 -06:00
Alex Gleason 5b1de5da8c
Chats: improve uploading progress bar styles 2022-12-06 16:39:37 -06:00
Alex Gleason 9e39415ca8
Chats: gate upload button behind `chatsMedia` feature flag 2022-12-06 16:36:30 -06:00
Alex Gleason 4c5e8eb525
Chats: improve upload button styles 2022-12-06 16:33:53 -06:00
Alex Gleason dc420a843b
Chats: fix submitting an attachment 2022-12-06 16:27:07 -06:00
Alex Gleason 6eafb8c0c3
Chats: start making attachments work again 2022-12-06 16:21:00 -06:00
Alex Gleason 2ca4db5c3b
Chats: fix display of media attachments, fix break-words 2022-12-06 15:45:33 -06:00
marcin mikołajczak 3855d966af Add 'View event on {domain}'
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-06 22:33:17 +01:00
Alex Gleason e1c80920ed
Enable chatsv2 on TruthSocial 2022-12-06 15:25:40 -06:00
Alex Gleason 3aff4ee715
Replace proprietary send icon with Tabler 2022-12-06 15:20:48 -06:00
marcin mikołajczak 39b9cf4eed Show Unauthorized modal for 'X people going'
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-06 22:17:23 +01:00
Alex Gleason cad1d9071a
Restore "chats" name and icon 2022-12-06 15:16:36 -06:00
Alex Gleason 30646ec8c3
Fix pagination of chat messages 2022-12-06 15:12:24 -06:00
Chewbacca 994d58294a Support 'seen' property in the Feed Carousel 2022-12-06 16:00:56 -05:00
Alex Gleason f7bd5c5951
deduplicateById: fix Entity types 2022-12-06 14:48:41 -06:00
Alex Gleason 569296af36
Merge branch 'chats-pleroma' into chats 2022-12-06 14:36:38 -06:00
Chewbacca 717c21a2e3 Switch X for Check 2022-12-06 13:50:03 -05:00
Alex Gleason 2d9c73cf9e
EventHeader: fix initReport() calls 2022-12-06 12:21:25 -06:00
Alex Gleason 2cedd69f1d
Merge remote-tracking branch 'origin/develop' into chats 2022-12-06 11:53:47 -06:00
Alex Gleason cb7f0aeab8
Chats: deduplicate items 2022-12-05 18:38:32 -06:00
Chewbacca a73ade90c1 Change websocket event name 2022-12-05 15:41:06 -05:00
Chewbacca 0bed4d5f31 Update copy 2022-12-05 15:04:45 -05:00
Chewbacca 5e47a2567f Revert "Replace 'send' icon from Tabler"
This reverts commit d5303387f5.
2022-12-05 13:09:23 -05:00
Chewbacca d5303387f5 Replace 'send' icon from Tabler 2022-12-05 08:45:20 -05:00
Chewbacca 9cc9e8876b Fix infinite pagination of chats 2022-12-05 08:41:26 -05:00
Alex Gleason 6154e4bac4
Rotate arrows for RTL 2022-12-04 19:40:09 -06:00
Alex Gleason 4a48e9d510
Merge remote-tracking branch 'origin/develop' into chats 2022-12-04 19:27:54 -06: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
marcin mikołajczak c531c26078 maybe fix links in modals
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-12-03 20:49:43 +01:00
Chewbacca 5816659a09 Refactor chat functions 2022-12-02 15:50:54 -05:00
Chewbacca b5aca1649d Remove unused 'initReportById' function 2022-12-02 09:03:08 -05:00
Chewbacca 8df7d9c9ef UX improvements to message bubble 2022-12-02 08:28:51 -05:00
Chewbacca d875c1c3e8 Fix tests 2022-12-01 13:08:05 -05:00
Chewbacca 67a61ad3b4 Search on focus 2022-12-01 12:40:30 -05:00
Alex Gleason 31444756e4
Merge remote-tracking branch 'origin/develop' into chats 2022-11-30 12:46:24 -06:00
Chewbacca 50f5e2af38 Merge remote-tracking branch 'origin/develop' into chats 2022-11-28 10:03:40 -05:00
Alex Gleason 6697e0191b
Fix crash against Pleroma (make `latest_read_message_by_account` an optional param) 2022-11-27 15:34:43 -06:00
Alex Gleason 5bb30b6282
Merge remote-tracking branch 'origin/develop' into chats 2022-11-27 15:30:00 -06:00
Chewbacca e14230678d Add emoji autocomplete to Chats 2022-11-22 09:55:31 -05:00
Chewbacca f2e7cf4e5c Remove avatar from chat messages 2022-11-22 08:23:18 -05:00
marcin mikołajczak 5e05c32eed Remove unused config
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-11-21 21:59:35 +01:00
marcin mikołajczak fe50acf0c3 Move RSS button to account menu
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-11-21 21:03:35 +01:00
marcin mikołajczak 8be2ee918d Merge remote-tracking branch 'soapbox/develop' into rss-button 2022-11-21 20:41:25 +01:00
Chewbacca 8d9182eb44 Add max character count to Chat composer 2022-11-21 12:21:02 -05:00
Chewbacca f7f40703cd Merge remote-tracking branch 'origin/develop' into chats 2022-11-21 12:06:44 -05:00
Chewbacca 9f8aabc3d8 Align avatar to bottom 2022-11-17 13:22:47 -05:00
Chewbacca 10c6a7116c Add blocked message 2022-11-17 13:13:22 -05:00
Chewbacca 5fbe248b97 Clear cache from React Query on logout 2022-11-17 13:13:09 -05:00
Chewbacca ae0082ad53 Wrap chat settings in feature flag 2022-11-17 11:53:34 -05:00
Chewbacca 72c26bc9bc Merge remote-tracking branch 'origin/develop' into chats 2022-11-17 10:58:34 -05:00
Chewbacca dbfcc0da3e Add Chats onboarding tests 2022-11-14 16:09:07 -05:00
Chewbacca caa3873821 Account for API validation errors 2022-11-14 11:22:45 -05:00
Chewbacca d5fc6fe252 Merge remote-tracking branch 'origin/develop' into chats 2022-11-14 10:14:45 -05:00
Chewbacca ecc67737c6 D 2022-11-11 08:01:17 -05:00
Chewbacca b364af645f Remove overflow property from around Virtuoso 2022-11-11 07:58:42 -05:00
Chewbacca 3a7f27b5bf Drop chat_message.created notifications 2022-11-11 07:22:21 -05:00
Chewbacca c889ece788 Fix mobile navigation on Chats 2022-11-11 07:16:53 -05:00
Chewbacca d12ca77502 Merge remote-tracking branch 'origin/develop' into chats 2022-11-11 06:58:20 -05:00
marcin mikołajczak 5d10324127 Allow displaying RSS button to unauthenticated users
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2022-11-11 11:59:06 +01:00
Chewbacca c453bbb687 Update Chat with last_message when current_user is sending a message 2022-11-10 16:41:24 -05:00
Chewbacca 0164bf35a0 Temporarily disable sounds 2022-11-10 16:07:00 -05:00
Chewbacca 93a696a72f Re-sort the ChatList when new messages come in 2022-11-10 15:42:59 -05:00
Chewbacca 15c22863d7 Fetch relationships everytime we fetch a single chat 2022-11-10 11:56:36 -05:00
Chewbacca 98b2fdf9a4 Improve emoji to support custom 2022-11-09 13:17:10 -05:00
Chewbacca 38e350de24 Support Emoji-only messages 2022-11-09 12:55:22 -05:00
Chewbacca 94c55b6cbe Reduce size of read receipts 2022-11-09 12:34:06 -05:00
Chewbacca e7106a35b3 Refactor 'createChatMessage' mutation 2022-11-09 12:24:44 -05:00
Chewbacca 2460d85460 Add more tests to chats query 2022-11-09 10:28:15 -05:00
Chewbacca d637626838 Only mark last message as read if needed 2022-11-09 10:16:04 -05:00
Chewbacca e7e121e78f Fix spacing under last message 2022-11-09 09:16:22 -05:00
Chewbacca 7c68392617 Merge remote-tracking branch 'origin/develop' into chats 2022-11-09 09:03:48 -05:00
Chewbacca f5ddd586f6 Add 2 minute deletion duration for testing 2022-11-09 08:37:50 -05:00
Chewbacca f6290be1e2 Merge remote-tracking branch 'origin/develop' into chats 2022-11-09 07:46:51 -05:00
Chewbacca 756b03cfe5 Remove 'transparent' theme from Input 2022-11-07 16:30:53 -05:00
Chewbacca f269b754f0 Remove 'retry' if successful response 2022-11-07 16:25:53 -05:00
Chewbacca 0105458c22 Update privacy copy 2022-11-07 16:18:18 -05:00
Chewbacca 357e46248e Always refetch and re-hydrate the Chat 2022-11-07 15:40:19 -05:00
Chewbacca 37bec50c08 Use default search input 2022-11-07 15:40:04 -05:00
Chewbacca 0e52244d58 Add blankslate when chats are present 2022-11-07 12:13:44 -05:00
Chewbacca 715eeee540 Add tooltip to 'auto-delete' info 2022-11-07 11:53:40 -05:00
Chewbacca 1ae9775e07 Add link to profile in Chat header 2022-11-07 11:47:18 -05:00
Chewbacca 57b2629337 Consolidate 'message user' in profile 2022-11-07 11:43:17 -05:00
Chewbacca 14353c1aff Add blocked copy in ChatList 2022-11-07 11:16:47 -05:00
Chewbacca 3da075dd0c Change to 'last_message.unread' 2022-11-07 10:53:44 -05:00
Chewbacca 6538db17e7 Fix relative link to Profile 2022-11-07 10:04:02 -05:00
Chewbacca 5490e83caf Update alignment of title/search-box and ChatList 2022-11-07 10:01:11 -05:00
Chewbacca b9c649011c Update 'theme' of message timestamp in ChatList 2022-11-07 09:54:44 -05:00
Chewbacca acede4b519 Merge remote-tracking branch 'origin/develop' into chats 2022-11-07 08:17:11 -05:00
Chewbacca 97450f416c Fallback to username 2022-11-04 10:43:19 -04:00
Chewbacca 245a0f4fc8 Add Memory Router above ChatContext 2022-11-04 10:24:40 -04:00
Chewbacca 2ecf837656 Remove changing of screen when updating a chat 2022-11-04 09:49:35 -04:00
Chewbacca 4408c6035f Fix jump of content 2022-11-04 07:51:26 -04:00
Chewbacca f833a1560d Merge remote-tracking branch 'origin/develop' into chats 2022-11-04 07:37:12 -04:00
Chewbacca 8d99cfd24f Invalid individual Chat query on chat acceptance 2022-11-04 07:37:05 -04:00
Chewbacca 472df260fe Ensure Policy Modal opens upon login 2022-11-04 07:36:48 -04:00
Chewbacca 53208bd670 Improve light-mode styling on Policy Modal and Read Receipts 2022-11-04 07:36:30 -04:00
Chewbacca 63c02cf31e Temporarily disable setting the Chat cached object 2022-11-04 07:36:10 -04:00
Chewbacca b510ccb865 Fix loading state of blankslate 2022-11-03 17:08:48 -04:00
Chewbacca bc65331cbb Make sure relationship is fetched in Chat Main Page 2022-11-03 16:54:18 -04:00
Chewbacca 4767f4fd8c properly handle routing after deleting chat 2022-11-03 15:29:53 -04:00
Chewbacca fe55152667 Fix break-words with HTML 2022-11-03 15:22:18 -04:00
Chewbacca 7571b88c51 Add unread indicator + fix bug with read receipts 2022-11-03 15:16:07 -04:00
Chewbacca bfcafecfe2 Merge remote-tracking branch 'origin/develop' into chats 2022-11-03 14:16:52 -04:00
Chewbacca 51c01bfc04 Keep fresh messages 2022-11-03 13:55:33 -04:00
Chewbacca a2540cb0d0 Add route 2022-11-03 13:33:33 -04:00
Chewbacca 69723305eb Fix tests 2022-11-03 13:22:06 -04:00
Chewbacca 18717c7967 Update badge counts again to prevent overlay 2022-11-03 12:48:17 -04:00
Chewbacca 7451a52fc2 Merge remote-tracking branch 'origin/chats' into chats 2022-11-03 12:13:59 -04:00
Chewbacca df2f38a60f Add ability to DM from profile 2022-11-03 12:13:54 -04:00
Chewbacca be136fe6cf Add max count to sidebar icons 2022-11-03 12:13:45 -04:00
Alex Gleason 27b5211203
Merge remote-tracking branch 'origin/chats' into chats 2022-11-02 16:08:39 -05:00
Alex Gleason 8cd84b6128
Chats: accepting_messages --> accepts_chat_messages 2022-11-02 15:10:13 -05:00
Alex Gleason 1873ba3e22
Chats: feature-gate chat message reporting 2022-11-02 14:33:14 -05:00
Chewbacca d0960de07c Merge remote-tracking branch 'origin/chats' into chats 2022-11-02 15:28:22 -04:00
Chewbacca 54466f1293 Move query into Context 2022-11-02 15:28:16 -04:00
Alex Gleason 4d9f7fec32
Chats: normalize chat messages again so attachments don't break 2022-11-02 14:23:39 -05:00
Alex Gleason 9802257751
Chats: make chat acceptance and deletion feature-gated 2022-11-02 14:14:16 -05:00
Alex Gleason 4dc0ab2d00
Chats: make Truth Policies conditional 2022-11-02 14:02:43 -05:00
Alex Gleason 69d92b6f95
Chats: make chatsExpiration a conditional feature 2022-11-02 13:58:02 -05:00
Alex Gleason 239b2af553
Chats: make message_expiration optional (for Pleroma compatibility) 2022-11-02 13:53:41 -05:00
Alex Gleason eeb8ca37a6
Merge remote-tracking branch 'origin/develop' into chats 2022-11-02 11:27:21 -05:00
Chewbacca 9869cf6f55 Add 'unread' indicator to Messages 2022-11-01 14:35:51 -04:00
Chewbacca 650387dc77 Add Policy Modal 2022-11-01 13:22:29 -04:00
Chewbacca 929a78641b Fix bug when selecting previous chat 2022-11-01 10:04:21 -04:00
Chewbacca b33b32d9dc Update 'last_message' if the user deletes it 2022-11-01 09:44:21 -04:00
Chewbacca 15cd5f9104 Remove 'Getting Started' blankslate 2022-11-01 08:22:12 -04:00
Chewbacca e63f5e6fb5 Update lifespan copy to be dynamic in Intro 2022-11-01 08:04:31 -04:00
Chewbacca e0a3d03b55 Update Chat Settings for the main page 2022-11-01 07:59:30 -04:00
Chewbacca d9befff3f5 Update report text to be more clear 2022-10-31 15:55:04 -04:00
Chewbacca 1d04810c5a Update ToS link to accent blue 2022-10-31 15:53:24 -04:00
Chewbacca 2c7fcdd00b Update copy for Unblock modal 2022-10-31 15:51:51 -04:00
Chewbacca d89ac0e0a5 Conversation -> Chat 2022-10-31 15:48:42 -04:00
Chewbacca 86e79354d7 Add new Welcome experience 2022-10-31 12:14:22 -04:00
Chewbacca 0c0d568056 Merge remote-tracking branch 'origin/develop' into chats 2022-10-31 10:54:31 -04:00
Chewbacca 24bca458bd Add tests for chats query 2022-10-28 13:01:39 -04:00
Chewbacca 3e2888eb75 Handle unreadCount when messages are deleted 2022-10-27 13:59:54 -04:00
Chewbacca da1d8c7e97 Merge remote-tracking branch 'origin/develop' into chats 2022-10-27 10:25:46 -04:00
Chewbacca e8c72c8e11 Handle message deletions via websockets 2022-10-27 10:25:37 -04:00
Chewbacca 75233526cc Update duration design for Widget 2022-10-26 13:28:50 -04:00
Chewbacca 54363e24a9 Add ability to update deletion duration 2022-10-26 13:08:02 -04:00
Alex Gleason 41a608481f
ThemeEditor: allow editing colors (sort of) 2022-10-25 17:47:24 -05:00
Alex Gleason 3b1d8972b0
Scaffold theme editor 2022-10-25 16:56:25 -05:00
Chewbacca 22f3dd9444 Disable chatMessages query if blocked 2022-10-25 13:10:53 -04:00
Chewbacca f156c1026d Hide message history if blocked 2022-10-25 13:07:25 -04:00
Chewbacca 70957fe540 Add blocked/block experience to chats 2022-10-25 11:40:14 -04:00
Chewbacca 01c40eb42d Add 'delete for me' action 2022-10-25 10:13:08 -04:00
Chewbacca 9eb09e4aab Remove Chat Silence feature from web 2022-10-25 08:23:33 -04:00
Chewbacca d346d334f6 Merge remote-tracking branch 'origin/develop' into chats 2022-10-25 08:16:43 -04:00
Chewbacca c9424cda76 Merge remote-tracking branch 'origin/develop' into chats 2022-10-24 12:25:35 -04:00
Chewbacca dc6ac50c70 Merge remote-tracking branch 'origin/develop' into chats 2022-10-19 10:41:32 -04:00
Chewbacca 6098084c7d Fix reducer test 2022-10-17 12:24:24 -04:00
Chewbacca 694e1c8592 Fix linting errors 2022-10-17 12:23:03 -04:00
Chewbacca e0379f21e2 Fix test for ChatListItem 2022-10-17 12:11:10 -04:00
Chewbacca 780147dd24 Merge remote-tracking branch 'origin/chats' into chats 2022-10-17 12:08:55 -04:00
Chewbacca 4b85a72bc9 Fix test for ChatMessageList 2022-10-17 12:08:46 -04:00
Alex Gleason ca2aad2de0
Chats: focus textarea when navigating between chats (janky) 2022-10-17 10:50:33 -05:00
Alex Gleason 82250c23dc
Chats: search accounts only among people who follow you (TruthSocial) 2022-10-17 10:13:54 -05:00
Chewbacca 1ab7591b36 Merge remote-tracking branch 'origin/develop' into chats 2022-10-17 08:34:24 -04:00
Chewbacca 1007a2797e Re-organize folders 2022-10-17 08:34:19 -04:00
Chewbacca 65a8bf9aa1 Merge remote-tracking branch 'origin/develop' into chats 2022-10-14 14:27:53 -04:00
Justin a18cce4c81 Remove shadow from transparent input 2022-10-05 16:22:13 -04:00
Justin 7df4476427 Improve UX of chat messages 2022-10-05 16:13:29 -04:00
Justin 4a6d261bfd Improve UX of chat messages 2022-10-05 15:25:56 -04:00
Justin c41b71c76c Invalidate query cache when new chats come in 2022-10-05 15:15:16 -04:00
Alex Gleason 69d37a10fb
ChatList: display empty message 2022-10-04 19:22:18 -04:00
Alex Gleason 19382c3ab9
ChatPageNew: display disabled ChatComposer and "To:" label 2022-10-04 19:11:34 -04:00
Alex Gleason 4bab81bd7c
Separate ChatComposer into its own component 2022-10-04 19:00:00 -04:00
Alex Gleason 8c82d0400a
Chats: isSearch --> theme='search' 2022-10-04 17:47:15 -04:00
Alex Gleason 09887130b7
Merge remote-tracking branch 'origin/autosuggest-input-refactor' into chats 2022-10-04 17:46:45 -04:00
Alex Gleason f028b8e59f
ChatPageSidebar: increase padding 2022-10-04 15:15:08 -04:00
Alex Gleason 0bf616496f
Chats: add blankslate component to main page 2022-10-04 15:02:52 -04:00
Alex Gleason cdb5b505ba
Merge remote-tracking branch 'origin/develop' into chats 2022-10-04 12:40:48 -05:00
Justin e8ffa13629 Remove the ability to 'Report chat' from Intro 2022-10-04 11:00:07 -04:00
Justin 3a74496c35 Improve loading state of ChatMessageList 2022-10-04 10:50:55 -04:00
Justin 4447a3cda4 Convert ChatMessageList to Virtuoso 2022-10-04 10:48:37 -04:00
Justin f029c81d5f Fix break words for longer message contents 2022-10-03 11:14:13 -04:00
Justin 89af43df91 Add tests for ChatPane component 2022-10-03 11:03:43 -04:00
Justin e4ed68e070 Bump React Virtuoso 2022-10-03 11:03:19 -04:00
Justin dbee414ebc Add tests for ChatWidget component 2022-10-03 09:15:54 -04:00
Justin c63ed1af15 Refactor Chat Settings and add into Preferences page 2022-09-30 13:01:49 -04:00
Justin 65cdaeb886 Fix query key when not search query is present 2022-09-30 10:28:19 -04:00
Justin 7fde4a0c5c Small UI improvements to chat 2022-09-30 10:22:55 -04:00
Justin dc6c2657df Fix nested button structure 2022-09-29 13:54:18 -04:00
Justin d40fe483ef Push accounts into Redux store 2022-09-29 13:36:35 -04:00
Justin b590c062aa Show Skeleton when changing chats 2022-09-29 13:13:10 -04:00
Alex Gleason 78543292f1
Merge branch 'chats' of gitlab.com:soapbox-pub/soapbox into chats 2022-09-29 11:24:11 -05:00
Alex Gleason 40b8bab7ab
Chats: strip HTML when copying message text to clipboard 2022-09-29 11:23:49 -05:00
Justin 4c936fe6e0 Merge remote-tracking branch 'origin/chats' into chats 2022-09-29 12:04:28 -04:00
Justin 9d20d0d032 Fix order of flattenPages func 2022-09-29 12:04:23 -04:00
Alex Gleason 7722ce5e68
Chats: don't update own messages from streaming (for now) 2022-09-29 10:58:58 -05:00
Justin b0ea57b9b9 Merge remote-tracking branch 'origin/chats' into chats 2022-09-29 09:46:39 -04:00
Justin 0a8fa3e635 Add ability to report a Chat Message 2022-09-29 09:45:57 -04:00
Alex Gleason de78926142
ChatsPage: add settings cog 2022-09-28 19:39:22 -05:00
Alex Gleason f8199ab701
ChatPageNew: support account search to start a new chat 2022-09-28 19:35:28 -05:00
Alex Gleason acdd999c5c
Chats: display component at /chats/new 2022-09-28 19:26:49 -05:00
Alex Gleason e582eda17e
Route /chats/new to ChatIndex 2022-09-28 19:16:20 -05:00
Alex Gleason 2791d3453a
Chats: update chat cache in streaming 2022-09-28 15:55:56 -05:00
Alex Gleason d6e107dd0d
Chats: do routing a simpler way (keep context wrapper but set chat from route) 2022-09-28 15:38:05 -05:00
Alex Gleason 3ce5925280
useChat --> useChatActions 2022-09-28 15:20:59 -05:00
Alex Gleason 9c43f4b51e
UI: delete Gab groups commented routes 2022-09-28 13:39:45 -05:00
Alex Gleason e8b7fd8db8
Route /chats/:chatId to ChatPage component, cleanup UI imports, nuke ChatRoom (he cry) 2022-09-28 13:37:56 -05:00
Justin 002fef27a3 Add StatContext to store global stat state 2022-09-27 16:05:19 -04:00
Justin 058d0cec0b Merge remote-tracking branch 'origin/develop' into chats 2022-09-27 15:43:30 -04:00
Justin 17c2958df1 Use query key system 2022-09-27 15:42:24 -04:00
Justin 1a124c2eab Fix fade when scrolling on ChatList 2022-09-27 10:50:01 -04:00
Justin c40651150c Merge remote-tracking branch 'origin/develop' into chats 2022-09-27 10:41:20 -04:00
Justin 90c122bf3f Update leave chat summary 2022-09-27 10:18:12 -04:00
Justin f662023480 Add other actions for non-current-user messages 2022-09-23 13:00:40 -04:00
Justin 9768203f1b Open chat pane on action 2022-09-23 12:53:55 -04:00
Justin 0003b7323a Fix errant fetches to the silence endpoint 2022-09-23 09:48:52 -04:00
Justin 641bf1268d Fix loading state for chat-list 2022-09-23 09:24:20 -04:00
Justin 7335a3a0d3 Change color of last message text if unread 2022-09-23 09:08:46 -04:00
Justin 31b1f3ec97 I18n 2022-09-23 09:07:22 -04:00
Justin 0576565c83 Merge remote-tracking branch 'origin/chats' into chats 2022-09-23 09:04:05 -04:00
Justin e8b547565e Add options to the ChatListItem 2022-09-23 09:04:01 -04:00
Alex Gleason c8adde735f
ChatPage: fix height on mobile (where ThumbNavigation is present) 2022-09-22 17:38:00 -05:00
Alex Gleason 3c9ffd30b1
ChatPageSidebar: add new chat icon (non-functional) 2022-09-22 17:18:27 -05:00
Alex Gleason cbd7089166
ChatPageSidebar: refactor search 2022-09-22 17:06:42 -05:00
Alex Gleason 7cf1943364
Add chatsSearch feature 2022-09-22 16:52:31 -05:00
Alex Gleason 10b9a4eb4e
Chats: don't make mark as read hit the API again 2022-09-22 16:34:20 -05:00
Alex Gleason 075cb15940
Add utils/queries, refactor streaming 2022-09-22 16:28:05 -05:00
Alex Gleason c12999a438
Chats: use v2 endpoint if supported 2022-09-22 16:06:15 -05:00
Alex Gleason fa919c217b
Create ChatSearchInput component 2022-09-22 15:24:11 -05:00
Alex Gleason 46d309ae45
ChatListItem: restrict height of last_message content 2022-09-22 14:58:31 -05:00
Alex Gleason 2e728d99f9
ChatWidget: remove 'direct' streaming (it uses the 'user' stream) 2022-09-22 14:36:46 -05:00
Alex Gleason 1a4a6382d3
Make account.chats_onboarded true by default for backwards-compatibility 2022-09-22 14:34:07 -05:00
Justin 516d35e8ab Increase space between ChatListItems 2022-09-22 14:13:15 -04:00
Justin 045fe8dcbb Improve spacing and height of Chats page 2022-09-22 14:03:12 -04:00
Justin 89c1225976 Hide widget if not onboarded 2022-09-22 12:55:29 -04:00
Justin 93b11ec99c Add new airplane icon for sending messages 2022-09-22 12:45:01 -04:00
Justin 7c134a0c29 Switch buttons 2022-09-22 12:39:52 -04:00
Justin 4466326f8c Change copy to 'Delete for both' 2022-09-22 11:51:12 -04:00
Alex Gleason 624d139a5a
Chats: MAKE WEBSOCKET STREAMING WORK!!! 2022-09-21 18:26:18 -05:00
Alex Gleason c3edd71bf3
Chats: WIP streaming mutations 2022-09-21 17:52:20 -05:00
Alex Gleason 15a5c01cef
Chats: ['chats'] --> ['chats', 'search'] 2022-09-21 13:47:46 -05:00
Alex Gleason 90c8096f9e
Merge remote-tracking branch 'origin/develop' into chats 2022-09-21 10:18:29 -05:00
Alex Gleason bf590d26c4
ChatPageMain: add back button for mobile 2022-09-19 16:28:32 -05:00
Alex Gleason 4ea422abb5
ChatsPage: remove pb-36 2022-09-19 15:13:55 -05:00
Alex Gleason 9dc1a0caec
ChatPage: allow selecting a chat on mobile 2022-09-19 15:12:18 -05:00
Alex Gleason 19ef0fee20
ChatPage: size the height correctly for mobile 2022-09-19 15:02:16 -05:00
Alex Gleason d1b10f72aa
ChatPage: collapse on mobile 2022-09-19 14:56:23 -05:00
Alex Gleason ad521e528e
ChatListItem: prevent links from being clicked 2022-09-19 14:33:22 -05:00
Alex Gleason e42f0bc9b0
ChatPageMain: allow switching chats before onboarding 2022-09-19 14:19:46 -05:00
Alex Gleason 6ce7c0a8cb
Chats: clean up some eslint errors 2022-09-19 14:14:39 -05:00
Alex Gleason 23bbaf329b
UI: remove QueryClient (it's already in containers/soapbox, how did that happen?) 2022-09-19 13:04:51 -05:00
Alex Gleason d7243c0e91
Merge remote-tracking branch 'origin/develop' into chats 2022-09-19 13:01:40 -05:00
Justin 88d848ee17 Add welcome screen to Chats main page 2022-09-16 14:33:31 -04:00
Justin 9cb34dc45c Refactor ChatPage into multiple components 2022-09-16 10:22:43 -04:00
Justin acdb89e698 Move ChatPage into subfolder 2022-09-16 10:13:45 -04:00
Justin 4352d17217 Add snooze icon to ChatList 2022-09-16 08:57:09 -04:00
Justin 8e35d1dd92 Improve infinite scroll 2022-09-15 10:49:09 -04:00
Justin 6240ea5a23 Finish i18n for DMs 2022-09-14 10:35:32 -04:00
Justin a60d6770af Remove temp verification 2022-09-13 16:38:28 -04:00
Justin 5eab883fd1 Chats -> i18n 2022-09-13 16:33:34 -04:00
Justin ea1583dcac Fix chat silence bug 2022-09-13 16:24:19 -04:00
Justin 45afb665b9 Add chat settings to chat main page 2022-09-13 14:11:22 -04:00
Justin 0ae515ef18 Refactor ChatSearch and add various states 2022-09-13 11:55:13 -04:00
Justin 0952fe6dae Add Chat context api to main page 2022-09-13 11:18:46 -04:00
Justin 09d73b1c45 Refactor chat component naming 2022-09-12 16:46:19 -04:00
Justin 8e1aa9f9e8 Add dark mode support to main page 2022-09-12 15:33:08 -04:00
Justin 5b73afbc4e Remove unused prop 2022-09-12 15:05:19 -04:00
Justin 56c617bd32 Merge branch 'alex-chats' into chats 2022-09-12 14:50:02 -04:00
Justin 81bfc06990 Add tests 2022-09-12 14:42:15 -04:00
Justin a68aeb8464 Start changing the way search works 2022-09-12 14:42:06 -04:00
Justin 1c179cd4a0 Add error states 2022-09-08 12:47:19 -04:00
Justin c48b4adc81 Error handling for bad sends 2022-09-08 10:24:20 -04:00
Justin e333a5042e Merge branch 'chats' into alex-chats 2022-09-08 08:37:58 -04:00
Justin 6b38e37019 Merge remote-tracking branch 'origin/develop' into chats 2022-09-08 08:37:52 -04:00
Alex Gleason 0ac3b0824b
Add header to desktop chats 2022-09-01 13:17:31 -05:00
Alex Gleason 624720a7bc
ChatIndex: clamp to screen height-ish 2022-09-01 13:17:31 -05:00
Alex Gleason 90ece157e6
ChatIndex: improve the desktop layout 2022-09-01 13:17:31 -05:00
Alex Gleason 7fc732d0d0
Chat: fix various overflow issues 2022-09-01 13:17:31 -05:00
Alex Gleason 2a5a43d914
ChatIndex: break layout into columns 2022-09-01 13:17:30 -05:00
Alex Gleason bb535b10ed
Add ChatsPage for bigger layout 2022-09-01 13:17:30 -05:00
Alex Gleason 471ee4d179
Rename chats to messages 2022-09-01 13:17:30 -05:00
Alex Gleason 2f0a41cc36
ChatMessageList: fix horizontal overflow for long messages in UI 2022-09-01 13:17:30 -05:00
Alex Gleason 271bc271f7
Chats: normalize chat messages from the API 2022-09-01 13:17:30 -05:00
Alex Gleason 2f5caad67f
Chats: use compareId to sort messages (fix Pleroma) 2022-09-01 13:17:30 -05:00
Justin fc81cda6bb Fix classnames import 2022-08-31 13:24:01 -04:00
Justin c63fdec916 Reset state on failure 2022-08-31 13:22:43 -04:00
Justin 7535862a40 Autogrow the textarea 2022-08-31 13:22:41 -04:00
Justin 3939e27827 Add ability to copy the message 2022-08-31 13:22:18 -04:00
Justin 5dd44d3094 Add last_message_id param to API 2022-08-31 13:22:18 -04:00
Justin 2a02f6dcc7 Rename snooze endpoint 2022-08-31 13:22:18 -04:00
Justin cfa183531e Fix text alignment 2022-08-31 13:22:18 -04:00
Justin b04bc6a7ae Add shadow when scrolling 2022-08-31 13:22:18 -04:00
Justin 01167af69e Add infinite scroll to ChatList 2022-08-31 13:22:16 -04:00
Justin e384d1f40d Setup websockets 2022-08-31 13:21:43 -04:00
Justin 0f7cfada50 Improve dark mode of chats 2022-08-31 13:21:43 -04:00
Justin ba2ffd1501 Snooze 2022-08-31 13:21:43 -04:00
Justin e7bd56f959 Refactor 2022-08-31 13:21:43 -04:00
Justin a2e2d60fc7 Add Message List Intro component 2022-08-31 13:21:43 -04:00
Justin 396a1f1f46 Add Chat Settings 2022-08-31 13:21:43 -04:00
Justin d2d64e4ec4 Refactor and auto-accept chats 2022-08-31 13:21:43 -04:00
Justin ea5525d02c Refactor leave/report chat 2022-08-31 13:21:43 -04:00
Justin 0cb0e8af9e Add ability to leave chat 2022-08-31 13:21:43 -04:00
Justin 8492cc59e2 Add ability to accept chat 2022-08-31 13:21:43 -04:00
Justin 1ed1f3fd2e Add ability to delete message 2022-08-31 13:21:42 -04:00
Justin 7557445a3e Disable submit button 2022-08-31 13:20:54 -04:00
Justin 751c031420 Disable submit button 2022-08-31 13:20:54 -04:00
Justin 84dc06db42 d 2022-08-31 13:20:54 -04:00
Justin 3a48082dc9 Remove old React Query stuff 2022-08-31 13:20:54 -04:00
Justin 2c6c281568 Add "useDebounce" hook 2022-08-31 13:20:53 -04:00
Justin 27df2b617e Update Input with append and prepend props 2022-08-31 13:20:53 -04:00
Justin f0b3cc67aa Add "items-start" support to Stack 2022-08-31 13:20:53 -04:00
Justin 2f568ffc84 Extend Textarea component with resizeable prop 2022-08-31 13:20:53 -04:00
Justin 2aab3bb736 Change translations for chat 2022-08-31 13:20:53 -04:00
Alex Gleason 58322862e4 Make chat panes REALLY BIG 2022-08-31 13:20:53 -04:00
Alex Gleason 0b4fc43172 Chats: break out Pane into a UI component 2022-08-31 13:20:53 -04:00
Justin f16da850fd Add React Query 2022-08-31 13:20:53 -04: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
1006 zmienionych plików z 46502 dodań i 43603 usunięć

Wyświetl plik

@ -5,4 +5,4 @@
/tmp/**
/coverage/**
/custom/**
!.eslintrc.js
!.eslintrc.cjs

Wyświetl plik

@ -5,6 +5,7 @@ module.exports = {
'eslint:recommended',
'plugin:import/typescript',
'plugin:compat/recommended',
'plugin:tailwindcss/recommended',
],
env: {
@ -18,7 +19,7 @@ module.exports = {
ATTACHMENT_HOST: false,
},
parser: 'babel-eslint',
parser: '@babel/eslint-parser',
plugins: [
'react',
@ -43,7 +44,7 @@ module.exports = {
react: {
version: 'detect',
},
'import/extensions': ['.js', '.jsx', '.ts', '.tsx'],
'import/extensions': ['.js', '.jsx', '.cjs', '.mjs', '.ts', '.tsx'],
'import/ignore': [
'node_modules',
'\\.(css|scss|json)$',
@ -54,13 +55,17 @@ module.exports = {
},
},
polyfills: [
'es:all',
'fetch',
'IntersectionObserver',
'Promise',
'URL',
'URLSearchParams',
'es:all', // core-js
'fetch', // not polyfilled, but ignore it
'IntersectionObserver', // npm:intersection-observer
'Promise', // core-js
'ResizeObserver', // npm:resize-observer-polyfill
'URL', // core-js
'URLSearchParams', // core-js
],
tailwindcss: {
config: 'tailwind.config.cjs',
},
},
rules: {
@ -235,18 +240,7 @@ module.exports = {
},
],
'import/newline-after-import': 'error',
'import/no-extraneous-dependencies': [
'error',
// {
// devDependencies: [
// 'webpack/**',
// 'app/soapbox/test_setup.js',
// 'app/soapbox/test_helpers.js',
// 'app/**/__tests__/**',
// 'app/**/__mocks__/**',
// ],
// },
],
'import/no-extraneous-dependencies': 'error',
'import/no-unresolved': 'error',
'import/no-webpack-loader-syntax': 'error',
'import/order': [
@ -267,10 +261,30 @@ module.exports = {
},
],
'@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',
{
classRegex: '^(base|container|icon|item|list|outer|wrapper)?[c|C]lass(Name)?$',
config: 'tailwind.config.cjs',
},
],
'tailwindcss/migration-from-tailwind-2': 'error',
},
overrides: [
{

1
.gitattributes vendored 100644
Wyświetl plik

@ -0,0 +1 @@
CHANGELOG.md merge=union

Wyświetl plik

@ -3,6 +3,9 @@ image: node:18
variables:
NODE_ENV: test
default:
interruptible: true
cache: &cache
key:
files:
@ -15,6 +18,7 @@ stages:
- deps
- test
- deploy
- release
deps:
stage: deps
@ -32,6 +36,9 @@ danger:
# https://github.com/danger/danger-js/issues/1029#issuecomment-998915436
- export CI_MERGE_REQUEST_IID=${CI_OPEN_MERGE_REQUESTS#*!}
- npx danger ci
except:
variables:
- $CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME
allow_failure: true
lint-js:
@ -41,10 +48,12 @@ lint-js:
changes:
- "**/*.js"
- "**/*.jsx"
- "**/*.cjs"
- "**/*.mjs"
- "**/*.ts"
- "**/*.tsx"
- ".eslintignore"
- ".eslintrc.js"
- ".eslintrc.cjs"
lint-sass:
stage: test
@ -65,7 +74,7 @@ jest:
- "app/soapbox/**/*"
- "webpack/**/*"
- "custom/**/*"
- "jest.config.js"
- "jest.config.cjs"
- "package.json"
- "yarn.lock"
- ".gitlab-ci.yml"
@ -80,7 +89,8 @@ jest:
nginx-test:
stage: test
image: nginx:latest
before_script: cp installation/mastodon.conf /etc/nginx/conf.d/default.conf
before_script:
- cp installation/mastodon.conf /etc/nginx/conf.d/default.conf
script: nginx -t
only:
changes:
@ -88,7 +98,12 @@ nginx-test:
build-production:
stage: test
script: yarn build
script:
- yarn build
- yarn manage:translations en
# Fail if files got changed.
# https://stackoverflow.com/a/9066385
- git diff --quiet
variables:
NODE_ENV: production
artifacts:
@ -103,22 +118,11 @@ docs-deploy:
script:
- curl -X POST -F"token=$CI_JOB_TOKEN" -F'ref=master' https://gitlab.com/api/v4/projects/15685485/trigger/pipeline
only:
refs:
- develop
variables:
- $CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME
changes:
- "docs/**/*"
# Supposed to fail when translations are outdated, instead always passes
#
# i18n:
# stage: build
# script: yarn manage:translations
# variables:
# NODE_ENV: development
# before_script:
# - yarn
# - yarn build
review:
stage: deploy
environment:
@ -140,21 +144,33 @@ pages:
paths:
- public
only:
refs:
- develop
variables:
- $CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME
docker:
stage: deploy
image: docker:20.10.17
image: docker:23.0.0
services:
- docker:20.10.17-dind
- docker:23.0.0-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:
refs:
- develop
- 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
rules:
- if: $CI_COMMIT_TAG
script:
- npx ts-node ./scripts/do-release.ts
interruptible: false
include:
- template: Jobs/Dependency-Scanning.gitlab-ci.yml
- template: Security/License-Scanning.gitlab-ci.yml

Wyświetl plik

@ -0,0 +1,8 @@
## Summary
<!-- Describe your changes in detail -->
## Screenshots (if appropriate):
| Before | After |
| ------ | ----- |
| | |

Wyświetl plik

@ -1,5 +1,8 @@
{
"*.js": "eslint --cache",
"*.cjs": "eslint --cache",
"*.mjs": "eslint --cache",
"*.ts": "eslint --cache",
"*.tsx": "eslint --cache",
"app/styles/**/*.scss": "stylelint"
}

43
.storybook/main.ts 100644
Wyświetl plik

@ -0,0 +1,43 @@
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

@ -0,0 +1,22 @@
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

@ -1,16 +1,22 @@
{
"extends": ["stylelint-config-standard"],
"ignoreFiles": ["app/styles/reset.scss"],
"plugins": ["stylelint-scss"],
"extends": ["stylelint-config-standard-scss"],
"rules": {
"alpha-value-notation": null,
"at-rule-no-unknown": null,
"at-rule-empty-line-before": ["always", { "ignore": ["after-comment", "first-nested", "inside-block", "blockless-after-same-name-blockless", "blockless-after-blockless"] }],
"color-function-notation": null,
"custom-property-pattern": null,
"declaration-block-no-redundant-longhand-properties": null,
"declaration-colon-newline-after": null,
"declaration-empty-line-before": "never",
"font-family-no-missing-generic-family-keyword": [true, { "ignoreFontFamilies": ["ForkAwesome", "Font Awesome 5 Free", "OpenDyslexic", "soapbox"] }],
"font-family-no-missing-generic-family-keyword": [true, { "ignoreFontFamilies": ["ForkAwesome", "Font Awesome 5 Free"] }],
"max-line-length": null,
"no-descending-specificity": null,
"no-duplicate-selectors": null,
"scss/at-rule-no-unknown": [true, { "ignoreAtRules": ["/tailwind/", "layer"]}],
"no-invalid-position-at-import-rule": null
"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"
}
}

Wyświetl plik

@ -1 +1 @@
nodejs 18.2.0
nodejs 18.14.0

Wyświetl plik

@ -3,6 +3,7 @@
"dbaeumer.vscode-eslint",
"bradlc.vscode-tailwindcss",
"stylelint.vscode-stylelint",
"wix.vscode-import-cost"
"wix.vscode-import-cost",
"redhat.vscode-yaml"
]
}

14
.vscode/settings.json vendored
Wyświetl plik

@ -1,9 +1,21 @@
{
"css.validate": false,
"editor.insertSpaces": true,
"editor.tabSize": 2,
"files.associations": {
"*.conf.template": "properties"
},
"files.eol": "\n",
"files.insertFinalNewline": false
"files.insertFinalNewline": false,
"json.schemas": [
{
"fileMatch": [".lintstagedrc.json"],
"url": "https://json.schemastore.org/lintstagedrc.schema.json"
},
{
"fileMatch": ["renovate.json"],
"url": "https://docs.renovatebot.com/renovate-schema.json"
}
],
"scss.validate": false
}

Wyświetl plik

@ -4,6 +4,189 @@ 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
- Posts: Support posts filtering on recent Mastodon versions
- Reactions: Support custom emoji reactions
- Compatbility: Support Mastodon v2 timeline filters.
- Posts: Support dislikes on Friendica.
- UI: added a character counter to some textareas.
### Changed
- Posts: truncate Nostr pubkeys in reply mentions.
- Posts: upgraded emoji picker component.
- UI: unified design of "approve" and "reject" buttons in follow requests and waitlist.
### Fixed
- Posts: fixed emojis being cut off in reactions modal.
- Posts: fix audio player progress bar visibility.
- 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.
## [3.2.0] - 2023-02-15
### Added
- Admin: redirect the homepage to any URL.
- Compatibility: added compatibility with Friendica.
- Posts: bot badge on statuses from bot accounts.
- Compatibility: improved browser support for older browsers.
- Events: allow to repost events in event menu.
- 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.
- Chats: reset chat message field height after sending a message.
- Admin: allow to manage announcements.
### Changed
- Chats: improved display of media attachments.
- ServiceWorker: switch to a network-first strategy. The "An update is available!" prompt goes away.
- Posts: increased font size of focused status in threads.
- Posts: let "mute conversation" be clicked from any feed, not just noficiations.
- Posts: display all emoji reactions.
- Reactions: improved UI of reactions on statuses.
- Profile: make verified badge more prominent, overlapping with avatar.
### Fixed
- Admin: fixed hover card in reports modal shows reporter not reportee
- Chats: media attachments rendering at the wrong size and/or causing the chat to scroll on load.
- Chats: don't display "copy" button for messages without text.
- Posts: don't have to click the play button twice for embedded videos.
- 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.
## [3.1.0] - 2023-01-13
### Added
- Compatibility: rudimentary support for Takahē.
- UI: added backdrop blur behind modals.
- Admin: let admins configure media preview for attachment thumbnails.
- Login: accept `?server` param in external login, eg `fe.soapbox.pub/login/external?server=gleasonator.com`.
- Backups: restored Pleroma backups functionality.
- Export: restored "Export data" to CSV.
### Changed
- Posts: letterbox images to 19:6 again.
- Status Info: moved context (repost, pinned) to improve UX.
- Posts: remove file icon from empty link previews.
- Settings: moved "Import data" under settings.
- Composer: add more descriptive discard confirmation message.
### Fixed
- Layout: use accent color for "floating action button" (mobile compose button).
- ServiceWorker: don't serve favicon, robots.txt, and others from ServiceWorker.
- Datepicker: correctly default to the current year.
- Scheduled posts: fix page crashing on deleting a scheduled post.
- Events: don't crash when searching for a location.
- Search: fixes an abort error when using the navbar search component.
- Posts: fix monospace font in Markdown code blocks.
- Modals: fix action buttons overflow
- Editing: don't insert edited posts to the top of the feed.
- Editing: don't display edited posts as pending posts.
- Modals: close modal when navigating to a different page.
- Modals: fix "View context" button in media modal.
- Posts: let unauthenticated users to translate posts if allowed by backend.
- Chats: fix jumpy scrollbar.
- Composer: fix alignment of icon in submit button.
- Login: add a border around QR codes.
- Composer: don't display action button in reply indicator.
## [3.0.0] - 2022-12-25
### Added
- Editing: ability to edit posts and view edit history (on Rebased, Pleroma, and Mastodon).
- Events: ability to create, view, and comment on Events (on Rebased).
- Onboarding: display an introduction wizard to newly registered accounts.
- Posts: translate foreign language posts into your native language (on Rebased, Mastodon; if configured by the admin).
- Posts: ability to view quotes of a post (on Rebased).
- Posts: hover the "replying to" line to see a preview card of the parent post.
- Chats: ability to leave a chat (on Rebased, Truth Social).
- Chats: ability to disable chats for yourself.
- Layout: added right-to-left support for Arabic, Hebrew, Persian, and Central Kurdish languages.
- Composer: support custom emoji categories.
- Search: ability to search posts from a specific account (on Pleroma, Rebased).
- Theme: auto-detect system theme by default.
- Profile: remove a specific user from your followers (on Rebased, Mastodon).
- Suggestions: ability to view all suggested profiles.
- Feeds: display suggested accounts in Home feed (optional by admin).
- Compatibility: added compatibility with Truth Social, Fedibird, Pixelfed, Akkoma, and Glitch.
- Developers: added Test feed, Service Worker debugger, and Network Error preview.
- Reports: display server rules in reports. Let users select rule violations when submitting a report.
- Admin: added Theme Editor, a GUI for customizing the color scheme.
- Admin: custom badges. Admins can add non-federating badges to any user's profile (on Rebased, Pleroma).
- Admin: consolidated user dropdown actions (verify/suggest/etc) into a unified "Moderate User" modal.
- i18n: updated translations for Italian, Polish, Arabic, Hebrew, and German.
- Toast: added the ability to dismiss toast notifications.
### Changed
- UI: the whole UI has been overhauled both inside and out. 97% of the codebase has been rewritten to TypeScript, and a new component library has been introduced with Tailwind CSS.
- Chats: redesigned chats. Includes an improved desktop UI, unified chat widget, expanding textarea, and autosuggestions.
- Lists: ability to edit and delete a list.
- Settings: unified settings under one path with separate sections.
- Posts: changed the thumbs-up icon to a heart.
- Posts: move instance favicon beside username instead of post timestamp.
- Posts: changed the behavior of content warnings. CWs and sensitive media are unified into one design.
- Posts: redesigned interaction counters to use text instead of icons.
- Posts: letterbox images taller than 1:1.
- Profile: overhauled user profiles to be consistent with the rest of the UI.
- Composer: move emoji button alongside other composer buttons, add numerical counter.
- Birthdays: move today's birthdays out of notifications into right sidebar.
- Performance: improve scrolling/navigation between feeds by using a virtual window library.
- Admin: reorganize UI into 3-column layout.
- Admin: include external link to frontend repo for the running commit.
- Toast: redesigned toast notifications.
### Removed
- Theme: Halloween theme.
- Settings: advanced notification settings.
- Settings: dyslexic mode.
- Settings: demetricator.
- Profile: ability to set and view private notes on an account.
- Feeds: per-feed filters for replies, media, etc.
- Backup and export functionality (for now).
- Posts: hide non-emoji images embedded in post content.
### Security
- Glitch Social: fixed XSS vulnerability on Glitch Social where custom emojis could be exploited to embed a script tag.
## [2.0.0] - 2022-05-01
### Added
- Quote Posting: repost with comment on Fedibird and Rebased.
- Profile: ability to feature other users on your profile (on Rebased, Mastodon).
- Profile: ability to add location to the user's profile (on Rebased, Truth Social).
- Birthdays: ability to add a birthday to your profile (on Rebased, Pleroma).
- Birthdays: support for age-gated registration if configured by the admin (on Rebased, Pleroma).
- Birthdays: display today's birthdays in notifications.
- Notifications: added unread badge to favicon when user has notifications.
- Notifications: display full attachments in notifications instead of links.
- Search: added a dedicated search page with prefilled suggestions.
- Compatibility: improved support for Mastodon, added support for Mitra.
- Ethereum: Metamask sign-in with Mitra.
- i18n: added Shavian alphabet (`en-Shaw`) transliteration.
- i18n: added Icelandic translation.
### Changed
- Feeds: added gaps between posts in feeds.
- Feeds: automatically load new posts when scrolled to the top of the feed.
- Layout: improved design of top navigation bar.
- Layout: add left sidebar navigation.
- Icons: replaced Fork Awesome icons with Tabler icons.
- Posts: moved mentions out of the post content into an area above the post for replies (on Pleroma and Rebased - Mastodon falls back to the old behavior).
- Composer: use graphical ring counter for character count.
### Fixed
- Multi-Account: fix switching between profiles on different servers with the same local username.
## [1.3.0] - 2021-07-02
### Changed
- Layout: show right sidebar on all pages.

213
README.md
Wyświetl plik

@ -1,202 +1,81 @@
# Soapbox
![Soapbox Screenshot](soapbox-screenshot.png)
**Soapbox** is a frontend for Mastodon and Pleroma with a focus on custom branding and ease of use.
**Soapbox** is customizable open-source software that puts the power of social media in the hands of the people. Feature-rich and hyper-focused on providing a user experience to rival Big Tech, Soapbox is already home to some of the biggest alternative social platforms.
## Try it out
# On The Fediverse
Visit https://fe.soapbox.pub/ and point it to your favorite instance.
You may have heard of **Mastodon**. Soapbox builds upon what Mastodon made great to make something even better.
## :rocket: Deploy on Pleroma
You can run **Mastodon+Soapbox**, **Rebased+Soapbox**, and more.
Installing Soapbox on an existing Pleroma server is extremely easy.
Just ssh into the server and download a .zip of the latest build:
Soapbox is the **frontend** (what users see) while Mastodon is the **backend** (data, APIs). You can mix-and-match in the Fediverse ecosystem.
```sh
curl -L https://gitlab.com/soapbox-pub/soapbox/-/jobs/artifacts/develop/download?job=build-production -o soapbox.zip
```
> 💡 If you're starting a new server, we highly recommend **Rebased+Soapbox**. Rebased is our custom-built backend just for Soapbox, providing important new features such as **quote posting** and **chats**.
>
> See: [Installing Rebased+Soapbox](https://soapbox.pub/install/)
Then unpack it into Pleroma's `instance` directory:
# Try It Out
```sh
busybox unzip soapbox.zip -o -d /opt/pleroma/instance
```
Want to give Soapbox a shot? Here are some suggested servers:
**That's it!** :tada:
**Soapbox is installed.**
The change will take effect immediately, just refresh your browser tab.
It's not necessary to restart the Pleroma service.
- [gleasonator.com](https://gleasonator.com/) - operated by the lead developer of Soapbox
- [social.teci.world](https://social.teci.world/) - free speech server run by a Soapbox contributor
- [spinster.xyz](https://spinster.xyz/) - one of the largest feminist communities on the internet
- [poa.st](https://poa.st/) - the largest Soapbox server on the network
***For OTP releases,*** *unpack to /var/lib/pleroma instead.*
Want to use Soapbox against **any existing Mastodon/Pleroma server?** Try:
To remove Soapbox and revert to the default pleroma-fe, simply `rm /opt/pleroma/instance/static/index.html` (you can delete other stuff in there too, but be careful not to delete your own HTML files).
- [fe.soapbox.pub](https://fe.soapbox.pub) - enter your server's domain name to use Soapbox on any server!
## :elephant: Deploy on Mastodon
# 🚀 Starting Your Own Server
See [Installing Soapbox over Mastodon](https://docs.soapbox.pub/frontend/administration/mastodon/).
Starting your own server is one of the best ways to have freedom online! We recommend installing **Rebased+Soapbox**.
## How does it work?
See here for a detailed setup guide: [Installing Rebased+Soapbox](https://soapbox.pub/install/)
Soapbox is a [single-page application (SPA)](https://en.wikipedia.org/wiki/Single-page_application) that runs entirely in the browser with JavaScript.
# Adding Soapbox to an Existing Server
It has a single HTML file, `index.html`, responsible only for loading the required JavaScript and CSS.
It interacts with the backend through [XMLHttpRequest (XHR)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest).
Already have a server? No problem — it is still possible to use Soapbox.
Here is a simplified example with Nginx:
- [Deploying on Pleroma](https://docs.soapbox.pub/frontend/installing/#install-soapbox)
- [Deploying on Mastodon](https://docs.soapbox.pub/frontend/administration/mastodon/)
```nginx
location /api {
proxy_pass http://backend;
}
> 💡 If using Pleroma, it's recommended to [upgrade it to Rebased](https://gitlab.com/-/snippets/2411739). This comes with better support and many new features, helping you get the most out of Soapbox.
location / {
root /opt/soapbox;
try_files $uri index.html;
}
```
# Developing Soapbox
(See [`mastodon.conf`](https://gitlab.com/soapbox-pub/soapbox/-/blob/develop/installation/mastodon.conf) for a full example.)
tl;dr — `git clone`, `yarn`, and `yarn dev`.
Soapbox incorporates much of the [Mastodon API](https://docs.joinmastodon.org/methods/), [Pleroma API](https://api.pleroma.social/), and more.
It detects features supported by the backend to provide the right experience for the backend.
For detailed guides, see these pages:
# Running locally
1. [Soapbox local development](https://docs.soapbox.pub/frontend/development/running-locally/)
2. [yarn commands](https://docs.soapbox.pub/frontend/development/yarn-commands/)
3. [How it works](https://docs.soapbox.pub/frontend/development/how-it-works/)
4. [Environment variables](https://docs.soapbox.pub/frontend/development/local-config/)
5. [Developing a backend](https://docs.soapbox.pub/frontend/development/developing-backend/)
To get it running, just clone the repo:
```sh
git clone https://gitlab.com/soapbox-pub/soapbox.git
cd soapbox
```
Ensure that Node.js and Yarn are installed, then install dependencies:
```sh
yarn
```
Finally, run the dev server:
```sh
yarn dev
```
**That's it!** :tada:
It will serve at `http://localhost:3036` by default.
You should see an input box - just enter the domain name of your instance to log in.
Tip: you can even enter a local instance like `http://localhost:3000`!
### Troubleshooting: `ERROR: NODE_ENV must be set`
Create a `.env` file if you haven't already.
```sh
cp .env.example .env
```
And ensure that it contains `NODE_ENV=development`.
Try again.
### Troubleshooting: it's not working!
Run `node -V` and compare your Node.js version with the version in [`.tool-versions`](https://gitlab.com/soapbox-pub/soapbox/-/blob/develop/.tool-versions).
If they don't match, try installing [asdf](https://asdf-vm.com/).
## Local Dev Configuration
The following configuration variables are supported supported in local development.
Edit `.env` to set them.
All configuration is optional, except `NODE_ENV`.
#### `NODE_ENV`
The Node environment.
Soapbox checks for the following options:
- `development` - What you should use while developing Soapbox.
- `production` - Use when compiling to deploy to a live server.
- `test` - Use when running automated tests.
#### `BACKEND_URL`
URL to the backend server.
Can be http or https, and can include a port.
For https, be sure to also set `PROXY_HTTPS_INSECURE=true`.
**Default:** `http://localhost:4000`
#### `PROXY_HTTPS_INSECURE`
Allows using an HTTPS backend if set to `true`.
This is needed if `BACKEND_URL` is set to an `https://` value.
[More info](https://stackoverflow.com/a/48624590/8811886).
**Default:** `false`
# Yarn Commands
The following commands are supported.
You must set `NODE_ENV` to use these commands.
To do so, you can add the following line to your `.env` file:
```sh
NODE_ENV=development
```
#### Local dev server
- `yarn dev` - Run the local dev server.
#### Building
- `yarn build` - Compile without a dev server, into `/static` directory.
#### Translations
- `yarn manage:translations` - Normalizes translation files. Should always be run after editing i18n strings.
#### Tests
- `yarn test:all` - Runs all tests and linters.
- `yarn test` - Runs Jest for frontend unit tests.
- `yarn lint` - Runs all linters.
- `yarn lint:js` - Runs only JavaScript linter.
- `yarn lint:sass` - Runs only SASS linter.
# Contributing
## Contributing
We welcome contributions to this project.
To contribute, see [Contributing to Soapbox](docs/contributing.md).
# Customization
Translators can help by providing [translations through Weblate](https://hosted.weblate.org/projects/soapbox-pub/soapbox/).
Native speakers from all around the world are welcome!
Soapbox supports customization of the user interface, to allow per-instance branding and other features.
Some examples include:
# Project Philosophy
- Instance name
- Site logo
- Favicon
- About page
- Terms of Service page
- Privacy Policy page
- Copyright Policy (DMCA) page
- Promo panel list items, e.g. blog site link
- Soapbox extensions, e.g. Patron module
- Default settings, e.g. default theme
Soapbox was born out of the need to build independent platforms with **a unique identity and brand**.
More details can be found in [Customizing Soapbox](docs/customization.md).
This is in contrast to Mastodon's idea, where all servers are called "Mastodon" and use the Mastodon colors and logo. Users won't see the word "Soapbox" throughout the UI, they'll see the name of **your website** and your logo. To facilitate this, Soapbox has a robust customization UI and integrated moderation tools. Large servers are a priority.
One disadvantage of this approach is that it does not help the software spread. Some of the biggest servers on the network and running Soapbox and people don't even know it!
# License & Credits
Soapbox is based on [Gab Social](https://code.gab.com/gab/social/gab-social)'s frontend which is in turn based on [Mastodon](https://github.com/tootsuite/mastodon/)'s frontend.
- `static/sounds/chat.mp3` and `static/sounds/chat.oga` are from [notificationsounds.com](https://notificationsounds.com/notification-sounds/intuition-561) licensed under CC BY 4.0.
© Alex Gleason & other Soapbox contributors
© Eugen Rochko & other Mastodon contributors
© Trump Media & Technology Group
© 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
@ -205,8 +84,8 @@ the Free Software Foundation, either version 3 of the License, or
Soapbox is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with Soapbox. If not, see <https://www.gnu.org/licenses/>.
along with Soapbox. If not, see <https://www.gnu.org/licenses/>.

Wyświetl plik

@ -1,17 +0,0 @@
import loadPolyfills from './soapbox/load-polyfills';
// Load iframe event listener
require('./soapbox/iframe');
// @ts-ignore
require.context('./assets/images/', true);
// Load stylesheet
require('react-datepicker/dist/react-datepicker.css');
require('./styles/application.scss');
loadPolyfills().then(() => {
require('./soapbox/main').default();
}).catch(e => {
console.error(e);
});

Wyświetl plik

@ -1,94 +0,0 @@
Copyright (c) 2019-07-29, Abbie Gonzalez (https://abbiecod.es|support@abbiecod.es),
with Reserved Font Name OpenDyslexic.
Copyright (c) 12/2012 - 2019
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

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

Wyświetl plik

@ -1 +1,107 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 95 95" width="100" height="100"><path d="M94.909 19.374C94.909 8.674 86.235 0 75.534 0c-10.647 0-19.28 8.591-19.365 19.217l-15.631 2.09c-1.961-6.007-7.598-10.35-14.258-10.35-8.284 0-15.002 6.716-15.002 15.002 0 6.642 4.321 12.267 10.303 14.24l-2.205 16.056c-10.66.049-19.285 8.7-19.285 19.37C.091 86.325 8.765 95 19.466 95c10.677 0 19.332-8.638 19.37-19.304l18.093-2.501c1.979 5.972 7.598 10.285 14.234 10.285 8.284 0 15.002-6.716 15.002-15.002 0-6.891-4.652-12.682-10.983-14.441l1.365-15.339c10.229-.53 18.363-8.966 18.363-19.324zM56.194 67.8l-18.116 2.505a19.39 19.39 0 0 0-13.312-13.3l2.205-16.077a14.98 14.98 0 0 0 14.27-14.222l15.655-2.094c1.894 6.757 7.351 12.009 14.225 13.612l-1.365 15.322c-7.4.688-13.224 6.753-13.562 14.254z" fill="#ffffff"/></svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
id="svg2"
style="clip-rule:evenodd;fill-rule:evenodd;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
sodipodi:docname="soapbox-logo-white.svg"
xml:space="preserve"
version="1.1"
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
viewBox="0 0 100 100"
width="100"
height="100"
inkscape:export-filename="/home/miklobit/Downloads/citizen4/logo/citizen4-logo-250px.png"
inkscape:export-xdpi="63.5"
inkscape:export-ydpi="63.5"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"><sodipodi:namedview
id="namedview12"
bordercolor="#666666"
inkscape:pageshadow="2"
guidetolerance="10"
pagecolor="#ffffff"
gridtolerance="10"
inkscape:zoom="5.0135101"
objecttolerance="10"
borderopacity="1"
inkscape:current-layer="g1133"
inkscape:cx="54.253406"
inkscape:cy="42.086282"
inkscape:window-width="1920"
showgrid="false"
inkscape:pageopacity="0"
inkscape:window-height="1016"
inkscape:document-rotation="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-x="0"
inkscape:window-y="36"
inkscape:window-maximized="1"
units="mm"
inkscape:showpageshadow="2"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="px" />
<defs
id="defs4">
<style
id="style6"
type="text/css">
.fil0 {fill:black}
</style>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath932"><g
id="g936"
style="fill:#ffffff;stroke:#000000;stroke-width:0.468608;stroke-miterlimit:4;stroke-dasharray:none"
transform="matrix(40.327178,0,0,40.327178,-206.26309,-5.404074)">
<path
id="path934"
sodipodi:nodetypes="ccccc"
style="fill:#ffffff;stroke:#000000;stroke-width:0.468608;stroke-miterlimit:4;stroke-dasharray:none"
d="M 4.25,1.3382 0.4955,2.4662 C 0.58759,5.2588 1.2884,8.6655 4.25,9.6618 7.2442,8.694 7.8774,5.2291 8.0045,2.4662 Z" />
</g></clipPath><clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath932-3"><g
id="g936-6"
style="fill:#ffffff;stroke:#000000;stroke-width:0.468608;stroke-miterlimit:4;stroke-dasharray:none"
transform="matrix(40.327178,0,0,40.327178,-206.26309,-5.404074)"><path
id="path934-7"
sodipodi:nodetypes="ccccc"
style="fill:#ffffff;stroke:#000000;stroke-width:0.468608;stroke-miterlimit:4;stroke-dasharray:none"
d="M 4.25,1.3382 0.4955,2.4662 C 0.58759,5.2588 1.2884,8.6655 4.25,9.6618 7.2442,8.694 7.8774,5.2291 8.0045,2.4662 Z" /></g></clipPath>
</defs>
<metadata
id="metadata7"><rdf:RDF><cc:Work><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><cc:license
rdf:resource="http://creativecommons.org/licenses/by-nc-sa/4.0/" /><dc:date>2023-02-18T14:20:55</dc:date><dc:source>https://soc.citizen4.eu</dc:source><dc:subject><rdf:Bag><rdf:li>citizen4</rdf:li><rdf:li>logo</rdf:li><rdf:li>shield</rdf:li></rdf:Bag></dc:subject><dc:creator><cc:Agent><dc:title>miklo</dc:title></cc:Agent></dc:creator><dc:description>Citizen4 logo</dc:description></cc:Work><cc:License
rdf:about="http://creativecommons.org/licenses/by-nc-sa/4.0/"><cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" /><cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" /><cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" /><cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" /><cc:prohibits
rdf:resource="http://creativecommons.org/ns#CommercialUse" /><cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /><cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" /></cc:License></rdf:RDF></metadata><g
inkscape:groupmode="layer"
id="g1133"
inkscape:label="citizen4"
style="display:inline;fill:#ffffff"
transform="translate(9.1709534,9.343974)"><g
id="g1149"
transform="matrix(0.28130772,0,0,0.28130772,-1.9206898,-6.7154381)"
style="fill:#ffffff"><path
id="path1127"
style="fill:#ffffff;fill-opacity:1;stroke-width:2.298"
d="m 233.61288,175.15307 h -30.0693 v -8.40148 h -35.71547 v -22.85127 h 35.71317 v -8.40148 h 30.0716 c 1.31445,0 2.42898,0.4596 3.34818,1.3765 0.9169,0.9215 1.3788,2.03832 1.3788,3.34818 v 30.20487 c 0,1.22484 -0.4596,2.32098 -1.3788,3.28154 -0.9192,0.95827 -2.03602,1.44314 -3.34818,1.44314 z m 18.90793,-30.07388 c 6.91237,0 10.37315,3.41253 10.37315,10.24447 0,6.83195 -3.45618,10.24217 -10.37315,10.24217 -6.82735,0 -10.24218,-3.41482 -10.24218,-10.24217 0,-6.82734 3.41483,-10.24447 10.24218,-10.24447 z M 70.322893,175.15307 h 30.069297 v -8.40148 h 35.71546 v -22.85127 h -35.71317 v -8.40148 H 70.322893 c -1.31446,0 -2.42898,0.4596 -3.34818,1.3765 -0.9169,0.9215 -1.3788,2.03832 -1.3788,3.34818 v 30.20487 c 0,1.22484 0.4596,2.32098 1.3788,3.28154 0.9192,0.95827 2.03602,1.44314 3.34818,1.44314 z m -18.90793,-30.07388 c -6.91237,0 -10.37315,3.41253 -10.37315,10.24447 0,6.83195 3.45618,10.24217 10.37315,10.24217 6.82735,0 10.24218,-3.41482 10.24218,-10.24217 0,-6.82734 -3.41483,-10.24447 -10.24218,-10.24447 z M 171.79501,73.680969 v 30.069301 h -8.40148 v 35.71546 h -22.85128 v -35.71317 h -8.40147 V 73.680969 c 0,-1.31445 0.45959,-2.42898 1.37649,-3.34818 0.9215,-0.9169 2.03832,-1.3788 3.34819,-1.3788 h 30.20487 c 1.22483,0 2.32097,0.4596 3.28153,1.3788 0.95827,0.9192 1.44315,2.03602 1.44315,3.34818 z m -30.07388,-18.90793 c 0,-6.91237 3.41252,-10.37315 10.24446,-10.37315 6.83195,0 10.24218,3.45618 10.24218,10.37315 0,6.82735 -3.41482,10.24218 -10.24218,10.24218 -6.82734,0 -10.24446,-3.41483 -10.24446,-10.24218 z m 30.07388,182.197911 v -30.06929 h -8.40148 v -35.71547 h -22.85128 v 35.71317 h -8.40147 v 30.07159 c 0,1.31446 0.45959,2.42898 1.37649,3.34818 0.9215,0.9169 2.03832,1.3788 3.34819,1.3788 h 30.20487 c 1.22483,0 2.32097,-0.4596 3.28153,-1.3788 0.95827,-0.9192 1.44315,-2.03602 1.44315,-3.34818 z m -30.07388,18.90793 c 0,6.91237 3.41252,10.37315 10.24446,10.37315 6.83195,0 10.24218,-3.45618 10.24218,-10.37315 0,-6.82735 -3.41482,-10.24218 -10.24218,-10.24218 -6.82734,0 -10.24446,3.41483 -10.24446,10.24218 z M 151.92079,0.52207567 0.51240486,46.01113 C 4.2261345,158.6288 32.487823,296.01139 151.92079,336.18936 272.66842,297.16072 298.20359,157.43109 303.32917,46.01113 Z" /></g></g></svg>

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 812 B

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 6.7 KiB

Wyświetl plik

@ -1 +1,127 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 95 95" width="100" height="100"><path d="M94.909 19.374C94.909 8.674 86.235 0 75.534 0c-10.647 0-19.28 8.591-19.365 19.217l-15.631 2.09c-1.961-6.007-7.598-10.35-14.258-10.35-8.284 0-15.002 6.716-15.002 15.002 0 6.642 4.321 12.267 10.303 14.24l-2.205 16.056c-10.66.049-19.285 8.7-19.285 19.37C.091 86.325 8.765 95 19.466 95c10.677 0 19.332-8.638 19.37-19.304l18.093-2.501c1.979 5.972 7.598 10.285 14.234 10.285 8.284 0 15.002-6.716 15.002-15.002 0-6.891-4.652-12.682-10.983-14.441l1.365-15.339c10.229-.53 18.363-8.966 18.363-19.324zM56.194 67.8l-18.116 2.505a19.39 19.39 0 0 0-13.312-13.3l2.205-16.077a14.98 14.98 0 0 0 14.27-14.222l15.655-2.094c1.894 6.757 7.351 12.009 14.225 13.612l-1.365 15.322c-7.4.688-13.224 6.753-13.562 14.254z" fill="#0482d8"/></svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
id="svg2"
style="clip-rule:evenodd;fill-rule:evenodd;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
sodipodi:docname="soapbox-logo.svg"
xml:space="preserve"
version="1.1"
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
viewBox="0 0 100 100"
width="100"
height="100"
inkscape:export-filename="/home/miklobit/Downloads/citizen4/logo/citizen4-logo-250px.png"
inkscape:export-xdpi="63.5"
inkscape:export-ydpi="63.5"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"><sodipodi:namedview
id="namedview12"
bordercolor="#666666"
inkscape:pageshadow="2"
guidetolerance="10"
pagecolor="#ffffff"
gridtolerance="10"
inkscape:zoom="5.0135101"
objecttolerance="10"
borderopacity="1"
inkscape:current-layer="svg2"
inkscape:cx="54.253406"
inkscape:cy="42.086282"
inkscape:window-width="1920"
showgrid="false"
inkscape:pageopacity="0"
inkscape:window-height="1016"
inkscape:document-rotation="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-x="0"
inkscape:window-y="36"
inkscape:window-maximized="1"
units="mm"
inkscape:showpageshadow="2"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="px" />
<defs
id="defs4">
<style
id="style6"
type="text/css">
.fil0 {fill:black}
</style>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath932"><g
id="g936"
style="fill:#ffffff;stroke:#000000;stroke-width:0.468608;stroke-miterlimit:4;stroke-dasharray:none"
transform="matrix(40.327178,0,0,40.327178,-206.26309,-5.404074)">
<path
id="path934"
sodipodi:nodetypes="ccccc"
style="fill:#ffffff;stroke:#000000;stroke-width:0.468608;stroke-miterlimit:4;stroke-dasharray:none"
d="M 4.25,1.3382 0.4955,2.4662 C 0.58759,5.2588 1.2884,8.6655 4.25,9.6618 7.2442,8.694 7.8774,5.2291 8.0045,2.4662 Z" />
</g></clipPath><clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath932-3"><g
id="g936-6"
style="fill:#ffffff;stroke:#000000;stroke-width:0.468608;stroke-miterlimit:4;stroke-dasharray:none"
transform="matrix(40.327178,0,0,40.327178,-206.26309,-5.404074)"><path
id="path934-7"
sodipodi:nodetypes="ccccc"
style="fill:#ffffff;stroke:#000000;stroke-width:0.468608;stroke-miterlimit:4;stroke-dasharray:none"
d="M 4.25,1.3382 0.4955,2.4662 C 0.58759,5.2588 1.2884,8.6655 4.25,9.6618 7.2442,8.694 7.8774,5.2291 8.0045,2.4662 Z" /></g></clipPath>
</defs>
<metadata
id="metadata7"><rdf:RDF><cc:Work><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><cc:license
rdf:resource="http://creativecommons.org/licenses/by-nc-sa/4.0/" /><dc:date>2023-02-18T14:20:55</dc:date><dc:source>https://soc.citizen4.eu</dc:source><dc:subject><rdf:Bag><rdf:li>citizen4</rdf:li><rdf:li>logo</rdf:li><rdf:li>shield</rdf:li></rdf:Bag></dc:subject><dc:creator><cc:Agent><dc:title>miklo</dc:title></cc:Agent></dc:creator><dc:description>Citizen4 logo</dc:description></cc:Work><cc:License
rdf:about="http://creativecommons.org/licenses/by-nc-sa/4.0/"><cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" /><cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" /><cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" /><cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" /><cc:prohibits
rdf:resource="http://creativecommons.org/ns#CommercialUse" /><cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /><cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" /></cc:License></rdf:RDF></metadata><g
inkscape:groupmode="layer"
id="layer1"
inkscape:label="shield"
style="display:inline"
transform="translate(9.1709534,9.343974)"><g
id="g912"
style="clip-rule:evenodd;fill:#003399;fill-opacity:1;fill-rule:evenodd;stroke:#888888;stroke-width:0.468608;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
transform="matrix(11.344346,0,0,11.344346,-7.3976698,-21.749578)"><path
id="path910"
sodipodi:nodetypes="ccccc"
style="fill:#003399;fill-opacity:1;stroke:#888888;stroke-width:0.468608;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 4.25,1.3382 0.4955,2.4662 C 0.58759,5.2588 1.2884,8.6655 4.25,9.6618 7.2442,8.694 7.8774,5.2291 8.0045,2.4662 Z" /></g></g><g
inkscape:groupmode="layer"
id="g1133"
inkscape:label="citizen2"
style="display:inline"
transform="translate(9.1709534,9.343974)"><g
id="g1149"
transform="matrix(0.28130772,0,0,0.28130772,-1.9206898,-6.7154381)"><path
id="path1119"
style="fill:#ffcc00;fill-opacity:1;stroke-width:2.298"
d="m 171.79501,236.97095 v -30.06929 h -8.40148 v -35.71547 h -22.85128 v 35.71317 h -8.40147 v 30.07159 c 0,1.31446 0.45959,2.42898 1.37649,3.34818 0.9215,0.9169 2.03832,1.3788 3.34819,1.3788 h 30.20487 c 1.22483,0 2.32097,-0.4596 3.28153,-1.3788 0.95827,-0.9192 1.44315,-2.03602 1.44315,-3.34818 z m -30.07388,18.90793 c 0,6.91237 3.41252,10.37315 10.24446,10.37315 6.83195,0 10.24218,-3.45618 10.24218,-10.37315 0,-6.82735 -3.41482,-10.24218 -10.24218,-10.24218 -6.82734,0 -10.24446,3.41483 -10.24446,10.24218 z" /><path
id="path1121"
style="fill:#ffcc00;fill-opacity:1;stroke-width:2.298"
d="m 171.79501,73.680969 v 30.069301 h -8.40148 v 35.71546 h -22.85128 v -35.71317 h -8.40147 V 73.680969 c 0,-1.31445 0.45959,-2.42898 1.37649,-3.34818 0.9215,-0.9169 2.03832,-1.3788 3.34819,-1.3788 h 30.20487 c 1.22483,0 2.32097,0.4596 3.28153,1.3788 0.95827,0.9192 1.44315,2.03602 1.44315,3.34818 z m -30.07388,-18.90793 c 0,-6.91237 3.41252,-10.37315 10.24446,-10.37315 6.83195,0 10.24218,3.45618 10.24218,10.37315 0,6.82735 -3.41482,10.24218 -10.24218,10.24218 -6.82734,0 -10.24446,-3.41483 -10.24446,-10.24218 z" /><path
id="path1125"
style="fill:#ffcc00;fill-opacity:1;stroke-width:2.298"
d="m 70.322893,175.15307 h 30.069297 v -8.40148 h 35.71546 v -22.85127 h -35.71317 v -8.40148 H 70.322893 c -1.31446,0 -2.42898,0.4596 -3.34818,1.3765 -0.9169,0.9215 -1.3788,2.03832 -1.3788,3.34818 v 30.20487 c 0,1.22484 0.4596,2.32098 1.3788,3.28154 0.9192,0.95827 2.03602,1.44314 3.34818,1.44314 z m -18.90793,-30.07388 c -6.91237,0 -10.37315,3.41253 -10.37315,10.24447 0,6.83195 3.45618,10.24217 10.37315,10.24217 6.82735,0 10.24218,-3.41482 10.24218,-10.24217 0,-6.82734 -3.41483,-10.24447 -10.24218,-10.24447 z" /><path
id="path1127"
style="fill:#ffcc00;fill-opacity:1;stroke-width:2.298"
d="m 233.61288,175.15307 h -30.0693 v -8.40148 h -35.71547 v -22.85127 h 35.71317 v -8.40148 h 30.0716 c 1.31445,0 2.42898,0.4596 3.34818,1.3765 0.9169,0.9215 1.3788,2.03832 1.3788,3.34818 v 30.20487 c 0,1.22484 -0.4596,2.32098 -1.3788,3.28154 -0.9192,0.95827 -2.03602,1.44314 -3.34818,1.44314 z m 18.90793,-30.07388 c 6.91237,0 10.37315,3.41253 10.37315,10.24447 0,6.83195 -3.45618,10.24217 -10.37315,10.24217 -6.82735,0 -10.24218,-3.41482 -10.24218,-10.24217 0,-6.82734 3.41483,-10.24447 10.24218,-10.24447 z" /></g></g></svg>

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 812 B

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 7.6 KiB

Wyświetl plik

@ -0,0 +1,6 @@
# Sound licenses
- `chat.mp3`
- `chat.oga`
© [notificationsounds.com](https://notificationsounds.com/notification-sounds/intuition-561), licensed under [CC BY 4.0](https://creativecommons.org/licenses/by-sa/4.0/).

Wyświetl plik

@ -5,7 +5,6 @@
<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">
<meta name="referrer" content="same-origin" />
<link href="/manifest.json" rel="manifest">
<!--server-generated-meta-->
<%= snippets %>

Wyświetl plik

@ -0,0 +1,16 @@
{
"note": "patriots 900000001",
"discoverable": true,
"id": "109989480368015378",
"domain": null,
"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",
"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",
"group_visibility": "everyone",
"created_at": "2023-03-08T00:00:00.000Z",
"display_name": "PATRIOT PATRIOTS",
"membership_required": true,
"members_count": 1,
"tags": []
}

Wyświetl plik

@ -0,0 +1,166 @@
import { render } from '@testing-library/react';
import { AxiosError } from 'axios';
import React from 'react';
import { IntlProvider } from 'react-intl';
import { act, screen } from 'soapbox/jest/test-helpers';
function renderApp() {
const { Toaster } = require('react-hot-toast');
const toast = require('../toast').default;
return {
toast,
...render(
<IntlProvider locale='en'>
<Toaster />,
</IntlProvider>,
),
};
}
beforeAll(() => {
jest.spyOn(console, 'error').mockImplementation(() => {});
});
afterEach(() => {
(console.error as any).mockClear();
});
afterAll(() => {
(console.error as any).mockRestore();
});
describe('toasts', () =>{
it('renders successfully', async() => {
const { toast } = renderApp();
act(() => {
toast.success('hello');
});
expect(screen.getByTestId('toast')).toBeInTheDocument();
expect(screen.getByTestId('toast-message')).toHaveTextContent('hello');
});
describe('actionable button', () => {
it('renders the button', async() => {
const { toast } = renderApp();
act(() => {
toast.success('hello', { action: () => null, actionLabel: 'click me' });
});
expect(screen.getByTestId('toast-action')).toHaveTextContent('click me');
});
it('does not render the button', async() => {
const { toast } = renderApp();
act(() => {
toast.success('hello');
});
expect(screen.queryAllByTestId('toast-action')).toHaveLength(0);
});
});
describe('showAlertForError()', () => {
const buildError = (message: string, status: number) => new AxiosError<any>(message, String(status), undefined, null, {
data: {
error: message,
},
statusText: String(status),
status,
headers: {},
config: {},
});
describe('with a 502 status code', () => {
it('renders the correct message', async() => {
const message = 'The server is down';
const error = buildError(message, 502);
const { toast } = renderApp();
act(() => {
toast.showAlertForError(error);
});
expect(screen.getByTestId('toast')).toBeInTheDocument();
expect(screen.getByTestId('toast-message')).toHaveTextContent('The server is down');
});
});
describe('with a 404 status code', () => {
it('renders the correct message', async() => {
const error = buildError('', 404);
const { toast } = renderApp();
act(() => {
toast.showAlertForError(error);
});
expect(screen.queryAllByTestId('toast')).toHaveLength(0);
});
});
describe('with a 410 status code', () => {
it('renders the correct message', async() => {
const error = buildError('', 410);
const { toast } = renderApp();
act(() => {
toast.showAlertForError(error);
});
expect(screen.queryAllByTestId('toast')).toHaveLength(0);
});
});
describe('with an accepted status code', () => {
describe('with a message from the server', () => {
it('renders the correct message', async() => {
const message = 'custom message';
const error = buildError(message, 200);
const { toast } = renderApp();
act(() => {
toast.showAlertForError(error);
});
expect(screen.getByTestId('toast')).toBeInTheDocument();
expect(screen.getByTestId('toast-message')).toHaveTextContent(message);
});
});
describe('without a message from the server', () => {
it('renders the correct message', async() => {
const message = 'The request has been accepted for processing';
const error = buildError(message, 202);
const { toast } = renderApp();
act(() => {
toast.showAlertForError(error);
});
expect(screen.getByTestId('toast')).toBeInTheDocument();
expect(screen.getByTestId('toast-message')).toHaveTextContent(message);
});
});
});
describe('without a response', () => {
it('renders the default message', async() => {
const error = new AxiosError();
const { toast } = renderApp();
act(() => {
toast.showAlertForError(error);
});
expect(screen.getByTestId('toast')).toBeInTheDocument();
expect(screen.getByTestId('toast-message')).toHaveTextContent('An unexpected error occurred.');
});
});
});
});

Wyświetl plik

@ -1,146 +0,0 @@
import { AxiosError } from 'axios';
import { mockStore, rootState } from 'soapbox/jest/test-helpers';
import { dismissAlert, showAlert, showAlertForError } from '../alerts';
const buildError = (message: string, status: number) => new AxiosError<any>(message, String(status), undefined, null, {
data: {
error: message,
},
statusText: String(status),
status,
headers: {},
config: {},
});
let store: ReturnType<typeof mockStore>;
beforeEach(() => {
const state = rootState;
store = mockStore(state);
});
describe('dismissAlert()', () => {
it('dispatches the proper actions', async() => {
const alert = 'hello world';
const expectedActions = [
{ type: 'ALERT_DISMISS', alert },
];
await store.dispatch(dismissAlert(alert as any));
const actions = store.getActions();
expect(actions).toEqual(expectedActions);
});
});
describe('showAlert()', () => {
it('dispatches the proper actions', async() => {
const title = 'title';
const message = 'msg';
const severity = 'info';
const expectedActions = [
{ type: 'ALERT_SHOW', title, message, severity },
];
await store.dispatch(showAlert(title, message, severity));
const actions = store.getActions();
expect(actions).toEqual(expectedActions);
});
});
describe('showAlert()', () => {
describe('with a 502 status code', () => {
it('dispatches the proper actions', async() => {
const message = 'The server is down';
const error = buildError(message, 502);
const expectedActions = [
{ type: 'ALERT_SHOW', title: '', message, severity: 'error' },
];
await store.dispatch(showAlertForError(error));
const actions = store.getActions();
expect(actions).toEqual(expectedActions);
});
});
describe('with a 404 status code', () => {
it('dispatches the proper actions', async() => {
const error = buildError('', 404);
await store.dispatch(showAlertForError(error));
const actions = store.getActions();
expect(actions).toEqual([]);
});
});
describe('with a 410 status code', () => {
it('dispatches the proper actions', async() => {
const error = buildError('', 410);
await store.dispatch(showAlertForError(error));
const actions = store.getActions();
expect(actions).toEqual([]);
});
});
describe('with an accepted status code', () => {
describe('with a message from the server', () => {
it('dispatches the proper actions', async() => {
const message = 'custom message';
const error = buildError(message, 200);
const expectedActions = [
{ type: 'ALERT_SHOW', title: '', message, severity: 'error' },
];
await store.dispatch(showAlertForError(error));
const actions = store.getActions();
expect(actions).toEqual(expectedActions);
});
});
describe('without a message from the server', () => {
it('dispatches the proper actions', async() => {
const message = 'The request has been accepted for processing';
const error = buildError(message, 202);
const expectedActions = [
{ type: 'ALERT_SHOW', title: '', message, severity: 'error' },
];
await store.dispatch(showAlertForError(error));
const actions = store.getActions();
expect(actions).toEqual(expectedActions);
});
});
});
describe('without a response', () => {
it('dispatches the proper actions', async() => {
const error = new AxiosError();
const expectedActions = [
{
type: 'ALERT_SHOW',
title: {
defaultMessage: 'Oops!',
id: 'alert.unexpected.title',
},
message: {
defaultMessage: 'An unexpected error occurred.',
id: 'alert.unexpected.message',
},
severity: 'error',
},
];
await store.dispatch(showAlertForError(error));
const actions = store.getActions();
expect(actions).toEqual(expectedActions);
});
});
});

Wyświetl plik

@ -46,13 +46,6 @@ describe('uploadCompose()', () => {
const expectedActions = [
{ type: 'COMPOSE_UPLOAD_REQUEST', id: 'home', skipLoading: true },
{
type: 'ALERT_SHOW',
message: 'Image exceeds the current file size limit (10 Bytes)',
actionLabel: undefined,
actionLink: undefined,
severity: 'error',
},
{ type: 'COMPOSE_UPLOAD_FAIL', id: 'home', error: true, skipLoading: true },
];
@ -99,13 +92,6 @@ describe('uploadCompose()', () => {
const expectedActions = [
{ type: 'COMPOSE_UPLOAD_REQUEST', id: 'home', skipLoading: true },
{
type: 'ALERT_SHOW',
message: 'Video exceeds the current file size limit (10 Bytes)',
actionLabel: undefined,
actionLink: undefined,
severity: 'error',
},
{ type: 'COMPOSE_UPLOAD_FAIL', id: 'home', error: true, skipLoading: true },
];

Wyświetl plik

@ -2,7 +2,9 @@ import { Map as ImmutableMap } from 'immutable';
import { __stub } from 'soapbox/api';
import { mockStore, rootState } from 'soapbox/jest/test-helpers';
import { AccountRecord } from 'soapbox/normalizers';
import { AuthUserRecord, ReducerRecord } from '../../reducers/auth';
import {
fetchMe, patchMe,
} from '../me';
@ -38,18 +40,18 @@ describe('fetchMe()', () => {
beforeEach(() => {
const state = rootState
.set('auth', ImmutableMap({
.set('auth', ReducerRecord({
me: accountUrl,
users: ImmutableMap({
[accountUrl]: ImmutableMap({
[accountUrl]: AuthUserRecord({
'access_token': token,
}),
}),
}))
.set('accounts', ImmutableMap({
[accountUrl]: {
[accountUrl]: AccountRecord({
url: accountUrl,
},
}),
}) as any);
store = mockStore(state);
});
@ -112,4 +114,4 @@ describe('patchMe()', () => {
expect(actions).toEqual(expectedActions);
});
});
});
});

Wyświetl plik

@ -10,10 +10,10 @@ import {
} from './importer';
import type { AxiosError, CancelToken } from 'axios';
import type { History } from 'history';
import type { Map as ImmutableMap } from 'immutable';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { APIEntity, Status } from 'soapbox/types/entities';
import type { History } from 'soapbox/types/history';
const ACCOUNT_CREATE_REQUEST = 'ACCOUNT_CREATE_REQUEST';
const ACCOUNT_CREATE_SUCCESS = 'ACCOUNT_CREATE_SUCCESS';
@ -228,7 +228,7 @@ const fetchAccountFail = (id: string | null, error: AxiosError) => ({
});
type FollowAccountOpts = {
reblogs?: boolean,
reblogs?: boolean
notify?: boolean
};

Wyświetl plik

@ -1,13 +1,18 @@
import { defineMessages } from 'react-intl';
import { fetchRelationships } from 'soapbox/actions/accounts';
import { importFetchedAccount, importFetchedAccounts, importFetchedStatuses } from 'soapbox/actions/importer';
import toast from 'soapbox/toast';
import { filterBadges, getTagDiff } from 'soapbox/utils/badges';
import { getFeatures } from 'soapbox/utils/features';
import api, { getLinks } from '../api';
import { openModal } from './modals';
import type { AxiosResponse } from 'axios';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { APIEntity } from 'soapbox/types/entities';
import type { APIEntity, Announcement } from 'soapbox/types/entities';
const ADMIN_CONFIG_FETCH_REQUEST = 'ADMIN_CONFIG_FETCH_REQUEST';
const ADMIN_CONFIG_FETCH_SUCCESS = 'ADMIN_CONFIG_FETCH_SUCCESS';
@ -77,6 +82,45 @@ 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';
const ADMIN_USER_INDEX_FETCH_FAIL = 'ADMIN_USER_INDEX_FETCH_FAIL';
const ADMIN_USER_INDEX_FETCH_REQUEST = 'ADMIN_USER_INDEX_FETCH_REQUEST';
const ADMIN_USER_INDEX_FETCH_SUCCESS = 'ADMIN_USER_INDEX_FETCH_SUCCESS';
const ADMIN_USER_INDEX_QUERY_SET = 'ADMIN_USER_INDEX_QUERY_SET';
const ADMIN_ANNOUNCEMENTS_FETCH_FAIL = 'ADMIN_ANNOUNCEMENTS_FETCH_FAILS';
const ADMIN_ANNOUNCEMENTS_FETCH_REQUEST = 'ADMIN_ANNOUNCEMENTS_FETCH_REQUEST';
const ADMIN_ANNOUNCEMENTS_FETCH_SUCCESS = 'ADMIN_ANNOUNCEMENTS_FETCH_SUCCESS';
const ADMIN_ANNOUNCEMENTS_EXPAND_FAIL = 'ADMIN_ANNOUNCEMENTS_EXPAND_FAILS';
const ADMIN_ANNOUNCEMENTS_EXPAND_REQUEST = 'ADMIN_ANNOUNCEMENTS_EXPAND_REQUEST';
const ADMIN_ANNOUNCEMENTS_EXPAND_SUCCESS = 'ADMIN_ANNOUNCEMENTS_EXPAND_SUCCESS';
const ADMIN_ANNOUNCEMENT_CHANGE_CONTENT = 'ADMIN_ANNOUNCEMENT_CHANGE_CONTENT';
const ADMIN_ANNOUNCEMENT_CHANGE_START_TIME = 'ADMIN_ANNOUNCEMENT_CHANGE_START_TIME';
const ADMIN_ANNOUNCEMENT_CHANGE_END_TIME = 'ADMIN_ANNOUNCEMENT_CHANGE_END_TIME';
const ADMIN_ANNOUNCEMENT_CHANGE_ALL_DAY = 'ADMIN_ANNOUNCEMENT_CHANGE_ALL_DAY';
const ADMIN_ANNOUNCEMENT_CREATE_REQUEST = 'ADMIN_ANNOUNCEMENT_CREATE_REQUEST';
const ADMIN_ANNOUNCEMENT_CREATE_SUCCESS = 'ADMIN_ANNOUNCEMENT_CREATE_REQUEST';
const ADMIN_ANNOUNCEMENT_CREATE_FAIL = 'ADMIN_ANNOUNCEMENT_CREATE_FAIL';
const ADMIN_ANNOUNCEMENT_DELETE_REQUEST = 'ADMIN_ANNOUNCEMENT_DELETE_REQUEST';
const ADMIN_ANNOUNCEMENT_DELETE_SUCCESS = 'ADMIN_ANNOUNCEMENT_DELETE_REQUEST';
const ADMIN_ANNOUNCEMENT_DELETE_FAIL = 'ADMIN_ANNOUNCEMENT_DELETE_FAIL';
const ADMIN_ANNOUNCEMENT_MODAL_INIT = 'ADMIN_ANNOUNCEMENT_MODAL_INIT';
const messages = defineMessages({
announcementCreateSuccess: { id: 'admin.edit_announcement.created', defaultMessage: 'Announcement created' },
announcementDeleteSuccess: { id: 'admin.edit_announcement.deleted', defaultMessage: 'Announcement deleted' },
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 = () =>
@ -103,6 +147,19 @@ const updateConfig = (configs: Record<string, any>[]) =>
});
};
const updateSoapboxConfig = (data: Record<string, any>) =>
(dispatch: AppDispatch, _getState: () => RootState) => {
const params = [{
group: ':pleroma',
key: ':frontend_configurations',
value: [{
tuple: [':soapbox_fe', data],
}],
}];
return dispatch(updateConfig(params));
};
const fetchMastodonReports = (params: Record<string, any>) =>
(dispatch: AppDispatch, getState: () => RootState) =>
api(getState)
@ -531,6 +588,137 @@ const unsuggestUsers = (accountIds: string[]) =>
});
};
const setUserIndexQuery = (query: string) => ({ type: ADMIN_USER_INDEX_QUERY_SET, query });
const fetchUserIndex = () =>
(dispatch: AppDispatch, getState: () => RootState) => {
const { filters, page, query, pageSize, isLoading } = getState().admin_user_index;
if (isLoading) return;
dispatch({ type: ADMIN_USER_INDEX_FETCH_REQUEST });
dispatch(fetchUsers(filters.toJS() as string[], page + 1, query, pageSize))
.then((data: any) => {
if (data.error) {
dispatch({ type: ADMIN_USER_INDEX_FETCH_FAIL });
} else {
const { users, count, next } = (data);
dispatch({ type: ADMIN_USER_INDEX_FETCH_SUCCESS, users, count, next });
}
}).catch(() => {
dispatch({ type: ADMIN_USER_INDEX_FETCH_FAIL });
});
};
const expandUserIndex = () =>
(dispatch: AppDispatch, getState: () => RootState) => {
const { filters, page, query, pageSize, isLoading, next, loaded } = getState().admin_user_index;
if (!loaded || isLoading) return;
dispatch({ type: ADMIN_USER_INDEX_EXPAND_REQUEST });
dispatch(fetchUsers(filters.toJS() as string[], page + 1, query, pageSize, next))
.then((data: any) => {
if (data.error) {
dispatch({ type: ADMIN_USER_INDEX_EXPAND_FAIL });
} else {
const { users, count, next } = (data);
dispatch({ type: ADMIN_USER_INDEX_EXPAND_SUCCESS, users, count, next });
}
}).catch(() => {
dispatch({ type: ADMIN_USER_INDEX_EXPAND_FAIL });
});
};
const fetchAdminAnnouncements = () =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch({ type: ADMIN_ANNOUNCEMENTS_FETCH_REQUEST });
return api(getState)
.get('/api/pleroma/admin/announcements', { params: { limit: 50 } })
.then(({ data }) => {
dispatch({ type: ADMIN_ANNOUNCEMENTS_FETCH_SUCCESS, announcements: data });
return data;
}).catch(error => {
dispatch({ type: ADMIN_ANNOUNCEMENTS_FETCH_FAIL, error });
});
};
const expandAdminAnnouncements = () =>
(dispatch: AppDispatch, getState: () => RootState) => {
const page = getState().admin_announcements.page;
dispatch({ type: ADMIN_ANNOUNCEMENTS_EXPAND_REQUEST });
return api(getState)
.get('/api/pleroma/admin/announcements', { params: { limit: 50, offset: page * 50 } })
.then(({ data }) => {
dispatch({ type: ADMIN_ANNOUNCEMENTS_EXPAND_SUCCESS, announcements: data });
return data;
}).catch(error => {
dispatch({ type: ADMIN_ANNOUNCEMENTS_EXPAND_FAIL, error });
});
};
const changeAnnouncementContent = (content: string) => ({
type: ADMIN_ANNOUNCEMENT_CHANGE_CONTENT,
value: content,
});
const changeAnnouncementStartTime = (time: Date | null) => ({
type: ADMIN_ANNOUNCEMENT_CHANGE_START_TIME,
value: time,
});
const changeAnnouncementEndTime = (time: Date | null) => ({
type: ADMIN_ANNOUNCEMENT_CHANGE_END_TIME,
value: time,
});
const changeAnnouncementAllDay = (allDay: boolean) => ({
type: ADMIN_ANNOUNCEMENT_CHANGE_ALL_DAY,
value: allDay,
});
const handleCreateAnnouncement = () =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch({ type: ADMIN_ANNOUNCEMENT_CREATE_REQUEST });
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',
{ content, starts_at, ends_at, all_day },
).then(({ data }) => {
dispatch({ type: ADMIN_ANNOUNCEMENT_CREATE_SUCCESS, announcement: data });
toast.success(id ? messages.announcementUpdateSuccess : messages.announcementCreateSuccess);
dispatch(fetchAdminAnnouncements());
return data;
}).catch(error => {
dispatch({ type: ADMIN_ANNOUNCEMENT_CREATE_FAIL, error });
});
};
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 }) => {
dispatch({ type: ADMIN_ANNOUNCEMENT_DELETE_SUCCESS, id });
toast.success(messages.announcementDeleteSuccess);
dispatch(fetchAdminAnnouncements());
return data;
}).catch(error => {
dispatch({ type: ADMIN_ANNOUNCEMENT_DELETE_FAIL, id, error });
});
};
const initAnnouncementModal = (announcement?: Announcement) =>
(dispatch: AppDispatch) => {
dispatch({ type: ADMIN_ANNOUNCEMENT_MODAL_INIT, announcement });
dispatch(openModal('EDIT_ANNOUNCEMENT'));
};
export {
ADMIN_CONFIG_FETCH_REQUEST,
ADMIN_CONFIG_FETCH_SUCCESS,
@ -583,8 +771,33 @@ export {
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,
ADMIN_USER_INDEX_FETCH_FAIL,
ADMIN_USER_INDEX_FETCH_REQUEST,
ADMIN_USER_INDEX_FETCH_SUCCESS,
ADMIN_USER_INDEX_QUERY_SET,
ADMIN_ANNOUNCEMENTS_FETCH_FAIL,
ADMIN_ANNOUNCEMENTS_FETCH_REQUEST,
ADMIN_ANNOUNCEMENTS_FETCH_SUCCESS,
ADMIN_ANNOUNCEMENTS_EXPAND_FAIL,
ADMIN_ANNOUNCEMENTS_EXPAND_REQUEST,
ADMIN_ANNOUNCEMENTS_EXPAND_SUCCESS,
ADMIN_ANNOUNCEMENT_CHANGE_CONTENT,
ADMIN_ANNOUNCEMENT_CHANGE_START_TIME,
ADMIN_ANNOUNCEMENT_CHANGE_END_TIME,
ADMIN_ANNOUNCEMENT_CHANGE_ALL_DAY,
ADMIN_ANNOUNCEMENT_CREATE_FAIL,
ADMIN_ANNOUNCEMENT_CREATE_REQUEST,
ADMIN_ANNOUNCEMENT_CREATE_SUCCESS,
ADMIN_ANNOUNCEMENT_DELETE_FAIL,
ADMIN_ANNOUNCEMENT_DELETE_REQUEST,
ADMIN_ANNOUNCEMENT_DELETE_SUCCESS,
ADMIN_ANNOUNCEMENT_MODAL_INIT,
fetchConfig,
updateConfig,
updateSoapboxConfig,
fetchReports,
closeReports,
fetchUsers,
@ -608,4 +821,16 @@ export {
setRole,
suggestUsers,
unsuggestUsers,
setUserIndexQuery,
fetchUserIndex,
expandUserIndex,
fetchAdminAnnouncements,
expandAdminAnnouncements,
changeAnnouncementContent,
changeAnnouncementStartTime,
changeAnnouncementEndTime,
changeAnnouncementAllDay,
handleCreateAnnouncement,
deleteAnnouncement,
initAnnouncementModal,
};

Wyświetl plik

@ -1,75 +0,0 @@
import { defineMessages, MessageDescriptor } from 'react-intl';
import { httpErrorMessages } from 'soapbox/utils/errors';
import type { SnackbarActionSeverity } from './snackbar';
import type { AnyAction } from '@reduxjs/toolkit';
import type { AxiosError } from 'axios';
import type { NotificationObject } from 'react-notification';
const messages = defineMessages({
unexpectedTitle: { id: 'alert.unexpected.title', defaultMessage: 'Oops!' },
unexpectedMessage: { id: 'alert.unexpected.message', defaultMessage: 'An unexpected error occurred.' },
});
export const ALERT_SHOW = 'ALERT_SHOW';
export const ALERT_DISMISS = 'ALERT_DISMISS';
export const ALERT_CLEAR = 'ALERT_CLEAR';
const noOp = () => { };
function dismissAlert(alert: NotificationObject) {
return {
type: ALERT_DISMISS,
alert,
};
}
function showAlert(
title: MessageDescriptor | string = messages.unexpectedTitle,
message: MessageDescriptor | string = messages.unexpectedMessage,
severity: SnackbarActionSeverity = 'info',
) {
return {
type: ALERT_SHOW,
title,
message,
severity,
};
}
const showAlertForError = (error: AxiosError<any>) => (dispatch: React.Dispatch<AnyAction>, _getState: any) => {
if (error?.response) {
const { data, status, statusText } = error.response;
if (status === 502) {
return dispatch(showAlert('', 'The server is down', 'error'));
}
if (status === 404 || status === 410) {
// Skip these errors as they are reflected in the UI
return dispatch(noOp as any);
}
let message: string | undefined = statusText;
if (data?.error) {
message = data.error;
}
if (!message) {
message = httpErrorMessages.find((httpError) => httpError.code === status)?.description;
}
return dispatch(showAlert('', message, 'error'));
} else {
console.error(error);
return dispatch(showAlert(undefined, undefined, 'error'));
}
};
export {
dismissAlert,
showAlert,
showAlertForError,
};

Wyświetl plik

@ -1,14 +1,13 @@
import { defineMessages } from 'react-intl';
import toast from 'soapbox/toast';
import { isLoggedIn } from 'soapbox/utils/auth';
import { getFeatures } from 'soapbox/utils/features';
import api from '../api';
import { showAlertForError } from './alerts';
import { importFetchedAccounts } from './importer';
import { patchMeSuccess } from './me';
import snackbar from './snackbar';
import type { AxiosError } from 'axios';
import type { AppDispatch, RootState } from 'soapbox/store';
@ -80,7 +79,7 @@ const fetchAliasesSuggestions = (q: string) =>
api(getState).get('/api/v1/accounts/search', { params }).then(({ data }) => {
dispatch(importFetchedAccounts(data));
dispatch(fetchAliasesSuggestionsReady(q, data));
}).catch(error => dispatch(showAlertForError(error)));
}).catch(error => toast.showAlertForError(error));
};
const fetchAliasesSuggestionsReady = (query: string, accounts: APIEntity[]) => ({
@ -114,7 +113,7 @@ const addToAliases = (account: Account) =>
api(getState).patch('/api/v1/accounts/update_credentials', { also_known_as: [...alsoKnownAs, account.pleroma.get('ap_id')] })
.then((response => {
dispatch(snackbar.success(messages.createSuccess));
toast.success(messages.createSuccess);
dispatch(addToAliasesSuccess);
dispatch(patchMeSuccess(response.data));
}))
@ -129,7 +128,7 @@ const addToAliases = (account: Account) =>
alias: account.acct,
})
.then(() => {
dispatch(snackbar.success(messages.createSuccess));
toast.success(messages.createSuccess);
dispatch(addToAliasesSuccess);
dispatch(fetchAliases);
})
@ -165,7 +164,7 @@ const removeFromAliases = (account: string) =>
api(getState).patch('/api/v1/accounts/update_credentials', { also_known_as: alsoKnownAs.filter((id: string) => id !== account) })
.then(response => {
dispatch(snackbar.success(messages.removeSuccess));
toast.success(messages.removeSuccess);
dispatch(removeFromAliasesSuccess);
dispatch(patchMeSuccess(response.data));
})
@ -182,7 +181,7 @@ const removeFromAliases = (account: string) =>
},
})
.then(response => {
dispatch(snackbar.success(messages.removeSuccess));
toast.success(messages.removeSuccess);
dispatch(removeFromAliasesSuccess);
dispatch(fetchAliases);
})

Wyświetl plik

@ -14,14 +14,14 @@ import { createApp } from 'soapbox/actions/apps';
import { fetchMeSuccess, fetchMeFail } from 'soapbox/actions/me';
import { obtainOAuthToken, revokeOAuthToken } from 'soapbox/actions/oauth';
import { startOnboarding } from 'soapbox/actions/onboarding';
import snackbar from 'soapbox/actions/snackbar';
import { custom } from 'soapbox/custom';
import { queryClient } from 'soapbox/queries/client';
import KVStore from 'soapbox/storage/kv-store';
import toast from 'soapbox/toast';
import { getLoggedInAccount, parseBaseURL } from 'soapbox/utils/auth';
import sourceCode from 'soapbox/utils/code';
import { getFeatures } from 'soapbox/utils/features';
import { normalizeUsername } from 'soapbox/utils/input';
import { getScopes } from 'soapbox/utils/scopes';
import { isStandalone } from 'soapbox/utils/state';
import api, { baseClient } from '../api';
@ -29,7 +29,6 @@ import api, { baseClient } from '../api';
import { importFetchedAccount } from './importer';
import type { AxiosError } from 'axios';
import type { Map as ImmutableMap } from 'immutable';
import type { AppDispatch, RootState } from 'soapbox/store';
export const SWITCH_ACCOUNT = 'SWITCH_ACCOUNT';
@ -51,17 +50,12 @@ const customApp = custom('app');
export const messages = defineMessages({
loggedOut: { id: 'auth.logged_out', defaultMessage: 'Logged out.' },
awaitingApproval: { id: 'auth.awaiting_approval', defaultMessage: 'Your account is awaiting approval' },
invalidCredentials: { id: 'auth.invalid_credentials', defaultMessage: 'Wrong username or password' },
});
const noOp = () => new Promise(f => f(undefined));
const getScopes = (state: RootState) => {
const instance = state.instance;
const { scopes } = getFeatures(instance);
return scopes;
};
const createAppAndToken = () =>
(dispatch: AppDispatch) =>
dispatch(getAuthApp()).then(() =>
@ -94,11 +88,11 @@ const createAuthApp = () =>
const createAppToken = () =>
(dispatch: AppDispatch, getState: () => RootState) => {
const app = getState().auth.get('app');
const app = getState().auth.app;
const params = {
client_id: app.get('client_id'),
client_secret: app.get('client_secret'),
client_id: app.client_id!,
client_secret: app.client_secret!,
redirect_uri: 'urn:ietf:wg:oauth:2.0:oob',
grant_type: 'client_credentials',
scope: getScopes(getState()),
@ -111,11 +105,11 @@ const createAppToken = () =>
const createUserToken = (username: string, password: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const app = getState().auth.get('app');
const app = getState().auth.app;
const params = {
client_id: app.get('client_id'),
client_secret: app.get('client_secret'),
client_id: app.client_id!,
client_secret: app.client_secret!,
redirect_uri: 'urn:ietf:wg:oauth:2.0:oob',
grant_type: 'password',
username: username,
@ -127,32 +121,12 @@ const createUserToken = (username: string, password: string) =>
.then((token: Record<string, string | number>) => dispatch(authLoggedIn(token)));
};
export const refreshUserToken = () =>
(dispatch: AppDispatch, getState: () => RootState) => {
const refreshToken = getState().auth.getIn(['user', 'refresh_token']);
const app = getState().auth.get('app');
if (!refreshToken) return dispatch(noOp);
const params = {
client_id: app.get('client_id'),
client_secret: app.get('client_secret'),
refresh_token: refreshToken,
redirect_uri: 'urn:ietf:wg:oauth:2.0:oob',
grant_type: 'refresh_token',
scope: getScopes(getState()),
};
return dispatch(obtainOAuthToken(params))
.then((token: Record<string, string | number>) => dispatch(authLoggedIn(token)));
};
export const otpVerify = (code: string, mfa_token: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const app = getState().auth.get('app');
const app = getState().auth.app;
return api(getState, 'app').post('/oauth/mfa/challenge', {
client_id: app.get('client_id'),
client_secret: app.get('client_secret'),
client_id: app.client_id,
client_secret: app.client_secret,
mfa_token: mfa_token,
code: code,
challenge_type: 'totp',
@ -204,21 +178,21 @@ export const rememberAuthAccount = (accountUrl: string) =>
export const loadCredentials = (token: string, accountUrl: string) =>
(dispatch: AppDispatch) => dispatch(rememberAuthAccount(accountUrl))
.then(() => {
dispatch(verifyCredentials(token, accountUrl));
})
.then(() => dispatch(verifyCredentials(token, accountUrl)))
.catch(() => dispatch(verifyCredentials(token, accountUrl)));
export const logIn = (username: string, password: string) =>
(dispatch: AppDispatch) => dispatch(getAuthApp()).then(() => {
return dispatch(createUserToken(normalizeUsername(username), password));
}).catch((error: AxiosError) => {
if ((error.response?.data as any).error === 'mfa_required') {
if ((error.response?.data as any)?.error === 'mfa_required') {
// If MFA is required, throw the error and handle it in the component.
throw error;
} else if ((error.response?.data as any)?.identifier === 'awaiting_approval') {
toast.error(messages.awaitingApproval);
} else {
// Return "wrong password" message.
dispatch(snackbar.error(messages.invalidCredentials));
toast.error(messages.invalidCredentials);
}
throw error;
});
@ -235,9 +209,9 @@ export const logOut = () =>
if (!account) return dispatch(noOp);
const params = {
client_id: state.auth.getIn(['app', 'client_id']),
client_secret: state.auth.getIn(['app', 'client_secret']),
token: state.auth.getIn(['users', account.url, 'access_token']),
client_id: state.auth.app.client_id!,
client_secret: state.auth.app.client_secret!,
token: state.auth.users.get(account.url)!.access_token,
};
return dispatch(revokeOAuthToken(params))
@ -248,7 +222,7 @@ export const logOut = () =>
dispatch({ type: AUTH_LOGGED_OUT, account, standalone });
return dispatch(snackbar.success(messages.loggedOut));
toast.success(messages.loggedOut);
});
};
@ -265,10 +239,10 @@ export const switchAccount = (accountId: string, background = false) =>
export const fetchOwnAccounts = () =>
(dispatch: AppDispatch, getState: () => RootState) => {
const state = getState();
return state.auth.get('users').forEach((user: ImmutableMap<string, string>) => {
const account = state.accounts.get(user.get('id'));
return state.auth.users.forEach((user) => {
const account = state.accounts.get(user.id);
if (!account) {
dispatch(verifyCredentials(user.get('access_token')!, user.get('url')));
dispatch(verifyCredentials(user.access_token, user.url));
}
});
};

Wyświetl plik

@ -6,8 +6,8 @@ import { getFeatures } from 'soapbox/utils/features';
import api, { getLinks } from '../api';
import type { History } from 'history';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { History } from 'soapbox/types/history';
const CHATS_FETCH_REQUEST = 'CHATS_FETCH_REQUEST';
const CHATS_FETCH_SUCCESS = 'CHATS_FETCH_SUCCESS';

Wyświetl plik

@ -3,16 +3,16 @@ import { List as ImmutableList } from 'immutable';
import throttle from 'lodash/throttle';
import { defineMessages, IntlShape } from 'react-intl';
import snackbar from 'soapbox/actions/snackbar';
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 { tagHistory } from 'soapbox/settings';
import toast from 'soapbox/toast';
import { isLoggedIn } from 'soapbox/utils/auth';
import { getFeatures, parseVersion } from 'soapbox/utils/features';
import { formatBytes, getVideoDuration } from 'soapbox/utils/media';
import resizeImage from 'soapbox/utils/resize-image';
import { showAlert, showAlertForError } from './alerts';
import { useEmoji } from './emojis';
import { importFetchedAccounts } from './importer';
import { uploadMedia, fetchMedia, updateMedia } from './media';
@ -20,11 +20,11 @@ import { openModal, closeModal } from './modals';
import { getSettings } from './settings';
import { createStatus } from './statuses';
import type { History } from 'history';
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 { AppDispatch, RootState } from 'soapbox/store';
import type { Account, APIEntity, Status, Tag } from 'soapbox/types/entities';
import type { History } from 'soapbox/types/history';
const { CancelToken, isCancel } = axios;
@ -47,6 +47,7 @@ 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_SUGGESTIONS_CLEAR = 'COMPOSE_SUGGESTIONS_CLEAR';
const COMPOSE_SUGGESTIONS_READY = 'COMPOSE_SUGGESTIONS_READY';
@ -87,13 +88,13 @@ const COMPOSE_SET_STATUS = 'COMPOSE_SET_STATUS';
const messages = defineMessages({
exceededImageSizeLimit: { id: 'upload_error.image_size_limit', defaultMessage: 'Image exceeds the current file size limit ({limit})' },
exceededVideoSizeLimit: { id: 'upload_error.video_size_limit', defaultMessage: 'Video exceeds the current file size limit ({limit})' },
exceededVideoDurationLimit: { id: 'upload_error.video_duration_limit', defaultMessage: 'Video exceeds the current duration limit ({limit} seconds)' },
exceededVideoDurationLimit: { id: 'upload_error.video_duration_limit', defaultMessage: 'Video exceeds the current duration limit ({limit, plural, one {# second} other {# seconds}})' },
scheduleError: { id: 'compose.invalid_schedule', defaultMessage: 'You must schedule a post at least 5 minutes out.' },
success: { id: 'compose.submit_success', defaultMessage: 'Your post was sent' },
editSuccess: { id: 'compose.edit_success', defaultMessage: 'Your post was edited' },
uploadErrorLimit: { id: 'upload_error.limit', defaultMessage: 'File upload limit exceeded.' },
uploadErrorPoll: { id: 'upload_error.poll', defaultMessage: 'File upload not allowed with polls.' },
view: { id: 'snackbar.view', defaultMessage: 'View' },
view: { id: 'toast.view', defaultMessage: 'View' },
replyConfirm: { id: 'confirmations.reply.confirm', defaultMessage: 'Reply' },
replyMessage: { id: 'confirmations.reply.message', defaultMessage: 'Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?' },
});
@ -211,7 +212,10 @@ const handleComposeSubmit = (dispatch: AppDispatch, getState: () => RootState, c
dispatch(insertIntoTagHistory(composeId, data.tags || [], status));
dispatch(submitComposeSuccess(composeId, { ...data }));
dispatch(snackbar.success(edit ? messages.editSuccess : messages.success, messages.view, `/@${data.account.acct}/posts/${data.id}`));
toast.success(edit ? messages.editSuccess : messages.success, {
actionLabel: messages.view,
actionLink: `/@${data.account.acct}/posts/${data.id}`,
});
};
const needsDescriptions = (state: RootState, composeId: string) => {
@ -245,7 +249,7 @@ const submitCompose = (composeId: string, routerHistory?: History, force = false
let to = compose.to;
if (!validateSchedule(state, composeId)) {
dispatch(snackbar.error(messages.scheduleError));
toast.error(messages.scheduleError);
return;
}
@ -274,7 +278,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,
@ -288,6 +292,8 @@ const submitCompose = (composeId: string, routerHistory?: History, force = false
to,
};
if (compose.privacy === 'group') params.group_id = compose.group_id;
dispatch(createStatus(params, idempotencyKey, statusId)).then(function(data) {
if (!statusId && data.visibility === 'direct' && getState().conversations.mounted <= 0 && routerHistory) {
routerHistory.push('/messages');
@ -330,7 +336,7 @@ const uploadCompose = (composeId: string, files: FileList, intl: IntlShape) =>
const mediaCount = media ? media.size : 0;
if (files.length + mediaCount > attachmentLimit) {
dispatch(showAlert(undefined, messages.uploadErrorLimit, 'error'));
toast.error(messages.uploadErrorLimit);
return;
}
@ -346,18 +352,18 @@ const uploadCompose = (composeId: string, files: FileList, intl: IntlShape) =>
if (isImage && maxImageSize && (f.size > maxImageSize)) {
const limit = formatBytes(maxImageSize);
const message = intl.formatMessage(messages.exceededImageSizeLimit, { limit });
dispatch(snackbar.error(message));
toast.error(message);
dispatch(uploadComposeFail(composeId, true));
return;
} else if (isVideo && maxVideoSize && (f.size > maxVideoSize)) {
const limit = formatBytes(maxVideoSize);
const message = intl.formatMessage(messages.exceededVideoSizeLimit, { limit });
dispatch(snackbar.error(message));
toast.error(message);
dispatch(uploadComposeFail(composeId, true));
return;
} else if (isVideo && maxVideoDuration && (videoDurationInSeconds > maxVideoDuration)) {
const message = intl.formatMessage(messages.exceededVideoDurationLimit, { limit: maxVideoDuration });
dispatch(snackbar.error(message));
toast.error(message);
dispatch(uploadComposeFail(composeId, true));
return;
}
@ -468,6 +474,15 @@ 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 clearComposeSuggestions = (composeId: string) => {
if (cancelFetchComposeSuggestionsAccounts) {
cancelFetchComposeSuggestionsAccounts();
@ -496,13 +511,15 @@ const fetchComposeSuggestionsAccounts = throttle((dispatch, getState, composeId,
dispatch(readyComposeSuggestionsAccounts(composeId, token, response.data));
}).catch(error => {
if (!isCancel(error)) {
dispatch(showAlertForError(error));
toast.showAlertForError(error);
}
});
}, 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));
};
@ -547,7 +564,7 @@ const selectComposeSuggestion = (composeId: string, position: number, token: str
let completion, startPosition;
if (typeof suggestion === 'object' && suggestion.id) {
completion = suggestion.native || suggestion.colons;
completion = isNativeEmoji(suggestion) ? suggestion.native : suggestion.colons;
startPosition = position - 1;
dispatch(useEmoji(suggestion));
@ -720,7 +737,7 @@ const eventDiscussionCompose = (composeId: string, status: Status) =>
const instance = state.instance;
const { explicitAddressing } = getFeatures(instance);
dispatch({
return dispatch({
type: COMPOSE_EVENT_REPLY,
id: composeId,
status: status,
@ -747,6 +764,7 @@ export {
COMPOSE_UPLOAD_FAIL,
COMPOSE_UPLOAD_PROGRESS,
COMPOSE_UPLOAD_UNDO,
COMPOSE_GROUP_POST,
COMPOSE_SUGGESTIONS_CLEAR,
COMPOSE_SUGGESTIONS_READY,
COMPOSE_SUGGESTION_SELECT,
@ -799,6 +817,7 @@ export {
uploadComposeSuccess,
uploadComposeFail,
undoUploadCompose,
groupCompose,
clearComposeSuggestions,
fetchComposeSuggestions,
readyComposeSuggestionsEmojis,

Wyświetl plik

@ -3,7 +3,7 @@ import axios from 'axios';
import * as BuildConfig from 'soapbox/build-config';
import { isURL } from 'soapbox/utils/auth';
import sourceCode from 'soapbox/utils/code';
import { getFeatures } from 'soapbox/utils/features';
import { getScopes } from 'soapbox/utils/scopes';
import { createApp } from './apps';
@ -11,8 +11,7 @@ import type { AppDispatch, RootState } from 'soapbox/store';
const createProviderApp = () => {
return async(dispatch: AppDispatch, getState: () => RootState) => {
const state = getState();
const { scopes } = getFeatures(state.instance);
const scopes = getScopes(getState());
const params = {
client_name: sourceCode.displayName,
@ -29,8 +28,7 @@ export const prepareRequest = (provider: string) => {
return async(dispatch: AppDispatch, getState: () => RootState) => {
const baseURL = isURL(BuildConfig.BACKEND_URL) ? BuildConfig.BACKEND_URL : '';
const state = getState();
const { scopes } = getFeatures(state.instance);
const scopes = getScopes(getState());
const app = await dispatch(createProviderApp());
const { client_id, redirect_uri } = app;

Wyświetl plik

@ -1,13 +1,8 @@
import type { DropdownPlacement } from 'soapbox/components/dropdown-menu';
const DROPDOWN_MENU_OPEN = 'DROPDOWN_MENU_OPEN';
const DROPDOWN_MENU_CLOSE = 'DROPDOWN_MENU_CLOSE';
const openDropdownMenu = (id: number, placement: DropdownPlacement, keyboard: boolean) =>
({ type: DROPDOWN_MENU_OPEN, id, placement, keyboard });
const closeDropdownMenu = (id: number) =>
({ type: DROPDOWN_MENU_CLOSE, id });
const openDropdownMenu = () => ({ type: DROPDOWN_MENU_OPEN });
const closeDropdownMenu = () => ({ type: DROPDOWN_MENU_CLOSE });
export {
DROPDOWN_MENU_OPEN,

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,11 +70,11 @@ 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}`)
@ -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

@ -1,13 +1,13 @@
import { defineMessages, IntlShape } from 'react-intl';
import api, { getLinks } from 'soapbox/api';
import toast from 'soapbox/toast';
import { formatBytes } from 'soapbox/utils/media';
import resizeImage from 'soapbox/utils/resize-image';
import { importFetchedAccounts, importFetchedStatus, importFetchedStatuses } from './importer';
import { fetchMedia, uploadMedia } from './media';
import { closeModal, openModal } from './modals';
import snackbar from './snackbar';
import {
STATUS_FETCH_SOURCE_FAIL,
STATUS_FETCH_SOURCE_REQUEST,
@ -91,7 +91,7 @@ const messages = defineMessages({
editSuccess: { id: 'compose_event.edit_success', defaultMessage: 'Your event was edited' },
joinSuccess: { id: 'join_event.success', defaultMessage: 'Joined the event' },
joinRequestSuccess: { id: 'join_event.request_success', defaultMessage: 'Requested to join the event' },
view: { id: 'snackbar.view', defaultMessage: 'View' },
view: { id: 'toast.view', defaultMessage: 'View' },
authorized: { id: 'compose_event.participation_requests.authorize_success', defaultMessage: 'User accepted' },
rejected: { id: 'compose_event.participation_requests.reject_success', defaultMessage: 'User rejected' },
});
@ -163,7 +163,7 @@ const uploadEventBanner = (file: File, intl: IntlShape) =>
if (maxImageSize && (file.size > maxImageSize)) {
const limit = formatBytes(maxImageSize);
const message = intl.formatMessage(messages.exceededImageSizeLimit, { limit });
dispatch(snackbar.error(message));
toast.error(message);
dispatch(uploadEventBannerFail(true));
return;
}
@ -249,6 +249,7 @@ const submitEvent = () =>
status,
start_time: startTime,
join_mode: joinMode,
content_type: 'text/markdown',
};
if (endTime) params.end_time = endTime;
@ -263,7 +264,13 @@ const submitEvent = () =>
dispatch(closeModal('COMPOSE_EVENT'));
dispatch(importFetchedStatus(data));
dispatch(submitEventSuccess(data));
dispatch(snackbar.success(id ? messages.editSuccess : messages.success, messages.view, `/@${data.account.acct}/events/${data.id}`));
toast.success(
id ? messages.editSuccess : messages.success,
{
actionLabel: messages.view,
actionLink: `/@${data.account.acct}/events/${data.id}`,
},
);
}).catch(function(error) {
dispatch(submitEventFail(error));
});
@ -298,11 +305,13 @@ const joinEvent = (id: string, participationMessage?: string) =>
}).then(({ data }) => {
dispatch(importFetchedStatus(data));
dispatch(joinEventSuccess(data));
dispatch(snackbar.success(
toast.success(
data.pleroma.event?.join_state === 'pending' ? messages.joinRequestSuccess : messages.joinSuccess,
messages.view,
`/@${data.account.acct}/events/${data.id}`,
));
{
actionLabel: messages.view,
actionLink: `/@${data.account.acct}/events/${data.id}`,
},
);
}).catch(function(error) {
dispatch(joinEventFail(error, status, status?.event?.join_state || null));
});
@ -503,7 +512,7 @@ const authorizeEventParticipationRequest = (id: string, accountId: string) =>
.post(`/api/v1/pleroma/events/${id}/participation_requests/${accountId}/authorize`)
.then(() => {
dispatch(authorizeEventParticipationRequestSuccess(id, accountId));
dispatch(snackbar.success(messages.authorized));
toast.success(messages.authorized);
})
.catch(error => dispatch(authorizeEventParticipationRequestFail(id, accountId, error)));
};
@ -535,7 +544,7 @@ const rejectEventParticipationRequest = (id: string, accountId: string) =>
.post(`/api/v1/pleroma/events/${id}/participation_requests/${accountId}/reject`)
.then(() => {
dispatch(rejectEventParticipationRequestSuccess(id, accountId));
dispatch(snackbar.success(messages.rejected));
toast.success(messages.rejected);
})
.catch(error => dispatch(rejectEventParticipationRequestFail(id, accountId, error)));
};
@ -560,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

@ -1,10 +1,9 @@
import { defineMessages } from 'react-intl';
import snackbar from 'soapbox/actions/snackbar';
import api, { getLinks } from 'soapbox/api';
import { normalizeAccount } from 'soapbox/normalizers';
import toast from 'soapbox/toast';
import type { SnackbarAction } from './snackbar';
import type { AxiosResponse } from 'axios';
import type { RootState } from 'soapbox/store';
@ -35,9 +34,9 @@ type ExportDataActions = {
| typeof EXPORT_BLOCKS_FAIL
| typeof EXPORT_MUTES_REQUEST
| typeof EXPORT_MUTES_SUCCESS
| typeof EXPORT_MUTES_FAIL,
error?: any,
} | SnackbarAction
| typeof EXPORT_MUTES_FAIL
error?: any
}
function fileExport(content: string, fileName: string) {
const fileToDownload = document.createElement('a');
@ -75,7 +74,7 @@ export const exportFollows = () => (dispatch: React.Dispatch<ExportDataActions>,
followings.unshift('Account address,Show boosts');
fileExport(followings.join('\n'), 'export_followings.csv');
dispatch(snackbar.success(messages.followersSuccess));
toast.success(messages.followersSuccess);
dispatch({ type: EXPORT_FOLLOWS_SUCCESS });
}).catch(error => {
dispatch({ type: EXPORT_FOLLOWS_FAIL, error });
@ -90,7 +89,7 @@ export const exportBlocks = () => (dispatch: React.Dispatch<ExportDataActions>,
.then((blocks) => {
fileExport(blocks.join('\n'), 'export_block.csv');
dispatch(snackbar.success(messages.blocksSuccess));
toast.success(messages.blocksSuccess);
dispatch({ type: EXPORT_BLOCKS_SUCCESS });
}).catch(error => {
dispatch({ type: EXPORT_BLOCKS_FAIL, error });
@ -105,7 +104,7 @@ export const exportMutes = () => (dispatch: React.Dispatch<ExportDataActions>, g
.then((mutes) => {
fileExport(mutes.join('\n'), 'export_mutes.csv');
dispatch(snackbar.success(messages.mutesSuccess));
toast.success(messages.mutesSuccess);
dispatch({ type: EXPORT_MUTES_SUCCESS });
}).catch(error => {
dispatch({ type: EXPORT_MUTES_FAIL, error });

Wyświetl plik

@ -15,10 +15,11 @@ import sourceCode from 'soapbox/utils/code';
import { getWalletAndSign } from 'soapbox/utils/ethereum';
import { getFeatures } from 'soapbox/utils/features';
import { getQuirks } from 'soapbox/utils/quirks';
import { getInstanceScopes } from 'soapbox/utils/scopes';
import { baseClient } from '../api';
import type { AppDispatch } from 'soapbox/store';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { Instance } from 'soapbox/types/entities';
const fetchExternalInstance = (baseURL?: string) => {
@ -37,25 +38,23 @@ const fetchExternalInstance = (baseURL?: string) => {
};
const createExternalApp = (instance: Instance, baseURL?: string) =>
(dispatch: AppDispatch) => {
(dispatch: AppDispatch, _getState: () => RootState) => {
// Mitra: skip creating the auth app
if (getQuirks(instance).noApps) return new Promise(f => f({}));
const { scopes } = getFeatures(instance);
const params = {
client_name: sourceCode.displayName,
client_name: sourceCode.displayName,
redirect_uris: `${window.location.origin}/login/external`,
website: sourceCode.homepage,
scopes,
website: sourceCode.homepage,
scopes: getInstanceScopes(instance),
};
return dispatch(createApp(params, baseURL));
};
const externalAuthorize = (instance: Instance, baseURL: string) =>
(dispatch: AppDispatch) => {
const { scopes } = getFeatures(instance);
(dispatch: AppDispatch, _getState: () => RootState) => {
const scopes = getInstanceScopes(instance);
return dispatch(createExternalApp(instance, baseURL)).then((app) => {
const { client_id, redirect_uri } = app as Record<string, string>;
@ -76,7 +75,7 @@ const externalAuthorize = (instance: Instance, baseURL: string) =>
};
const externalEthereumLogin = (instance: Instance, baseURL?: string) =>
(dispatch: AppDispatch) => {
(dispatch: AppDispatch, getState: () => RootState) => {
const loginMessage = instance.login_message;
return getWalletAndSign(loginMessage).then(({ wallet, signature }) => {
@ -89,7 +88,7 @@ const externalEthereumLogin = (instance: Instance, baseURL?: string) =>
client_secret: client_secret,
password: signature as string,
redirect_uri: 'urn:ietf:wg:oauth:2.0:oob',
scope: getFeatures(instance).scopes,
scope: getInstanceScopes(instance),
};
return dispatch(obtainOAuthToken(params, baseURL))

Wyświetl plik

@ -11,25 +11,25 @@ export const FAMILIAR_FOLLOWERS_FETCH_SUCCESS = 'FAMILIAR_FOLLOWERS_FETCH_SUCCES
export const FAMILIAR_FOLLOWERS_FETCH_FAIL = 'FAMILIAR_FOLLOWERS_FETCH_FAIL';
type FamiliarFollowersFetchRequestAction = {
type: typeof FAMILIAR_FOLLOWERS_FETCH_REQUEST,
id: string,
type: typeof FAMILIAR_FOLLOWERS_FETCH_REQUEST
id: string
}
type FamiliarFollowersFetchRequestSuccessAction = {
type: typeof FAMILIAR_FOLLOWERS_FETCH_SUCCESS,
id: string,
accounts: Array<APIEntity>,
type: typeof FAMILIAR_FOLLOWERS_FETCH_SUCCESS
id: string
accounts: Array<APIEntity>
}
type FamiliarFollowersFetchRequestFailAction = {
type: typeof FAMILIAR_FOLLOWERS_FETCH_FAIL,
id: string,
error: any,
type: typeof FAMILIAR_FOLLOWERS_FETCH_FAIL
id: string
error: any
}
type AccountsImportAction = {
type: typeof ACCOUNTS_IMPORT,
accounts: Array<APIEntity>,
type: typeof ACCOUNTS_IMPORT
accounts: Array<APIEntity>
}
export type FamiliarFollowersActions = FamiliarFollowersFetchRequestAction | FamiliarFollowersFetchRequestSuccessAction | FamiliarFollowersFetchRequestFailAction | AccountsImportAction

Wyświetl plik

@ -1,6 +1,6 @@
import { defineMessages } from 'react-intl';
import snackbar from 'soapbox/actions/snackbar';
import toast from 'soapbox/toast';
import { isLoggedIn } from 'soapbox/utils/auth';
import { getFeatures } from 'soapbox/utils/features';
@ -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,45 +57,238 @@ 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 });
dispatch(snackbar.success(messages.added));
toast.success(messages.added);
}).catch(error => {
dispatch({ type: FILTERS_CREATE_FAIL, error });
});
};
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 => {
dispatch({ type: FILTERS_DELETE_SUCCESS, filter: response.data });
dispatch(snackbar.success(messages.removed));
toast.success(messages.removed);
}).catch(error => {
dispatch({ type: FILTERS_DELETE_FAIL, error });
});
};
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

@ -0,0 +1,964 @@
import { defineMessages } from 'react-intl';
import { deleteEntities } from 'soapbox/entity-store/actions';
import toast from 'soapbox/toast';
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';
const GROUP_CREATE_REQUEST = 'GROUP_CREATE_REQUEST';
const GROUP_CREATE_SUCCESS = 'GROUP_CREATE_SUCCESS';
const GROUP_CREATE_FAIL = 'GROUP_CREATE_FAIL';
const GROUP_UPDATE_REQUEST = 'GROUP_UPDATE_REQUEST';
const GROUP_UPDATE_SUCCESS = 'GROUP_UPDATE_SUCCESS';
const GROUP_UPDATE_FAIL = 'GROUP_UPDATE_FAIL';
const GROUP_DELETE_REQUEST = 'GROUP_DELETE_REQUEST';
const GROUP_DELETE_SUCCESS = 'GROUP_DELETE_SUCCESS';
const GROUP_DELETE_FAIL = 'GROUP_DELETE_FAIL';
const GROUP_FETCH_REQUEST = 'GROUP_FETCH_REQUEST';
const GROUP_FETCH_SUCCESS = 'GROUP_FETCH_SUCCESS';
const GROUP_FETCH_FAIL = 'GROUP_FETCH_FAIL';
const GROUPS_FETCH_REQUEST = 'GROUPS_FETCH_REQUEST';
const GROUPS_FETCH_SUCCESS = 'GROUPS_FETCH_SUCCESS';
const GROUPS_FETCH_FAIL = 'GROUPS_FETCH_FAIL';
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_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';
const GROUP_BLOCKS_FETCH_REQUEST = 'GROUP_BLOCKS_FETCH_REQUEST';
const GROUP_BLOCKS_FETCH_SUCCESS = 'GROUP_BLOCKS_FETCH_SUCCESS';
const GROUP_BLOCKS_FETCH_FAIL = 'GROUP_BLOCKS_FETCH_FAIL';
const GROUP_BLOCKS_EXPAND_REQUEST = 'GROUP_BLOCKS_EXPAND_REQUEST';
const GROUP_BLOCKS_EXPAND_SUCCESS = 'GROUP_BLOCKS_EXPAND_SUCCESS';
const GROUP_BLOCKS_EXPAND_FAIL = 'GROUP_BLOCKS_EXPAND_FAIL';
const GROUP_BLOCK_REQUEST = 'GROUP_BLOCK_REQUEST';
const GROUP_BLOCK_SUCCESS = 'GROUP_BLOCK_SUCCESS';
const GROUP_BLOCK_FAIL = 'GROUP_BLOCK_FAIL';
const GROUP_UNBLOCK_REQUEST = 'GROUP_UNBLOCK_REQUEST';
const GROUP_UNBLOCK_SUCCESS = 'GROUP_UNBLOCK_SUCCESS';
const GROUP_UNBLOCK_FAIL = 'GROUP_UNBLOCK_FAIL';
const GROUP_PROMOTE_REQUEST = 'GROUP_PROMOTE_REQUEST';
const GROUP_PROMOTE_SUCCESS = 'GROUP_PROMOTE_SUCCESS';
const GROUP_PROMOTE_FAIL = 'GROUP_PROMOTE_FAIL';
const GROUP_DEMOTE_REQUEST = 'GROUP_DEMOTE_REQUEST';
const GROUP_DEMOTE_SUCCESS = 'GROUP_DEMOTE_SUCCESS';
const GROUP_DEMOTE_FAIL = 'GROUP_DEMOTE_FAIL';
const GROUP_MEMBERSHIPS_FETCH_REQUEST = 'GROUP_MEMBERSHIPS_FETCH_REQUEST';
const GROUP_MEMBERSHIPS_FETCH_SUCCESS = 'GROUP_MEMBERSHIPS_FETCH_SUCCESS';
const GROUP_MEMBERSHIPS_FETCH_FAIL = 'GROUP_MEMBERSHIPS_FETCH_FAIL';
const GROUP_MEMBERSHIPS_EXPAND_REQUEST = 'GROUP_MEMBERSHIPS_EXPAND_REQUEST';
const GROUP_MEMBERSHIPS_EXPAND_SUCCESS = 'GROUP_MEMBERSHIPS_EXPAND_SUCCESS';
const GROUP_MEMBERSHIPS_EXPAND_FAIL = 'GROUP_MEMBERSHIPS_EXPAND_FAIL';
const GROUP_MEMBERSHIP_REQUESTS_FETCH_REQUEST = 'GROUP_MEMBERSHIP_REQUESTS_FETCH_REQUEST';
const GROUP_MEMBERSHIP_REQUESTS_FETCH_SUCCESS = 'GROUP_MEMBERSHIP_REQUESTS_FETCH_SUCCESS';
const GROUP_MEMBERSHIP_REQUESTS_FETCH_FAIL = 'GROUP_MEMBERSHIP_REQUESTS_FETCH_FAIL';
const GROUP_MEMBERSHIP_REQUESTS_EXPAND_REQUEST = 'GROUP_MEMBERSHIP_REQUESTS_EXPAND_REQUEST';
const GROUP_MEMBERSHIP_REQUESTS_EXPAND_SUCCESS = 'GROUP_MEMBERSHIP_REQUESTS_EXPAND_SUCCESS';
const GROUP_MEMBERSHIP_REQUESTS_EXPAND_FAIL = 'GROUP_MEMBERSHIP_REQUESTS_EXPAND_FAIL';
const GROUP_MEMBERSHIP_REQUEST_AUTHORIZE_REQUEST = 'GROUP_MEMBERSHIP_REQUEST_AUTHORIZE_REQUEST';
const GROUP_MEMBERSHIP_REQUEST_AUTHORIZE_SUCCESS = 'GROUP_MEMBERSHIP_REQUEST_AUTHORIZE_SUCCESS';
const GROUP_MEMBERSHIP_REQUEST_AUTHORIZE_FAIL = 'GROUP_MEMBERSHIP_REQUEST_AUTHORIZE_FAIL';
const GROUP_MEMBERSHIP_REQUEST_REJECT_REQUEST = 'GROUP_MEMBERSHIP_REQUEST_REJECT_REQUEST';
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());
}
return data;
}).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(deleteEntities([id], 'Group'));
return api(getState).delete(`/api/v1/groups/${id}`)
.then(() => dispatch(deleteGroupSuccess(id)))
.catch(err => dispatch(deleteGroupFail(id, err)));
};
const deleteGroupRequest = (id: string) => ({
type: GROUP_DELETE_REQUEST,
id,
});
const deleteGroupSuccess = (id: string) => ({
type: GROUP_DELETE_SUCCESS,
id,
});
const deleteGroupFail = (id: string, error: AxiosError) => ({
type: GROUP_DELETE_FAIL,
id,
error,
});
const fetchGroup = (id: string) => (dispatch: AppDispatch, getState: () => RootState) => {
dispatch(fetchGroupRelationships([id]));
dispatch(fetchGroupRequest(id));
return api(getState).get(`/api/v1/groups/${id}`)
.then(({ data }) => {
dispatch(importFetchedGroups([data]));
dispatch(fetchGroupSuccess(data));
})
.catch(err => dispatch(fetchGroupFail(id, err)));
};
const fetchGroupRequest = (id: string) => ({
type: GROUP_FETCH_REQUEST,
id,
});
const fetchGroupSuccess = (group: APIEntity) => ({
type: GROUP_FETCH_SUCCESS,
group,
});
const fetchGroupFail = (id: string, error: AxiosError) => ({
type: GROUP_FETCH_FAIL,
id,
error,
});
const fetchGroups = () => (dispatch: AppDispatch, getState: () => RootState) => {
dispatch(fetchGroupsRequest());
return api(getState).get('/api/v1/groups')
.then(({ data }) => {
dispatch(importFetchedGroups(data));
dispatch(fetchGroupsSuccess(data));
dispatch(fetchGroupRelationships(data.map((item: APIEntity) => item.id)));
}).catch(err => dispatch(fetchGroupsFail(err)));
};
const fetchGroupsRequest = () => ({
type: GROUPS_FETCH_REQUEST,
});
const fetchGroupsSuccess = (groups: APIEntity[]) => ({
type: GROUPS_FETCH_SUCCESS,
groups,
});
const fetchGroupsFail = (error: AxiosError) => ({
type: GROUPS_FETCH_FAIL,
error,
});
const fetchGroupRelationships = (groupIds: string[]) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const state = getState();
const loadedRelationships = state.group_relationships;
const newGroupIds = groupIds.filter(id => loadedRelationships.get(id, null) === null);
if (!state.me || newGroupIds.length === 0) {
return;
}
dispatch(fetchGroupRelationshipsRequest(newGroupIds));
return api(getState).get(`/api/v1/groups/relationships?${newGroupIds.map(id => `id[]=${id}`).join('&')}`).then(response => {
dispatch(fetchGroupRelationshipsSuccess(response.data));
}).catch(error => {
dispatch(fetchGroupRelationshipsFail(error));
});
};
const fetchGroupRelationshipsRequest = (ids: string[]) => ({
type: GROUP_RELATIONSHIPS_FETCH_REQUEST,
ids,
skipLoading: true,
});
const fetchGroupRelationshipsSuccess = (relationships: APIEntity[]) => ({
type: GROUP_RELATIONSHIPS_FETCH_SUCCESS,
relationships,
skipLoading: true,
});
const fetchGroupRelationshipsFail = (error: AxiosError) => ({
type: GROUP_RELATIONSHIPS_FETCH_FAIL,
error,
skipLoading: true,
skipNotFound: 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));
return api(getState).post(`/api/v1/groups/${groupId}/kick`, { account_ids: [accountId] })
.then(() => dispatch(groupKickSuccess(groupId, accountId)))
.catch(err => dispatch(groupKickFail(groupId, accountId, err)));
};
const groupKickRequest = (groupId: string, accountId: string) => ({
type: GROUP_KICK_REQUEST,
groupId,
accountId,
});
const groupKickSuccess = (groupId: string, accountId: string) => ({
type: GROUP_KICK_SUCCESS,
groupId,
accountId,
});
const groupKickFail = (groupId: string, accountId: string, error: AxiosError) => ({
type: GROUP_KICK_SUCCESS,
groupId,
accountId,
error,
});
const fetchGroupBlocks = (id: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch(fetchGroupBlocksRequest(id));
return api(getState).get(`/api/v1/groups/${id}/blocks`).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedAccounts(response.data));
dispatch(fetchGroupBlocksSuccess(id, response.data, next ? next.uri : null));
}).catch(error => {
dispatch(fetchGroupBlocksFail(id, error));
});
};
const fetchGroupBlocksRequest = (id: string) => ({
type: GROUP_BLOCKS_FETCH_REQUEST,
id,
});
const fetchGroupBlocksSuccess = (id: string, accounts: APIEntity[], next: string | null) => ({
type: GROUP_BLOCKS_FETCH_SUCCESS,
id,
accounts,
next,
});
const fetchGroupBlocksFail = (id: string, error: AxiosError) => ({
type: GROUP_BLOCKS_FETCH_FAIL,
id,
error,
skipNotFound: true,
});
const expandGroupBlocks = (id: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const url = getState().user_lists.group_blocks.get(id)?.next || null;
if (url === null) {
return;
}
dispatch(expandGroupBlocksRequest(id));
return api(getState).get(url).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedAccounts(response.data));
dispatch(expandGroupBlocksSuccess(id, response.data, next ? next.uri : null));
dispatch(fetchRelationships(response.data.map((item: APIEntity) => item.id)));
}).catch(error => {
dispatch(expandGroupBlocksFail(id, error));
});
};
const expandGroupBlocksRequest = (id: string) => ({
type: GROUP_BLOCKS_EXPAND_REQUEST,
id,
});
const expandGroupBlocksSuccess = (id: string, accounts: APIEntity[], next: string | null) => ({
type: GROUP_BLOCKS_EXPAND_SUCCESS,
id,
accounts,
next,
});
const expandGroupBlocksFail = (id: string, error: AxiosError) => ({
type: GROUP_BLOCKS_EXPAND_FAIL,
id,
error,
});
const groupBlock = (groupId: string, accountId: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch(groupBlockRequest(groupId, accountId));
return api(getState).post(`/api/v1/groups/${groupId}/blocks`, { account_ids: [accountId] })
.then(() => dispatch(groupBlockSuccess(groupId, accountId)))
.catch(err => dispatch(groupBlockFail(groupId, accountId, err)));
};
const groupBlockRequest = (groupId: string, accountId: string) => ({
type: GROUP_BLOCK_REQUEST,
groupId,
accountId,
});
const groupBlockSuccess = (groupId: string, accountId: string) => ({
type: GROUP_BLOCK_SUCCESS,
groupId,
accountId,
});
const groupBlockFail = (groupId: string, accountId: string, error: AxiosError) => ({
type: GROUP_BLOCK_FAIL,
groupId,
accountId,
error,
});
const groupUnblock = (groupId: string, accountId: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch(groupUnblockRequest(groupId, accountId));
return api(getState).delete(`/api/v1/groups/${groupId}/blocks?account_ids[]=${accountId}`)
.then(() => dispatch(groupUnblockSuccess(groupId, accountId)))
.catch(err => dispatch(groupUnblockFail(groupId, accountId, err)));
};
const groupUnblockRequest = (groupId: string, accountId: string) => ({
type: GROUP_UNBLOCK_REQUEST,
groupId,
accountId,
});
const groupUnblockSuccess = (groupId: string, accountId: string) => ({
type: GROUP_UNBLOCK_SUCCESS,
groupId,
accountId,
});
const groupUnblockFail = (groupId: string, accountId: string, error: AxiosError) => ({
type: GROUP_UNBLOCK_FAIL,
groupId,
accountId,
error,
});
const groupPromoteAccount = (groupId: string, accountId: string, role: GroupRole) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch(groupPromoteAccountRequest(groupId, accountId));
return api(getState).post(`/api/v1/groups/${groupId}/promote`, { account_ids: [accountId], role: role })
.then((response) => dispatch(groupPromoteAccountSuccess(groupId, accountId, response.data)))
.catch(err => dispatch(groupPromoteAccountFail(groupId, accountId, err)));
};
const groupPromoteAccountRequest = (groupId: string, accountId: string) => ({
type: GROUP_PROMOTE_REQUEST,
groupId,
accountId,
});
const groupPromoteAccountSuccess = (groupId: string, accountId: string, memberships: APIEntity[]) => ({
type: GROUP_PROMOTE_SUCCESS,
groupId,
accountId,
memberships,
});
const groupPromoteAccountFail = (groupId: string, accountId: string, error: AxiosError) => ({
type: GROUP_PROMOTE_FAIL,
groupId,
accountId,
error,
});
const groupDemoteAccount = (groupId: string, accountId: string, role: GroupRole) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch(groupDemoteAccountRequest(groupId, accountId));
return api(getState).post(`/api/v1/groups/${groupId}/demote`, { account_ids: [accountId], role: role })
.then((response) => dispatch(groupDemoteAccountSuccess(groupId, accountId, response.data)))
.catch(err => dispatch(groupDemoteAccountFail(groupId, accountId, err)));
};
const groupDemoteAccountRequest = (groupId: string, accountId: string) => ({
type: GROUP_DEMOTE_REQUEST,
groupId,
accountId,
});
const groupDemoteAccountSuccess = (groupId: string, accountId: string, memberships: APIEntity[]) => ({
type: GROUP_DEMOTE_SUCCESS,
groupId,
accountId,
memberships,
});
const groupDemoteAccountFail = (groupId: string, accountId: string, error: AxiosError) => ({
type: GROUP_DEMOTE_FAIL,
groupId,
accountId,
error,
});
const fetchGroupMemberships = (id: string, role: GroupRole) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch(fetchGroupMembershipsRequest(id, role));
return api(getState).get(`/api/v1/groups/${id}/memberships`, { params: { role } }).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedAccounts(response.data.map((membership: APIEntity) => membership.account)));
dispatch(fetchGroupMembershipsSuccess(id, role, response.data, next ? next.uri : null));
}).catch(error => {
dispatch(fetchGroupMembershipsFail(id, role, error));
});
};
const fetchGroupMembershipsRequest = (id: string, role: GroupRole) => ({
type: GROUP_MEMBERSHIPS_FETCH_REQUEST,
id,
role,
});
const fetchGroupMembershipsSuccess = (id: string, role: GroupRole, memberships: APIEntity[], next: string | null) => ({
type: GROUP_MEMBERSHIPS_FETCH_SUCCESS,
id,
role,
memberships,
next,
});
const fetchGroupMembershipsFail = (id: string, role: GroupRole, error: AxiosError) => ({
type: GROUP_MEMBERSHIPS_FETCH_FAIL,
id,
role,
error,
skipNotFound: true,
});
const expandGroupMemberships = (id: string, role: GroupRole) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const url = getState().group_memberships.get(role).get(id)?.next || null;
if (url === null) {
return;
}
dispatch(expandGroupMembershipsRequest(id, role));
return api(getState).get(url).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedAccounts(response.data.map((membership: APIEntity) => membership.account)));
dispatch(expandGroupMembershipsSuccess(id, role, response.data, next ? next.uri : null));
dispatch(fetchRelationships(response.data.map((item: APIEntity) => item.id)));
}).catch(error => {
dispatch(expandGroupMembershipsFail(id, role, error));
});
};
const expandGroupMembershipsRequest = (id: string, role: GroupRole) => ({
type: GROUP_MEMBERSHIPS_EXPAND_REQUEST,
id,
role,
});
const expandGroupMembershipsSuccess = (id: string, role: GroupRole, memberships: APIEntity[], next: string | null) => ({
type: GROUP_MEMBERSHIPS_EXPAND_SUCCESS,
id,
role,
memberships,
next,
});
const expandGroupMembershipsFail = (id: string, role: GroupRole, error: AxiosError) => ({
type: GROUP_MEMBERSHIPS_EXPAND_FAIL,
id,
role,
error,
});
const fetchGroupMembershipRequests = (id: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch(fetchGroupMembershipRequestsRequest(id));
return api(getState).get(`/api/v1/groups/${id}/membership_requests`).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedAccounts(response.data));
dispatch(fetchGroupMembershipRequestsSuccess(id, response.data, next ? next.uri : null));
}).catch(error => {
dispatch(fetchGroupMembershipRequestsFail(id, error));
});
};
const fetchGroupMembershipRequestsRequest = (id: string) => ({
type: GROUP_MEMBERSHIP_REQUESTS_FETCH_REQUEST,
id,
});
const fetchGroupMembershipRequestsSuccess = (id: string, accounts: APIEntity[], next: string | null) => ({
type: GROUP_MEMBERSHIP_REQUESTS_FETCH_SUCCESS,
id,
accounts,
next,
});
const fetchGroupMembershipRequestsFail = (id: string, error: AxiosError) => ({
type: GROUP_MEMBERSHIP_REQUESTS_FETCH_FAIL,
id,
error,
skipNotFound: true,
});
const expandGroupMembershipRequests = (id: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const url = getState().user_lists.membership_requests.get(id)?.next || null;
if (url === null) {
return;
}
dispatch(expandGroupMembershipRequestsRequest(id));
return api(getState).get(url).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedAccounts(response.data));
dispatch(expandGroupMembershipRequestsSuccess(id, response.data, next ? next.uri : null));
dispatch(fetchRelationships(response.data.map((item: APIEntity) => item.id)));
}).catch(error => {
dispatch(expandGroupMembershipRequestsFail(id, error));
});
};
const expandGroupMembershipRequestsRequest = (id: string) => ({
type: GROUP_MEMBERSHIP_REQUESTS_EXPAND_REQUEST,
id,
});
const expandGroupMembershipRequestsSuccess = (id: string, accounts: APIEntity[], next: string | null) => ({
type: GROUP_MEMBERSHIP_REQUESTS_EXPAND_SUCCESS,
id,
accounts,
next,
});
const expandGroupMembershipRequestsFail = (id: string, error: AxiosError) => ({
type: GROUP_MEMBERSHIP_REQUESTS_EXPAND_FAIL,
id,
error,
});
const authorizeGroupMembershipRequest = (groupId: string, accountId: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch(authorizeGroupMembershipRequestRequest(groupId, accountId));
return api(getState)
.post(`/api/v1/groups/${groupId}/membership_requests/${accountId}/authorize`)
.then(() => dispatch(authorizeGroupMembershipRequestSuccess(groupId, accountId)))
.catch(error => dispatch(authorizeGroupMembershipRequestFail(groupId, accountId, error)));
};
const authorizeGroupMembershipRequestRequest = (groupId: string, accountId: string) => ({
type: GROUP_MEMBERSHIP_REQUEST_AUTHORIZE_REQUEST,
groupId,
accountId,
});
const authorizeGroupMembershipRequestSuccess = (groupId: string, accountId: string) => ({
type: GROUP_MEMBERSHIP_REQUEST_AUTHORIZE_SUCCESS,
groupId,
accountId,
});
const authorizeGroupMembershipRequestFail = (groupId: string, accountId: string, error: AxiosError) => ({
type: GROUP_MEMBERSHIP_REQUEST_AUTHORIZE_FAIL,
groupId,
accountId,
error,
});
const rejectGroupMembershipRequest = (groupId: string, accountId: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch(rejectGroupMembershipRequestRequest(groupId, accountId));
return api(getState)
.post(`/api/v1/groups/${groupId}/membership_requests/${accountId}/reject`)
.then(() => dispatch(rejectGroupMembershipRequestSuccess(groupId, accountId)))
.catch(error => dispatch(rejectGroupMembershipRequestFail(groupId, accountId, error)));
};
const rejectGroupMembershipRequestRequest = (groupId: string, accountId: string) => ({
type: GROUP_MEMBERSHIP_REQUEST_REJECT_REQUEST,
groupId,
accountId,
});
const rejectGroupMembershipRequestSuccess = (groupId: string, accountId: string) => ({
type: GROUP_MEMBERSHIP_REQUEST_REJECT_SUCCESS,
groupId,
accountId,
});
const rejectGroupMembershipRequestFail = (groupId: string, accountId: string, error?: AxiosError) => ({
type: GROUP_MEMBERSHIP_REQUEST_REJECT_FAIL,
groupId,
accountId,
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 visibility = getState().group_editor.locked ? 'members_only' : 'everyone'; // Truth Social
const params: Record<string, any> = {
display_name: displayName,
group_visibility: visibility,
note,
};
if (avatar) params.avatar = avatar;
if (header) params.header = header;
if (groupId === null) {
return dispatch(createGroup(params, shouldReset));
} else {
return dispatch(updateGroup(groupId, params, shouldReset));
}
};
export {
GROUP_EDITOR_SET,
GROUP_CREATE_REQUEST,
GROUP_CREATE_SUCCESS,
GROUP_CREATE_FAIL,
GROUP_UPDATE_REQUEST,
GROUP_UPDATE_SUCCESS,
GROUP_UPDATE_FAIL,
GROUP_DELETE_REQUEST,
GROUP_DELETE_SUCCESS,
GROUP_DELETE_FAIL,
GROUP_FETCH_REQUEST,
GROUP_FETCH_SUCCESS,
GROUP_FETCH_FAIL,
GROUPS_FETCH_REQUEST,
GROUPS_FETCH_SUCCESS,
GROUPS_FETCH_FAIL,
GROUP_RELATIONSHIPS_FETCH_REQUEST,
GROUP_RELATIONSHIPS_FETCH_SUCCESS,
GROUP_RELATIONSHIPS_FETCH_FAIL,
GROUP_DELETE_STATUS_REQUEST,
GROUP_DELETE_STATUS_SUCCESS,
GROUP_DELETE_STATUS_FAIL,
GROUP_KICK_REQUEST,
GROUP_KICK_SUCCESS,
GROUP_KICK_FAIL,
GROUP_BLOCKS_FETCH_REQUEST,
GROUP_BLOCKS_FETCH_SUCCESS,
GROUP_BLOCKS_FETCH_FAIL,
GROUP_BLOCKS_EXPAND_REQUEST,
GROUP_BLOCKS_EXPAND_SUCCESS,
GROUP_BLOCKS_EXPAND_FAIL,
GROUP_BLOCK_REQUEST,
GROUP_BLOCK_SUCCESS,
GROUP_BLOCK_FAIL,
GROUP_UNBLOCK_REQUEST,
GROUP_UNBLOCK_SUCCESS,
GROUP_UNBLOCK_FAIL,
GROUP_PROMOTE_REQUEST,
GROUP_PROMOTE_SUCCESS,
GROUP_PROMOTE_FAIL,
GROUP_DEMOTE_REQUEST,
GROUP_DEMOTE_SUCCESS,
GROUP_DEMOTE_FAIL,
GROUP_MEMBERSHIPS_FETCH_REQUEST,
GROUP_MEMBERSHIPS_FETCH_SUCCESS,
GROUP_MEMBERSHIPS_FETCH_FAIL,
GROUP_MEMBERSHIPS_EXPAND_REQUEST,
GROUP_MEMBERSHIPS_EXPAND_SUCCESS,
GROUP_MEMBERSHIPS_EXPAND_FAIL,
GROUP_MEMBERSHIP_REQUESTS_FETCH_REQUEST,
GROUP_MEMBERSHIP_REQUESTS_FETCH_SUCCESS,
GROUP_MEMBERSHIP_REQUESTS_FETCH_FAIL,
GROUP_MEMBERSHIP_REQUESTS_EXPAND_REQUEST,
GROUP_MEMBERSHIP_REQUESTS_EXPAND_SUCCESS,
GROUP_MEMBERSHIP_REQUESTS_EXPAND_FAIL,
GROUP_MEMBERSHIP_REQUEST_AUTHORIZE_REQUEST,
GROUP_MEMBERSHIP_REQUEST_AUTHORIZE_SUCCESS,
GROUP_MEMBERSHIP_REQUEST_AUTHORIZE_FAIL,
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,
deleteGroupFail,
fetchGroup,
fetchGroupRequest,
fetchGroupSuccess,
fetchGroupFail,
fetchGroups,
fetchGroupsRequest,
fetchGroupsSuccess,
fetchGroupsFail,
fetchGroupRelationships,
fetchGroupRelationshipsRequest,
fetchGroupRelationshipsSuccess,
fetchGroupRelationshipsFail,
groupDeleteStatus,
groupDeleteStatusRequest,
groupDeleteStatusSuccess,
groupDeleteStatusFail,
groupKick,
groupKickRequest,
groupKickSuccess,
groupKickFail,
fetchGroupBlocks,
fetchGroupBlocksRequest,
fetchGroupBlocksSuccess,
fetchGroupBlocksFail,
expandGroupBlocks,
expandGroupBlocksRequest,
expandGroupBlocksSuccess,
expandGroupBlocksFail,
groupBlock,
groupBlockRequest,
groupBlockSuccess,
groupBlockFail,
groupUnblock,
groupUnblockRequest,
groupUnblockSuccess,
groupUnblockFail,
groupPromoteAccount,
groupPromoteAccountRequest,
groupPromoteAccountSuccess,
groupPromoteAccountFail,
groupDemoteAccount,
groupDemoteAccountRequest,
groupDemoteAccountSuccess,
groupDemoteAccountFail,
fetchGroupMemberships,
fetchGroupMembershipsRequest,
fetchGroupMembershipsSuccess,
fetchGroupMembershipsFail,
expandGroupMemberships,
expandGroupMembershipsRequest,
expandGroupMembershipsSuccess,
expandGroupMembershipsFail,
fetchGroupMembershipRequests,
fetchGroupMembershipRequestsRequest,
fetchGroupMembershipRequestsSuccess,
fetchGroupMembershipRequestsFail,
expandGroupMembershipRequests,
expandGroupMembershipRequestsRequest,
expandGroupMembershipRequestsSuccess,
expandGroupMembershipRequestsFail,
authorizeGroupMembershipRequest,
authorizeGroupMembershipRequestRequest,
authorizeGroupMembershipRequestSuccess,
authorizeGroupMembershipRequestFail,
rejectGroupMembershipRequest,
rejectGroupMembershipRequestRequest,
rejectGroupMembershipRequestSuccess,
rejectGroupMembershipRequestFail,
changeGroupEditorTitle,
changeGroupEditorDescription,
changeGroupEditorPrivacy,
changeGroupEditorMedia,
resetGroupEditor,
submitGroupEditor,
};

Wyświetl plik

@ -1,10 +1,9 @@
import { defineMessages } from 'react-intl';
import snackbar from 'soapbox/actions/snackbar';
import toast from 'soapbox/toast';
import api from '../api';
import type { SnackbarAction } from './snackbar';
import type { RootState } from 'soapbox/store';
export const IMPORT_FOLLOWS_REQUEST = 'IMPORT_FOLLOWS_REQUEST';
@ -28,10 +27,10 @@ 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
} | SnackbarAction
}
const messages = defineMessages({
blocksSuccess: { id: 'import_data.success.blocks', defaultMessage: 'Blocks imported successfully' },
@ -45,7 +44,7 @@ export const importFollows = (params: FormData) =>
return api(getState)
.post('/api/pleroma/follow_import', params)
.then(response => {
dispatch(snackbar.success(messages.followersSuccess));
toast.success(messages.followersSuccess);
dispatch({ type: IMPORT_FOLLOWS_SUCCESS, config: response.data });
}).catch(error => {
dispatch({ type: IMPORT_FOLLOWS_FAIL, error });
@ -58,7 +57,7 @@ export const importBlocks = (params: FormData) =>
return api(getState)
.post('/api/pleroma/blocks_import', params)
.then(response => {
dispatch(snackbar.success(messages.blocksSuccess));
toast.success(messages.blocksSuccess);
dispatch({ type: IMPORT_BLOCKS_SUCCESS, config: response.data });
}).catch(error => {
dispatch({ type: IMPORT_BLOCKS_FAIL, error });
@ -71,7 +70,7 @@ export const importMutes = (params: FormData) =>
return api(getState)
.post('/api/pleroma/mutes_import', params)
.then(response => {
dispatch(snackbar.success(messages.mutesSuccess));
toast.success(messages.mutesSuccess);
dispatch({ type: IMPORT_MUTES_SUCCESS, config: response.data });
}).catch(error => {
dispatch({ type: IMPORT_MUTES_FAIL, error });

Wyświetl plik

@ -1,3 +1,8 @@
import { importEntities } from 'soapbox/entity-store/actions';
import { Entities } from 'soapbox/entity-store/entities';
import { Group, groupSchema } from 'soapbox/schemas';
import { filteredArray } from 'soapbox/schemas/utils';
import { getSettings } from '../settings';
import type { AppDispatch, RootState } from 'soapbox/store';
@ -5,42 +10,44 @@ import type { APIEntity } from 'soapbox/types/entities';
const ACCOUNT_IMPORT = 'ACCOUNT_IMPORT';
const ACCOUNTS_IMPORT = 'ACCOUNTS_IMPORT';
const GROUP_IMPORT = 'GROUP_IMPORT';
const GROUPS_IMPORT = 'GROUPS_IMPORT';
const STATUS_IMPORT = 'STATUS_IMPORT';
const STATUSES_IMPORT = 'STATUSES_IMPORT';
const POLLS_IMPORT = 'POLLS_IMPORT';
const ACCOUNT_FETCH_FAIL_FOR_USERNAME_LOOKUP = 'ACCOUNT_FETCH_FAIL_FOR_USERNAME_LOOKUP';
export function importAccount(account: APIEntity) {
return { type: ACCOUNT_IMPORT, account };
}
const importAccount = (account: APIEntity) =>
({ type: ACCOUNT_IMPORT, account });
export function importAccounts(accounts: APIEntity[]) {
return { type: ACCOUNTS_IMPORT, accounts };
}
const importAccounts = (accounts: APIEntity[]) =>
({ type: ACCOUNTS_IMPORT, accounts });
export function importStatus(status: APIEntity, idempotencyKey?: string) {
return (dispatch: AppDispatch, getState: () => RootState) => {
const importGroup = (group: Group) =>
importEntities([group], Entities.GROUPS);
const importGroups = (groups: Group[]) =>
importEntities(groups, Entities.GROUPS);
const importStatus = (status: APIEntity, idempotencyKey?: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const expandSpoilers = getSettings(getState()).get('expandSpoilers');
return dispatch({ type: STATUS_IMPORT, status, idempotencyKey, expandSpoilers });
};
}
export function importStatuses(statuses: APIEntity[]) {
return (dispatch: AppDispatch, getState: () => RootState) => {
const importStatuses = (statuses: APIEntity[]) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const expandSpoilers = getSettings(getState()).get('expandSpoilers');
return dispatch({ type: STATUSES_IMPORT, statuses, expandSpoilers });
};
}
export function importPolls(polls: APIEntity[]) {
return { type: POLLS_IMPORT, polls };
}
const importPolls = (polls: APIEntity[]) =>
({ type: POLLS_IMPORT, polls });
export function importFetchedAccount(account: APIEntity) {
return importFetchedAccounts([account]);
}
const importFetchedAccount = (account: APIEntity) =>
importFetchedAccounts([account]);
export function importFetchedAccounts(accounts: APIEntity[], args = { should_refetch: false }) {
const importFetchedAccounts = (accounts: APIEntity[], args = { should_refetch: false }) => {
const { should_refetch } = args;
const normalAccounts: APIEntity[] = [];
@ -61,10 +68,18 @@ export function importFetchedAccounts(accounts: APIEntity[], args = { should_ref
accounts.forEach(processAccount);
return importAccounts(normalAccounts);
}
};
export function importFetchedStatus(status: APIEntity, idempotencyKey?: string) {
return (dispatch: AppDispatch) => {
const importFetchedGroup = (group: APIEntity) =>
importFetchedGroups([group]);
const importFetchedGroups = (groups: APIEntity[]) => {
const entities = filteredArray(groupSchema).catch([]).parse(groups);
return importGroups(entities);
};
const importFetchedStatus = (status: APIEntity, idempotencyKey?: string) =>
(dispatch: AppDispatch) => {
// Skip broken statuses
if (isBroken(status)) return;
@ -96,10 +111,13 @@ export function importFetchedStatus(status: APIEntity, idempotencyKey?: string)
dispatch(importFetchedPoll(status.poll));
}
if (status.group?.id) {
dispatch(importFetchedGroup(status.group));
}
dispatch(importFetchedAccount(status.account));
dispatch(importStatus(status, idempotencyKey));
};
}
// Sometimes Pleroma can return an empty account,
// or a repost can appear of a deleted account. Skip these statuses.
@ -117,8 +135,8 @@ const isBroken = (status: APIEntity) => {
}
};
export function importFetchedStatuses(statuses: APIEntity[]) {
return (dispatch: AppDispatch, getState: () => RootState) => {
const importFetchedStatuses = (statuses: APIEntity[]) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const accounts: APIEntity[] = [];
const normalStatuses: APIEntity[] = [];
const polls: APIEntity[] = [];
@ -146,6 +164,10 @@ export function importFetchedStatuses(statuses: APIEntity[]) {
if (status.poll?.id) {
polls.push(status.poll);
}
if (status.group?.id) {
dispatch(importFetchedGroup(status.group));
}
}
statuses.forEach(processStatus);
@ -154,23 +176,37 @@ export function importFetchedStatuses(statuses: APIEntity[]) {
dispatch(importFetchedAccounts(accounts));
dispatch(importStatuses(normalStatuses));
};
}
export function importFetchedPoll(poll: APIEntity) {
return (dispatch: AppDispatch) => {
const importFetchedPoll = (poll: APIEntity) =>
(dispatch: AppDispatch) => {
dispatch(importPolls([poll]));
};
}
export function importErrorWhileFetchingAccountByUsername(username: string) {
return { type: ACCOUNT_FETCH_FAIL_FOR_USERNAME_LOOKUP, username };
}
const importErrorWhileFetchingAccountByUsername = (username: string) =>
({ type: ACCOUNT_FETCH_FAIL_FOR_USERNAME_LOOKUP, username });
export {
ACCOUNT_IMPORT,
ACCOUNTS_IMPORT,
GROUP_IMPORT,
GROUPS_IMPORT,
STATUS_IMPORT,
STATUSES_IMPORT,
POLLS_IMPORT,
ACCOUNT_FETCH_FAIL_FOR_USERNAME_LOOKUP,
importAccount,
importAccounts,
importGroup,
importGroups,
importStatus,
importStatuses,
importPolls,
importFetchedAccount,
importFetchedAccounts,
importFetchedGroup,
importFetchedGroups,
importFetchedStatus,
importFetchedStatuses,
importFetchedPoll,
importErrorWhileFetchingAccountByUsername,
};

Wyświetl plik

@ -10,12 +10,12 @@ import api from '../api';
const getMeUrl = (state: RootState) => {
const me = state.me;
return state.accounts.getIn([me, 'url']);
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);
const accountUrl = getMeUrl(state) || getAuthUserUrl(state) as string;
try {
return new URL(accountUrl).host;

Wyświetl plik

@ -1,6 +1,6 @@
import { defineMessages } from 'react-intl';
import snackbar from 'soapbox/actions/snackbar';
import toast from 'soapbox/toast';
import { isLoggedIn } from 'soapbox/utils/auth';
import api from '../api';
@ -20,6 +20,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 +32,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 +44,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';
@ -63,7 +75,7 @@ const REMOTE_INTERACTION_FAIL = 'REMOTE_INTERACTION_FAIL';
const messages = defineMessages({
bookmarkAdded: { id: 'status.bookmarked', defaultMessage: 'Bookmark added.' },
bookmarkRemoved: { id: 'status.unbookmarked', defaultMessage: 'Bookmark removed.' },
view: { id: 'snackbar.view', defaultMessage: 'View' },
view: { id: 'toast.view', defaultMessage: 'View' },
});
const reblog = (status: StatusEntity) =>
@ -96,7 +108,7 @@ const unreblog = (status: StatusEntity) =>
};
const toggleReblog = (status: StatusEntity) =>
(dispatch: AppDispatch, getState: () => RootState) => {
(dispatch: AppDispatch) => {
if (status.reblogged) {
dispatch(unreblog(status));
} else {
@ -169,7 +181,7 @@ const unfavourite = (status: StatusEntity) =>
};
const toggleFavourite = (status: StatusEntity) =>
(dispatch: AppDispatch, getState: () => RootState) => {
(dispatch: AppDispatch) => {
if (status.favourited) {
dispatch(unfavourite(status));
} else {
@ -215,6 +227,79 @@ 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.get('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.get('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));
@ -222,7 +307,10 @@ const bookmark = (status: StatusEntity) =>
api(getState).post(`/api/v1/statuses/${status.get('id')}/bookmark`).then(function(response) {
dispatch(importFetchedStatus(response.data));
dispatch(bookmarkSuccess(status, response.data));
dispatch(snackbar.success(messages.bookmarkAdded, messages.view, '/bookmarks'));
toast.success(messages.bookmarkAdded, {
actionLabel: messages.view,
actionLink: '/bookmarks',
});
}).catch(function(error) {
dispatch(bookmarkFail(status, error));
});
@ -235,7 +323,7 @@ const unbookmark = (status: StatusEntity) =>
api(getState).post(`/api/v1/statuses/${status.get('id')}/unbookmark`).then(response => {
dispatch(importFetchedStatus(response.data));
dispatch(unbookmarkSuccess(status, response.data));
dispatch(snackbar.success(messages.bookmarkRemoved));
toast.success(messages.bookmarkRemoved);
}).catch(error => {
dispatch(unbookmarkFail(status, error));
});
@ -348,6 +436,38 @@ const fetchFavouritesFail = (id: string, error: AxiosError) => ({
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));
@ -495,18 +615,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,
@ -543,6 +672,15 @@ export {
unfavouriteRequest,
unfavouriteSuccess,
unfavouriteFail,
dislike,
undislike,
toggleDislike,
dislikeRequest,
dislikeSuccess,
dislikeFail,
undislikeRequest,
undislikeSuccess,
undislikeFail,
bookmark,
unbookmark,
toggleBookmark,
@ -560,6 +698,10 @@ export {
fetchFavouritesRequest,
fetchFavouritesSuccess,
fetchFavouritesFail,
fetchDislikes,
fetchDislikesRequest,
fetchDislikesSuccess,
fetchDislikesFail,
fetchReactions,
fetchReactionsRequest,
fetchReactionsSuccess,

Wyświetl plik

@ -1,8 +1,8 @@
import toast from 'soapbox/toast';
import { isLoggedIn } from 'soapbox/utils/auth';
import api from '../api';
import { showAlertForError } from './alerts';
import { importFetchedAccounts } from './importer';
import type { AxiosError } from 'axios';
@ -265,7 +265,7 @@ const fetchListSuggestions = (q: string) => (dispatch: AppDispatch, getState: ()
api(getState).get('/api/v1/accounts/search', { params }).then(({ data }) => {
dispatch(importFetchedAccounts(data));
dispatch(fetchListSuggestionsReady(q, data));
}).catch(error => dispatch(showAlertForError(error)));
}).catch(error => toast.showAlertForError(error));
};
const fetchListSuggestionsReady = (query: string, accounts: APIEntity[]) => ({

Wyświetl plik

@ -6,7 +6,7 @@ import api from '../api';
import { loadCredentials } from './auth';
import { importFetchedAccount } from './importer';
import type { AxiosError, AxiosRequestHeaders } from 'axios';
import type { AxiosError, RawAxiosRequestHeaders } from 'axios';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { APIEntity } from 'soapbox/types/entities';
@ -30,8 +30,8 @@ const getMeUrl = (state: RootState) => {
const getMeToken = (state: RootState) => {
// Fallback for upgrading IDs to URLs
const accountUrl = getMeUrl(state) || state.auth.get('me');
return state.auth.getIn(['users', accountUrl, 'access_token']);
const accountUrl = getMeUrl(state) || state.auth.me;
return state.auth.users.get(accountUrl!)?.access_token;
};
const fetchMe = () =>
@ -46,7 +46,7 @@ const fetchMe = () =>
}
dispatch(fetchMeRequest());
return dispatch(loadCredentials(token, accountUrl))
return dispatch(loadCredentials(token, accountUrl!))
.catch(error => dispatch(fetchMeFail(error)));
};
@ -66,7 +66,7 @@ const patchMe = (params: Record<string, any>, isFormData = false) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch(patchMeRequest());
const headers: AxiosRequestHeaders = isFormData ? {
const headers: RawAxiosRequestHeaders = isFormData ? {
'Content-Type': 'multipart/form-data',
} : {};

Wyświetl plik

@ -4,10 +4,10 @@ import { defineMessages, IntlShape } from 'react-intl';
import { fetchAccountByUsername } from 'soapbox/actions/accounts';
import { deactivateUsers, deleteUsers, deleteStatus, toggleStatusSensitivity } from 'soapbox/actions/admin';
import { openModal } from 'soapbox/actions/modals';
import snackbar from 'soapbox/actions/snackbar';
import OutlineBox from 'soapbox/components/outline-box';
import { Stack, Text } from 'soapbox/components/ui';
import AccountContainer from 'soapbox/containers/account-container';
import toast from 'soapbox/toast';
import { isLocal } from 'soapbox/utils/accounts';
import type { AppDispatch, RootState } from 'soapbox/store';
@ -65,7 +65,7 @@ const deactivateUserModal = (intl: IntlShape, accountId: string, afterConfirm =
onConfirm: () => {
dispatch(deactivateUsers([accountId])).then(() => {
const message = intl.formatMessage(messages.userDeactivated, { acct });
dispatch(snackbar.success(message));
toast.success(message);
afterConfirm();
}).catch(() => {});
},
@ -105,34 +105,13 @@ const deleteUserModal = (intl: IntlShape, accountId: string, afterConfirm = () =
dispatch(deleteUsers([accountId])).then(() => {
const message = intl.formatMessage(messages.userDeleted, { acct });
dispatch(fetchAccountByUsername(acct));
dispatch(snackbar.success(message));
toast.success(message);
afterConfirm();
}).catch(() => {});
},
}));
};
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();
@ -147,7 +126,7 @@ const toggleStatusSensitivityModal = (intl: IntlShape, statusId: string, sensiti
onConfirm: () => {
dispatch(toggleStatusSensitivity(statusId, sensitive)).then(() => {
const message = intl.formatMessage(sensitive === false ? messages.statusMarkedSensitive : messages.statusMarkedNotSensitive, { acct });
dispatch(snackbar.success(message));
toast.success(message);
}).catch(() => {});
afterConfirm();
},
@ -168,7 +147,7 @@ const deleteStatusModal = (intl: IntlShape, statusId: string, afterConfirm = ()
onConfirm: () => {
dispatch(deleteStatus(statusId)).then(() => {
const message = intl.formatMessage(messages.statusDeleted, { acct });
dispatch(snackbar.success(message));
toast.success(message);
}).catch(() => {});
afterConfirm();
},
@ -178,7 +157,6 @@ const deleteStatusModal = (intl: IntlShape, statusId: string, afterConfirm = ()
export {
deactivateUserModal,
deleteUserModal,
rejectUserModal,
toggleStatusSensitivityModal,
deleteStatusModal,
};

Wyświetl plik

@ -47,7 +47,7 @@ const MAX_QUEUED_NOTIFICATIONS = 40;
defineMessages({
mention: { id: 'notification.mention', defaultMessage: '{name} mentioned you' },
group: { id: 'notifications.group', defaultMessage: '{count} notifications' },
group: { id: 'notifications.group', defaultMessage: '{count, plural, one {# notification} other {# notifications}}' },
});
const fetchRelatedRelationships = (dispatch: AppDispatch, notifications: APIEntity[]) => {
@ -89,6 +89,7 @@ const updateNotificationsQueue = (notification: APIEntity, intlMessages: Record<
(dispatch: AppDispatch, getState: () => RootState) => {
if (!notification.type) return; // drop invalid notifications
if (notification.type === 'pleroma:chat_mention') return; // Drop chat notifications, handle them per-chat
if (notification.type === 'chat') return; // Drop Truth Social chat notifications.
const showAlert = getSettings(getState()).getIn(['notifications', 'alerts', notification.type]);
const filters = getFilters(getState(), { contextType: 'notifications' });
@ -106,7 +107,10 @@ const updateNotificationsQueue = (notification: APIEntity, intlMessages: Record<
// Desktop notifications
try {
if (showAlert && !filtered) {
// eslint-disable-next-line compat/compat
const isNotificationsEnabled = window.Notification?.permission === 'granted';
if (showAlert && !filtered && isNotificationsEnabled) {
const title = new IntlMessageFormat(intlMessages[`notification.${notification.type}`], intlLocale).format({ name: notification.account.display_name.length > 0 ? notification.account.display_name : notification.account.username });
const body = (notification.status && notification.status.spoiler_text.length > 0) ? notification.status.spoiler_text : unescapeHTML(notification.status ? notification.status.content : '');

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

@ -4,7 +4,7 @@ import { openModal } from './modals';
import type { AxiosError } from 'axios';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { Account, Status } from 'soapbox/types/entities';
import type { Account, ChatMessage, Group, Status } from 'soapbox/types/entities';
const REPORT_INIT = 'REPORT_INIT';
const REPORT_CANCEL = 'REPORT_CANCEL';
@ -20,26 +20,33 @@ const REPORT_BLOCK_CHANGE = 'REPORT_BLOCK_CHANGE';
const REPORT_RULE_CHANGE = 'REPORT_RULE_CHANGE';
const initReport = (account: Account, status?: Status) =>
(dispatch: AppDispatch) => {
dispatch({
type: REPORT_INIT,
account,
status,
});
enum ReportableEntities {
ACCOUNT = 'ACCOUNT',
CHAT_MESSAGE = 'CHAT_MESSAGE',
GROUP = 'GROUP',
STATUS = 'STATUS'
}
return dispatch(openModal('REPORT'));
};
type ReportedEntity = {
status?: Status
chatMessage?: ChatMessage
group?: Group
}
const initReportById = (accountId: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch({
type: REPORT_INIT,
account: getState().accounts.get(accountId),
});
const initReport = (entityType: ReportableEntities, account: Account, entities?: ReportedEntity) => (dispatch: AppDispatch) => {
const { status, chatMessage, group } = entities || {};
dispatch(openModal('REPORT'));
};
dispatch({
type: REPORT_INIT,
entityType,
account,
status,
chatMessage,
group,
});
return dispatch(openModal('REPORT'));
};
const cancelReport = () => ({
type: REPORT_CANCEL,
@ -59,6 +66,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'])].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']),
@ -99,6 +108,7 @@ const changeReportRule = (ruleId: string) => ({
});
export {
ReportableEntities,
REPORT_INIT,
REPORT_CANCEL,
REPORT_SUBMIT_REQUEST,
@ -110,7 +120,6 @@ export {
REPORT_BLOCK_CHANGE,
REPORT_RULE_CHANGE,
initReport,
initReportById,
cancelReport,
toggleStatusReport,
submitReport,

Wyświetl plik

@ -1,3 +1,5 @@
import { getFeatures } from 'soapbox/utils/features';
import api, { getLinks } from '../api';
import type { AxiosError } from 'axios';
@ -18,10 +20,17 @@ const SCHEDULED_STATUS_CANCEL_FAIL = 'SCHEDULED_STATUS_CANCEL_FAIL';
const fetchScheduledStatuses = () =>
(dispatch: AppDispatch, getState: () => RootState) => {
if (getState().status_lists.get('scheduled_statuses')?.isLoading) {
const state = getState();
if (state.status_lists.get('scheduled_statuses')?.isLoading) {
return;
}
const instance = state.instance;
const features = getFeatures(instance);
if (!features.scheduledStatuses) return;
dispatch(fetchScheduledStatusesRequest());
api(getState).get('/api/v1/scheduled_statuses').then(response => {

Wyświetl plik

@ -1,7 +1,7 @@
import api from '../api';
import { fetchRelationships } from './accounts';
import { importFetchedAccounts, importFetchedStatuses } from './importer';
import { importFetchedAccounts, importFetchedGroups, importFetchedStatuses } from './importer';
import type { AxiosError } from 'axios';
import type { SearchFilter } from 'soapbox/reducers/search';
@ -83,6 +83,10 @@ const submitSearch = (filter?: SearchFilter) =>
dispatch(importFetchedStatuses(response.data.statuses));
}
if (response.data.groups) {
dispatch(importFetchedGroups(response.data.groups));
}
dispatch(fetchSearchSuccess(response.data, value, type));
dispatch(fetchRelationships(response.data.accounts.map((item: APIEntity) => item.id)));
}).catch(error => {
@ -139,6 +143,10 @@ const expandSearch = (type: SearchFilter) => (dispatch: AppDispatch, getState: (
dispatch(importFetchedStatuses(data.statuses));
}
if (data.groups) {
dispatch(importFetchedGroups(data.groups));
}
dispatch(expandSearchSuccess(data, value, type));
dispatch(fetchRelationships(data.accounts.map((item: APIEntity) => item.id)));
}).catch(error => {

Wyświetl plik

@ -4,7 +4,7 @@
* @see module:soapbox/actions/auth
*/
import snackbar from 'soapbox/actions/snackbar';
import toast from 'soapbox/toast';
import { getLoggedInAccount } from 'soapbox/utils/auth';
import { parseVersion, TRUTHSOCIAL } from 'soapbox/utils/features';
import { normalizeUsername } from 'soapbox/utils/input';
@ -50,7 +50,7 @@ const MOVE_ACCOUNT_FAIL = 'MOVE_ACCOUNT_FAIL';
const fetchOAuthTokens = () =>
(dispatch: AppDispatch, getState: () => RootState) => {
dispatch({ type: FETCH_TOKENS_REQUEST });
return api(getState).get('/api/oauth_tokens.json').then(({ data: tokens }) => {
return api(getState).get('/api/oauth_tokens').then(({ data: tokens }) => {
dispatch({ type: FETCH_TOKENS_SUCCESS, tokens });
}).catch(() => {
dispatch({ type: FETCH_TOKENS_FAIL });
@ -152,7 +152,7 @@ const deleteAccount = (password: string) =>
if (response.data.error) throw response.data.error; // This endpoint returns HTTP 200 even on failure
dispatch({ type: DELETE_ACCOUNT_SUCCESS, response });
dispatch({ type: AUTH_LOGGED_OUT, account });
dispatch(snackbar.success(messages.loggedOut));
toast.success(messages.loggedOut);
}).catch(error => {
dispatch({ type: DELETE_ACCOUNT_FAIL, error, skipAlert: true });
throw error;

Wyświetl plik

@ -1,14 +1,13 @@
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/locales/messages';
import toast from 'soapbox/toast';
import { isLoggedIn } from 'soapbox/utils/auth';
import { showAlertForError } from './alerts';
import snackbar from './snackbar';
import type { AppDispatch, RootState } from 'soapbox/store';
const SETTING_CHANGE = 'SETTING_CHANGE';
@ -20,12 +19,10 @@ 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,
@ -42,14 +39,13 @@ 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,
systemFont: false,
dyslexicFont: false,
demetricator: false,
isDeveloper: false,
@ -159,6 +155,8 @@ const defaultSettings = ImmutableMap({
}),
}),
groups: ImmutableMap({}),
trends: ImmutableMap({
show: true,
}),
@ -222,16 +220,22 @@ const saveSettingsImmediate = (opts?: SettingOpts) =>
dispatch({ type: SETTING_SAVE });
if (opts?.showAlert) {
dispatch(snackbar.success(messages.saveSuccess));
toast.success(saveSuccessMessage);
}
}).catch(error => {
dispatch(showAlertForError(error));
toast.showAlertForError(error);
});
};
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;
};
export {
SETTING_CHANGE,
SETTING_SAVE,
@ -243,4 +247,5 @@ export {
changeSetting,
saveSettingsImmediate,
saveSettings,
getLocale,
};

Wyświetl plik

@ -1,50 +0,0 @@
import { ALERT_SHOW } from './alerts';
import type { MessageDescriptor } from 'react-intl';
export type SnackbarActionSeverity = 'info' | 'success' | 'error';
type SnackbarMessage = string | MessageDescriptor;
export type SnackbarAction = {
type: typeof ALERT_SHOW,
message: SnackbarMessage,
actionLabel?: SnackbarMessage,
actionLink?: string,
action?: () => void,
severity: SnackbarActionSeverity,
};
type SnackbarOpts = {
actionLabel?: SnackbarMessage,
actionLink?: string,
action?: () => void,
dismissAfter?: number | false,
};
export const show = (
severity: SnackbarActionSeverity,
message: SnackbarMessage,
opts?: SnackbarOpts,
): SnackbarAction => ({
type: ALERT_SHOW,
message,
severity,
...opts,
});
export const info = (message: SnackbarMessage, actionLabel?: SnackbarMessage, actionLink?: string) =>
show('info', message, { actionLabel, actionLink });
export const success = (message: SnackbarMessage, actionLabel?: SnackbarMessage, actionLink?: string) =>
show('success', message, { actionLabel, actionLink });
export const error = (message: SnackbarMessage, actionLabel?: SnackbarMessage, actionLink?: string) =>
show('error', message, { actionLabel, actionLink });
export default {
info,
success,
error,
show,
};

Wyświetl plik

@ -32,8 +32,8 @@ const getSoapboxConfig = createSelector([
}
// If RGI reacts aren't supported, strip VS16s
// // https://git.pleroma.social/pleroma/pleroma/-/issues/2355
if (!features.emojiReactsRGI) {
// https://git.pleroma.social/pleroma/pleroma/-/issues/2355
if (features.emojiReactsNonRGI) {
soapboxConfig.set('allowedEmoji', soapboxConfig.allowedEmoji.map(removeVS16s));
}
});

Wyświetl plik

@ -48,6 +48,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;
};
@ -68,7 +70,7 @@ const createStatus = (params: Record<string, any>, idempotencyKey: string, statu
}
dispatch(importFetchedStatus(status, idempotencyKey));
dispatch({ type: STATUS_CREATE_SUCCESS, status, params, idempotencyKey });
dispatch({ type: STATUS_CREATE_SUCCESS, status, params, idempotencyKey, editing: !!statusId });
// Poll the backend for the updated card
if (status.expectsCard) {
@ -335,6 +337,11 @@ const undoStatusTranslation = (id: string) => ({
id,
});
const unfilterStatus = (id: string) => ({
type: STATUS_UNFILTER,
id,
});
export {
STATUS_CREATE_REQUEST,
STATUS_CREATE_SUCCESS,
@ -363,6 +370,7 @@ export {
STATUS_TRANSLATE_SUCCESS,
STATUS_TRANSLATE_FAIL,
STATUS_TRANSLATE_UNDO,
STATUS_UNFILTER,
createStatus,
editStatus,
fetchStatus,
@ -381,4 +389,5 @@ export {
toggleStatusHidden,
translateStatus,
undoStatusTranslation,
unfilterStatus,
};

Wyświetl plik

@ -1,5 +1,10 @@
import { getSettings } from 'soapbox/actions/settings';
import { getLocale, getSettings } from 'soapbox/actions/settings';
import messages from 'soapbox/locales/messages';
import { ChatKeys, IChat, isLastMessage } from 'soapbox/queries/chats';
import { queryClient } from 'soapbox/queries/client';
import { getUnreadChatsCount, updateChatListItem, updateChatMessage } from 'soapbox/utils/chats';
import { removePageItem } from 'soapbox/utils/queries';
import { play, soundCache } from 'soapbox/utils/sounds';
import { connectStream } from '../stream';
@ -22,19 +27,13 @@ import {
processTimelineUpdate,
} from './timelines';
import type { IStatContext } from 'soapbox/contexts/stat-context';
import type { AppDispatch, RootState } from 'soapbox/store';
import type { APIEntity } from 'soapbox/types/entities';
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;
@ -45,11 +44,45 @@ const updateFollowRelationships = (relationships: APIEntity) =>
});
};
const removeChatMessage = (payload: string) => {
const data = JSON.parse(payload);
const chatId = data.chat_id;
const chatMessageId = data.deleted_message_id;
// If the user just deleted the "last_message", then let's invalidate
// the Chat Search query so the Chat List will show the new "last_message".
if (isLastMessage(chatMessageId)) {
queryClient.invalidateQueries(ChatKeys.chatSearch());
}
removePageItem(ChatKeys.chatMessages(chatId), chatMessageId, (o: any, n: any) => String(o.id) === String(n));
};
// Update the specific Chat query data.
const updateChatQuery = (chat: IChat) => {
const cachedChat = queryClient.getQueryData<IChat>(ChatKeys.chat(chat.id));
if (!cachedChat) {
return;
}
const newChat = {
...cachedChat,
latest_read_message_by_account: chat.latest_read_message_by_account,
latest_read_message_created_at: chat.latest_read_message_created_at,
};
queryClient.setQueryData<Chat>(ChatKeys.chat(chat.id), newChat as any);
};
interface StreamOpts {
statContext?: IStatContext
}
const connectTimelineStream = (
timelineId: string,
path: string,
pollingRefresh: ((dispatch: AppDispatch, done?: () => void) => void) | null = null,
accept: ((status: APIEntity) => boolean) | null = null,
opts?: StreamOpts,
) => connectStream(path, pollingRefresh, (dispatch: AppDispatch, getState: () => RootState) => {
const locale = getLocale(getState());
@ -78,7 +111,14 @@ const connectTimelineStream = (
// break;
case 'notification':
messages[locale]().then(messages => {
dispatch(updateNotificationsQueue(JSON.parse(data.payload), messages, locale, window.location.pathname));
dispatch(
updateNotificationsQueue(
JSON.parse(data.payload),
messages,
locale,
window.location.pathname,
),
);
}).catch(error => {
console.error(error);
});
@ -90,20 +130,42 @@ const connectTimelineStream = (
dispatch(fetchFilters());
break;
case 'pleroma:chat_update':
dispatch((dispatch: AppDispatch, getState: () => RootState) => {
case 'chat_message.created': // TruthSocial
dispatch((_dispatch: AppDispatch, getState: () => RootState) => {
const chat = JSON.parse(data.payload);
const me = getState().me;
const messageOwned = !(chat.last_message && chat.last_message.account_id !== me);
const messageOwned = chat.last_message?.account_id === me;
const settings = getSettings(getState());
dispatch({
type: STREAMING_CHAT_UPDATE,
chat,
me,
// Only play sounds for recipient messages
meta: !messageOwned && getSettings(getState()).getIn(['chats', 'sound']) && { sound: 'chat' },
});
// Don't update own messages from streaming
if (!messageOwned) {
updateChatListItem(chat);
if (settings.getIn(['chats', 'sound'])) {
play(soundCache.chat);
}
// Increment unread counter
opts?.statContext?.setUnreadChatsCount(getUnreadChatsCount());
}
});
break;
case 'chat_message.deleted': // TruthSocial
removeChatMessage(data.payload);
break;
case 'chat_message.read': // TruthSocial
dispatch((_dispatch: AppDispatch, getState: () => RootState) => {
const chat = JSON.parse(data.payload);
const me = getState().me;
const isFromOtherUser = chat.account.id !== me;
if (isFromOtherUser) {
updateChatQuery(JSON.parse(data.payload));
}
});
break;
case 'chat_message.reaction': // TruthSocial
updateChatMessage(JSON.parse(data.payload));
break;
case 'pleroma:follow_relationships_update':
dispatch(updateFollowRelationships(JSON.parse(data.payload)));
break;
@ -129,8 +191,8 @@ const refreshHomeTimelineAndNotification = (dispatch: AppDispatch, done?: () =>
dispatch(expandNotifications({}, () =>
dispatch(fetchAnnouncements(done))))));
const connectUserStream = () =>
connectTimelineStream('home', 'user', refreshHomeTimelineAndNotification);
const connectUserStream = (opts?: StreamOpts) =>
connectTimelineStream('home', 'user', refreshHomeTimelineAndNotification, null, opts);
const connectCommunityStream = ({ onlyMedia }: Record<string, any> = {}) =>
connectTimelineStream(`community${onlyMedia ? ':media' : ''}`, `public:local${onlyMedia ? ':media' : ''}`);

Wyświetl plik

@ -219,6 +219,9 @@ const expandListTimeline = (id: string, { maxId }: Record<string, any> = {}, don
const expandGroupTimeline = (id: string, { maxId }: Record<string, any> = {}, done = noOp) =>
expandTimeline(`group:${id}`, `/api/v1/timelines/group/${id}`, { 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}`, {
max_id: maxId,
@ -309,6 +312,7 @@ export {
expandAccountMediaTimeline,
expandListTimeline,
expandGroupTimeline,
expandGroupMediaTimeline,
expandHashtagTimeline,
expandTimelineRequest,
expandTimelineSuccess,

Wyświetl plik

@ -17,6 +17,8 @@ const fetchTrendingStatuses = () =>
const instance = state.instance;
const features = getFeatures(instance);
if (!features.trendingStatuses && !features.trendingTruths) return;
dispatch({ type: TRENDING_STATUSES_FETCH_REQUEST });
return api(getState).get(features.trendingTruths ? '/api/v1/truth/trending/truths' : '/api/v1/trends/statuses').then(({ data: statuses }) => {
dispatch(importFetchedStatuses(statuses));

Wyświetl plik

@ -31,14 +31,15 @@ const AGE: Challenge = 'age';
export type Challenge = 'age' | 'sms' | 'email'
type Challenges = {
email?: 0 | 1,
sms?: number,
age?: number,
email?: 0 | 1
sms?: 0 | 1
age?: 0 | 1
}
type Verification = {
token?: string,
challenges?: Challenges,
token?: string
challenges?: Challenges
challengeTypes?: Array<'age' | 'sms' | 'email'>
};
/**
@ -83,6 +84,18 @@ const fetchStoredChallenges = () => {
}
};
/**
* Fetch and return the state of the verification challenge types.
*/
const fetchStoredChallengeTypes = () => {
try {
const verification: Verification | null = fetchStoredVerification();
return verification!.challengeTypes;
} catch {
return null;
}
};
/**
* Update the verification object in local storage.
*
@ -131,7 +144,10 @@ function saveChallenges(challenges: Array<'age' | 'sms' | 'email'>) {
}
}
updateStorage({ challenges: currentChallenges });
updateStorage({
challenges: currentChallenges,
challengeTypes: challenges,
});
}
/**
@ -267,13 +283,29 @@ const confirmEmailVerification = (emailToken: string) =>
return api(getState).post('/api/v1/pepe/verify_email/confirm', { token: emailToken }, {
headers: { Authorization: `Bearer ${token}` },
})
.then(() => {
finishChallenge(EMAIL);
dispatchNextChallenge(dispatch);
.then((response) => {
updateStorageFromEmailConfirmation(dispatch, response.data.token);
})
.finally(() => dispatch({ type: SET_LOADING, value: false }));
};
const updateStorageFromEmailConfirmation = (dispatch: AppDispatch, token: string) => {
const challengeTypes = fetchStoredChallengeTypes();
if (!challengeTypes) {
return;
}
const indexOfEmail = challengeTypes.indexOf('email');
const challenges: Challenges = {};
challengeTypes?.forEach((challengeType, idx) => {
const value = idx <= indexOfEmail ? 1 : 0;
challenges[challengeType] = value;
});
updateStorage({ token, challengeTypes, challenges });
dispatchNextChallenge(dispatch);
};
const postEmailVerification = () =>
(dispatch: AppDispatch) => {
finishChallenge(EMAIL);

Wyświetl plik

@ -21,6 +21,16 @@ export const getLinks = (response: AxiosResponse): LinkHeader => {
return new LinkHeader(response.headers?.link);
};
export const getNextLink = (response: AxiosResponse) => {
const nextLink = new LinkHeader(response.headers?.link);
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[]) => {
const axios = api.baseClient(...params);
setupMock(axios);

Wyświetl plik

@ -29,6 +29,10 @@ export const getNextLink = (response: AxiosResponse): string | undefined => {
return getLinks(response).refs.find(link => link.rel === 'next')?.uri;
};
export const getPrevLink = (response: AxiosResponse): string | undefined => {
return getLinks(response).refs.find(link => link.rel === 'prev')?.uri;
};
const getToken = (state: RootState, authType: string) => {
return authType === 'app' ? getAppToken(state) : getAccessToken(state);
};
@ -43,7 +47,7 @@ const maybeParseJSON = (data: string) => {
const getAuthBaseURL = createSelector([
(state: RootState, me: string | false | null) => state.accounts.getIn([me, 'url']),
(state: RootState, _me: string | false | null) => state.auth.get('me'),
(state: RootState, _me: string | false | null) => state.auth.me,
], (accountUrl, authUserUrl) => {
const baseURL = parseBaseURL(accountUrl) || parseBaseURL(authUserUrl);
return baseURL !== window.location.origin ? baseURL : '';
@ -62,7 +66,6 @@ export const baseClient = (accessToken?: string | null, baseURL: string = ''): A
headers: Object.assign(accessToken ? {
'Authorization': `Bearer ${accessToken}`,
} : {}),
transformResponse: [maybeParseJSON],
});
};

Wyświetl plik

@ -1,50 +0,0 @@
'use strict';
import 'intl';
import 'intl/locale-data/jsonp/en';
import 'es6-symbol/implement';
// @ts-ignore: No types
import includes from 'array-includes';
// @ts-ignore: No types
import isNaN from 'is-nan';
import assign from 'object-assign';
// @ts-ignore: No types
import values from 'object.values';
import { decode as decodeBase64 } from './utils/base64';
if (!Array.prototype.includes) {
includes.shim();
}
if (!Object.assign) {
Object.assign = assign;
}
if (!Object.values) {
values.shim();
}
if (!Number.isNaN) {
Number.isNaN = isNaN;
}
if (!HTMLCanvasElement.prototype.toBlob) {
const BASE64_MARKER = ';base64,';
Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', {
value(callback: any, type = 'image/png', quality: any) {
const dataURL = this.toDataURL(type, quality);
let data;
if (dataURL.includes(BASE64_MARKER)) {
const [, base64] = dataURL.split(BASE64_MARKER);
data = decodeBase64(base64);
} else {
[, data] = dataURL.split(',');
}
callback(new Blob([data], { type }));
},
});
}

Wyświetl plik

@ -1,7 +1,7 @@
import React from 'react';
interface IInlineSVG {
loader?: JSX.Element,
loader?: JSX.Element
}
const InlineSVG: React.FC<IInlineSVG> = ({ loader }): JSX.Element => {

Wyświetl plik

@ -1,31 +0,0 @@
import React from 'react';
import { normalizeAccount } from 'soapbox/normalizers';
import { render, screen } from '../../jest/test-helpers';
import AvatarOverlay from '../avatar-overlay';
import type { ReducerAccount } from 'soapbox/reducers/accounts';
describe('<AvatarOverlay', () => {
const account = normalizeAccount({
username: 'alice',
acct: 'alice',
display_name: 'Alice',
avatar: '/animated/alice.gif',
avatar_static: '/static/alice.jpg',
}) as ReducerAccount;
const friend = normalizeAccount({
username: 'eve',
acct: 'eve@blackhat.lair',
display_name: 'Evelyn',
avatar: '/animated/eve.gif',
avatar_static: '/static/eve.jpg',
}) as ReducerAccount;
it('renders a overlay avatar', () => {
render(<AvatarOverlay account={account} friend={friend} />);
expect(screen.queryAllByRole('img')).toHaveLength(2);
});
});

Wyświetl plik

@ -1,38 +0,0 @@
import React from 'react';
import { normalizeAccount } from 'soapbox/normalizers';
import { render, screen } from '../../jest/test-helpers';
import Avatar from '../avatar';
import type { ReducerAccount } from 'soapbox/reducers/accounts';
describe('<Avatar />', () => {
const account = normalizeAccount({
username: 'alice',
acct: 'alice',
display_name: 'Alice',
avatar: '/animated/alice.gif',
avatar_static: '/static/alice.jpg',
}) as ReducerAccount;
const size = 100;
// describe('Autoplay', () => {
// it('renders an animated avatar', () => {
// render(<Avatar account={account} animate size={size} />);
// expect(screen.getByRole('img').getAttribute('src')).toBe(account.get('avatar'));
// });
// });
describe('Still', () => {
it('renders a still avatar', () => {
render(<Avatar account={account} size={size} />);
expect(screen.getByRole('img').getAttribute('src')).toBe(account.get('avatar'));
});
});
// TODO add autoplay test if possible
});

Wyświetl plik

@ -1,16 +0,0 @@
import React from 'react';
import { render, screen } from '../../jest/test-helpers';
import EmojiSelector from '../emoji-selector';
describe('<EmojiSelector />', () => {
it('renders correctly', () => {
const children = <EmojiSelector />;
// @ts-ignore
children.__proto__.addEventListener = () => {};
render(children);
expect(screen.queryAllByRole('button')).toHaveLength(6);
});
});

Wyświetl plik

@ -1,9 +1,10 @@
import classNames from 'clsx';
import clsx from 'clsx';
import React, { useState } from 'react';
import { defineMessages, useIntl } from 'react-intl';
import AutosuggestAccountInput from 'soapbox/components/autosuggest-account-input';
import Icon from 'soapbox/components/icon';
import SvgIcon from './ui/icon/svg-icon';
const messages = defineMessages({
placeholder: { id: 'account_search.placeholder', defaultMessage: 'Search for an account' },
@ -11,11 +12,9 @@ const messages = defineMessages({
interface IAccountSearch {
/** Callback when a searched account is chosen. */
onSelected: (accountId: string) => void,
onSelected: (accountId: string) => void
/** Override the default placeholder of the input. */
placeholder?: string,
/** Position of results relative to the input. */
resultsPosition?: 'above' | 'below',
placeholder?: string
}
/** Input to search for accounts. */
@ -56,9 +55,10 @@ const AccountSearch: React.FC<IAccountSearch> = ({ onSelected, ...rest }) => {
};
return (
<div className='search search--account'>
<label>
<span style={{ display: 'none' }}>{intl.formatMessage(messages.placeholder)}</span>
<div className='w-full'>
<label className='sr-only'>{intl.formatMessage(messages.placeholder)}</label>
<div className='relative'>
<AutosuggestAccountInput
className='rounded-full'
placeholder={intl.formatMessage(messages.placeholder)}
@ -68,10 +68,24 @@ const AccountSearch: React.FC<IAccountSearch> = ({ onSelected, ...rest }) => {
onKeyDown={handleKeyDown}
{...rest}
/>
</label>
<div role='button' tabIndex={0} className='search__icon' onClick={handleClear}>
<Icon src={require('@tabler/icons/search.svg')} className={classNames('svg-icon--search', { active: isEmpty() })} />
<Icon src={require('@tabler/icons/backspace.svg')} className={classNames('svg-icon--backspace', { active: !isEmpty() })} aria-label={intl.formatMessage(messages.placeholder)} />
<div
role='button'
tabIndex={0}
className='absolute inset-y-0 right-0 flex cursor-pointer items-center px-3'
onClick={handleClear}
>
<SvgIcon
src={require('@tabler/icons/search.svg')}
className={clsx('h-4 w-4 text-gray-400', { hidden: !isEmpty() })}
/>
<SvgIcon
src={require('@tabler/icons/x.svg')}
className={clsx('h-4 w-4 text-gray-400', { hidden: isEmpty() })}
aria-label={intl.formatMessage(messages.placeholder)}
/>
</div>
</div>
</div>
);

Wyświetl plik

@ -1,28 +1,39 @@
import React from 'react';
import React, { useRef } from 'react';
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
import { Link, useHistory } from 'react-router-dom';
import HoverRefWrapper from 'soapbox/components/hover-ref-wrapper';
import VerificationBadge from 'soapbox/components/verification-badge';
import ActionButton from 'soapbox/features/ui/components/action-button';
import { useAppSelector, useOnScreen } from 'soapbox/hooks';
import { useAppSelector } from 'soapbox/hooks';
import { getAcct } from 'soapbox/utils/accounts';
import { displayFqn } from 'soapbox/utils/state';
import Badge from './badge';
import RelativeTimestamp from './relative-timestamp';
import { Avatar, Emoji, HStack, Icon, IconButton, Stack, Text } from './ui';
import type { StatusApprovalStatus } from 'soapbox/normalizers/status';
import type { Account as AccountSchema } from 'soapbox/schemas';
import type { Account as AccountEntity } from 'soapbox/types/entities';
interface IInstanceFavicon {
account: AccountEntity,
account: AccountEntity | AccountSchema
disabled?: boolean
}
const InstanceFavicon: React.FC<IInstanceFavicon> = ({ account }) => {
const messages = defineMessages({
bot: { id: 'account.badges.bot', defaultMessage: 'Bot' },
});
const InstanceFavicon: React.FC<IInstanceFavicon> = ({ account, disabled }) => {
const history = useHistory();
const handleClick: React.MouseEventHandler = (e) => {
e.stopPropagation();
if (disabled) return;
const timelineUrl = `/timeline/${account.domain}`;
if (!(e.ctrlKey || e.metaKey)) {
history.push(timelineUrl);
@ -32,44 +43,56 @@ const InstanceFavicon: React.FC<IInstanceFavicon> = ({ account }) => {
};
return (
<button className='w-4 h-4 flex-none focus:ring-primary-500 focus:ring-2 focus:ring-offset-2' onClick={handleClick}>
<img src={account.favicon} alt='' title={account.domain} className='w-full max-h-full' />
<button
className='h-4 w-4 flex-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2'
onClick={handleClick}
disabled={disabled}
>
<img src={account.favicon} alt='' title={account.domain} className='max-h-full w-full' />
</button>
);
};
interface IProfilePopper {
condition: boolean,
wrapper: (children: any) => React.ReactElement<any, any>
condition: boolean
wrapper: (children: React.ReactNode) => React.ReactNode
children: React.ReactNode
}
const ProfilePopper: React.FC<IProfilePopper> = ({ condition, wrapper, children }): any =>
condition ? wrapper(children) : children;
const ProfilePopper: React.FC<IProfilePopper> = ({ condition, wrapper, children }) => {
return (
<>
{condition ? wrapper(children) : children}
</>
);
};
interface IAccount {
account: AccountEntity,
action?: React.ReactElement,
actionAlignment?: 'center' | 'top',
actionIcon?: string,
actionTitle?: string,
export interface IAccount {
account: AccountEntity | AccountSchema
action?: React.ReactElement
actionAlignment?: 'center' | 'top'
actionIcon?: string
actionTitle?: string
/** Override other actions for specificity like mute/unmute. */
actionType?: 'muting' | 'blocking' | 'follow_request',
avatarSize?: number,
hidden?: boolean,
hideActions?: boolean,
id?: string,
onActionClick?: (account: any) => void,
showProfileHoverCard?: boolean,
timestamp?: string,
timestampUrl?: string,
futureTimestamp?: boolean,
withAccountNote?: boolean,
withDate?: boolean,
withLinkToProfile?: boolean,
withRelationship?: boolean,
showEdit?: boolean,
emoji?: string,
note?: string,
actionType?: 'muting' | 'blocking' | 'follow_request'
avatarSize?: number
hidden?: boolean
hideActions?: boolean
id?: string
onActionClick?: (account: any) => void
showProfileHoverCard?: boolean
timestamp?: string
timestampUrl?: string
futureTimestamp?: boolean
withAccountNote?: boolean
withDate?: boolean
withLinkToProfile?: boolean
withRelationship?: boolean
showEdit?: boolean
approvalStatus?: StatusApprovalStatus
emoji?: string
emojiUrl?: string
note?: string
}
const Account = ({
@ -92,22 +115,19 @@ const Account = ({
withLinkToProfile = true,
withRelationship = true,
showEdit = false,
approvalStatus,
emoji,
emojiUrl,
note,
}: IAccount) => {
const overflowRef = React.useRef<HTMLDivElement>(null);
const actionRef = React.useRef<HTMLDivElement>(null);
// @ts-ignore
const isOnScreen = useOnScreen(overflowRef);
const [style, setStyle] = React.useState<React.CSSProperties>({ visibility: 'hidden' });
const overflowRef = useRef<HTMLDivElement>(null);
const actionRef = useRef<HTMLDivElement>(null);
const me = useAppSelector((state) => state.me);
const username = useAppSelector((state) => account ? getAcct(account, displayFqn(state)) : null);
const handleAction = () => {
// @ts-ignore
onActionClick(account);
onActionClick!(account);
};
const renderAction = () => {
@ -125,8 +145,8 @@ const Account = ({
src={actionIcon}
title={actionTitle}
onClick={handleAction}
className='bg-transparent text-gray-600 dark:text-gray-600 hover:text-gray-700 dark:hover:text-gray-500'
iconClassName='w-4 h-4'
className='bg-transparent text-gray-600 hover:text-gray-700 dark:text-gray-600 dark:hover:text-gray-500'
iconClassName='h-4 w-4'
/>
);
}
@ -138,18 +158,7 @@ const Account = ({
return null;
};
React.useEffect(() => {
const style: React.CSSProperties = {};
const actionWidth = actionRef.current?.clientWidth || 0;
if (overflowRef.current) {
style.maxWidth = overflowRef.current.clientWidth - 30 - avatarSize - actionWidth;
} else {
style.visibility = 'hidden';
}
setStyle(style);
}, [isOnScreen, overflowRef, actionRef]);
const intl = useIntl();
if (!account) {
return null;
@ -169,9 +178,9 @@ const Account = ({
const LinkEl: any = withLinkToProfile ? Link : 'div';
return (
<div data-testid='account' className='flex-shrink-0 group block w-full' ref={overflowRef}>
<div data-testid='account' className='group block w-full shrink-0' ref={overflowRef}>
<HStack alignItems={actionAlignment} justifyContent='between'>
<HStack alignItems={withAccountNote || note ? 'top' : 'center'} space={3}>
<HStack alignItems={withAccountNote || note ? 'top' : 'center'} space={3} className='overflow-hidden'>
<ProfilePopper
condition={showProfileHoverCard}
wrapper={(children) => <HoverRefWrapper className='relative' accountId={account.id} inline>{children}</HoverRefWrapper>}
@ -184,14 +193,15 @@ const Account = ({
<Avatar src={account.avatar} size={avatarSize} />
{emoji && (
<Emoji
className='w-5 h-5 absolute -bottom-1.5 -right-1.5'
className='absolute bottom-0 -right-1.5 h-5 w-5'
emoji={emoji}
src={emojiUrl}
/>
)}
</LinkEl>
</ProfilePopper>
<div className='flex-grow'>
<div className='grow overflow-hidden'>
<ProfilePopper
condition={showProfileHoverCard}
wrapper={(children) => <HoverRefWrapper accountId={account.id} inline>{children}</HoverRefWrapper>}
@ -201,7 +211,7 @@ const Account = ({
title={account.acct}
onClick={(event: React.MouseEvent) => event.stopPropagation()}
>
<HStack space={1} alignItems='center' grow style={style}>
<HStack space={1} alignItems='center' grow>
<Text
size='sm'
weight='semibold'
@ -210,16 +220,18 @@ const Account = ({
/>
{account.verified && <VerificationBadge />}
{account.bot && <Badge slug='bot' title={intl.formatMessage(messages.bot)} />}
</HStack>
</LinkEl>
</ProfilePopper>
<Stack space={withAccountNote || note ? 1 : 0}>
<HStack alignItems='center' space={1} style={style}>
<Text theme='muted' size='sm' truncate>@{username}</Text>
<HStack alignItems='center' space={1}>
<Text theme='muted' size='sm' direction='ltr' truncate>@{username}</Text>
{account.favicon && (
<InstanceFavicon account={account} />
<InstanceFavicon account={account} disabled={!withLinkToProfile} />
)}
{(timestamp) ? (
@ -236,6 +248,18 @@ const Account = ({
</>
) : null}
{approvalStatus && ['pending', 'rejected'].includes(approvalStatus) && (
<>
<Text tag='span' theme='muted' size='sm'>&middot;</Text>
<Text tag='span' theme='muted' size='sm'>
{approvalStatus === 'pending'
? <FormattedMessage id='status.approval.pending' defaultMessage='Pending approval' />
: <FormattedMessage id='status.approval.rejected' defaultMessage='Rejected' />}
</Text>
</>
)}
{showEdit ? (
<>
<Text tag='span' theme='muted' size='sm'>&middot;</Text>

Wyświetl plik

@ -15,8 +15,8 @@ const obfuscatedCount = (count: number) => {
};
interface IAnimatedNumber {
value: number;
obfuscate?: boolean;
value: number
obfuscate?: boolean
}
const AnimatedNumber: React.FC<IAnimatedNumber> = ({ value, obfuscate }) => {
@ -50,7 +50,7 @@ const AnimatedNumber: React.FC<IAnimatedNumber> = ({ value, obfuscate }) => {
return (
<TransitionMotion styles={styles} willEnter={willEnter} willLeave={willLeave}>
{items => (
<span className='inline-flex flex-col items-stretch relative overflow-hidden'>
<span className='relative inline-flex flex-col items-stretch overflow-hidden'>
{items.map(({ key, data, style }) => (
<span key={key} style={{ position: (direction * style.y) > 0 ? 'absolute' : 'static', transform: `translateY(${style.y * 100}%)` }}>{obfuscate ? obfuscatedCount(data) : <FormattedNumber value={data} />}</span>
))}

Wyświetl plik

@ -4,7 +4,7 @@ import { useHistory } from 'react-router-dom';
import type { Announcement as AnnouncementEntity, Mention as MentionEntity } from 'soapbox/types/entities';
interface IAnnouncementContent {
announcement: AnnouncementEntity;
announcement: AnnouncementEntity
}
const AnnouncementContent: React.FC<IAnnouncementContent> = ({ announcement }) => {

Wyświetl plik

@ -11,10 +11,10 @@ import type { Map as ImmutableMap } from 'immutable';
import type { Announcement as AnnouncementEntity } from 'soapbox/types/entities';
interface IAnnouncement {
announcement: AnnouncementEntity;
addReaction: (id: string, name: string) => void;
removeReaction: (id: string, name: string) => void;
emojiMap: ImmutableMap<string, ImmutableMap<string, string>>;
announcement: AnnouncementEntity
addReaction: (id: string, name: string) => void
removeReaction: (id: string, name: string) => void
emojiMap: ImmutableMap<string, ImmutableMap<string, string>>
}
const Announcement: React.FC<IAnnouncement> = ({ announcement, addReaction, removeReaction, emojiMap }) => {

Wyświetl plik

@ -1,4 +1,4 @@
import classNames from 'clsx';
import clsx from 'clsx';
import { List as ImmutableList, Map as ImmutableMap } from 'immutable';
import React, { useState } from 'react';
import { FormattedMessage } from 'react-intl';
@ -52,7 +52,7 @@ const AnnouncementsPanel = () => {
key={i}
tabIndex={0}
onClick={() => setIndex(i)}
className={classNames({
className={clsx({
'w-2 h-2 rounded-full focus:ring-primary-600 focus:ring-2 focus:ring-offset-2': true,
'bg-gray-200 hover:bg-gray-300': i !== index,
'bg-primary-600': i === index,

Wyświetl plik

@ -1,15 +1,15 @@
import React from 'react';
import unicodeMapping from 'soapbox/features/emoji/emoji-unicode-mapping-light';
import unicodeMapping from 'soapbox/features/emoji/mapping';
import { useSettings } from 'soapbox/hooks';
import { joinPublicPath } from 'soapbox/utils/static';
import type { Map as ImmutableMap } from 'immutable';
interface IEmoji {
emoji: string;
emojiMap: ImmutableMap<string, ImmutableMap<string, string>>;
hovered: boolean;
emoji: string
emojiMap: ImmutableMap<string, ImmutableMap<string, string>>
hovered: boolean
}
const Emoji: React.FC<IEmoji> = ({ emoji, emojiMap, hovered }) => {
@ -24,7 +24,7 @@ const Emoji: React.FC<IEmoji> = ({ emoji, emojiMap, hovered }) => {
return (
<img
draggable='false'
className='emojione block m-0'
className='emojione m-0 block'
alt={emoji}
title={title}
src={joinPublicPath(`packs/emoji/${filename}.svg`)}
@ -37,7 +37,7 @@ const Emoji: React.FC<IEmoji> = ({ emoji, emojiMap, hovered }) => {
return (
<img
draggable='false'
className='emojione block m-0'
className='emojione m-0 block'
alt={shortCode}
title={shortCode}
src={filename as string}

Wyświetl plik

@ -1,8 +1,8 @@
import classNames from 'clsx';
import clsx from 'clsx';
import React, { useState } from 'react';
import AnimatedNumber from 'soapbox/components/animated-number';
import unicodeMapping from 'soapbox/features/emoji/emoji-unicode-mapping-light';
import unicodeMapping from 'soapbox/features/emoji/mapping';
import Emoji from './emoji';
@ -10,12 +10,12 @@ import type { Map as ImmutableMap } from 'immutable';
import type { AnnouncementReaction } from 'soapbox/types/entities';
interface IReaction {
announcementId: string;
reaction: AnnouncementReaction;
emojiMap: ImmutableMap<string, ImmutableMap<string, string>>;
addReaction: (id: string, name: string) => void;
removeReaction: (id: string, name: string) => void;
style: React.CSSProperties;
announcementId: string
reaction: AnnouncementReaction
emojiMap: ImmutableMap<string, ImmutableMap<string, string>>
addReaction: (id: string, name: string) => void
removeReaction: (id: string, name: string) => void
style: React.CSSProperties
}
const Reaction: React.FC<IReaction> = ({ announcementId, reaction, addReaction, removeReaction, emojiMap, style }) => {
@ -43,7 +43,7 @@ const Reaction: React.FC<IReaction> = ({ announcementId, reaction, addReaction,
return (
<button
className={classNames('flex shrink-0 items-center gap-1.5 bg-gray-100 dark:bg-primary-900 rounded-sm px-1.5 py-1 transition-colors', {
className={clsx('flex shrink-0 items-center gap-1.5 rounded-sm bg-gray-100 px-1.5 py-1 transition-colors dark:bg-primary-900', {
'bg-gray-200 dark:bg-primary-800': hovered,
'bg-primary-200 dark:bg-primary-500': reaction.me,
})}

Wyświetl plik

@ -1,30 +1,29 @@
import classNames from 'clsx';
import clsx from 'clsx';
import React from 'react';
import { TransitionMotion, spring } from 'react-motion';
import { Icon } from 'soapbox/components/ui';
import EmojiPickerDropdown from 'soapbox/features/compose/components/emoji-picker/emoji-picker-dropdown';
import EmojiPickerDropdown from 'soapbox/features/emoji/containers/emoji-picker-dropdown-container';
import { useSettings } from 'soapbox/hooks';
import Reaction from './reaction';
import type { List as ImmutableList, Map as ImmutableMap } from 'immutable';
import type { Emoji } from 'soapbox/components/autosuggest-emoji';
import type { Emoji, NativeEmoji } from 'soapbox/features/emoji';
import type { AnnouncementReaction } from 'soapbox/types/entities';
interface IReactionsBar {
announcementId: string;
reactions: ImmutableList<AnnouncementReaction>;
emojiMap: ImmutableMap<string, ImmutableMap<string, string>>;
addReaction: (id: string, name: string) => void;
removeReaction: (id: string, name: string) => void;
announcementId: string
reactions: ImmutableList<AnnouncementReaction>
emojiMap: ImmutableMap<string, ImmutableMap<string, string>>
addReaction: (id: string, name: string) => void
removeReaction: (id: string, name: string) => void
}
const ReactionsBar: React.FC<IReactionsBar> = ({ announcementId, reactions, addReaction, removeReaction, emojiMap }) => {
const reduceMotion = useSettings().get('reduceMotion');
const handleEmojiPick = (data: Emoji) => {
addReaction(announcementId, data.native.replace(/:/g, ''));
addReaction(announcementId, (data as NativeEmoji).native.replace(/:/g, ''));
};
const willEnter = () => ({ scale: reduceMotion ? 1 : 0 });
@ -42,7 +41,7 @@ const ReactionsBar: React.FC<IReactionsBar> = ({ announcementId, reactions, addR
return (
<TransitionMotion styles={styles} willEnter={willEnter} willLeave={willLeave}>
{items => (
<div className={classNames('flex flex-wrap items-center gap-1', { 'reactions-bar--empty': visibleReactions.isEmpty() })}>
<div className={clsx('flex flex-wrap items-center gap-1', { 'reactions-bar--empty': visibleReactions.isEmpty() })}>
{items.map(({ key, data, style }) => (
<Reaction
key={key}
@ -55,7 +54,7 @@ const ReactionsBar: React.FC<IReactionsBar> = ({ announcementId, reactions, addR
/>
))}
{visibleReactions.size < 8 && <EmojiPickerDropdown onPickEmoji={handleEmojiPick} button={<Icon className='h-4 w-4 text-gray-400 hover:text-gray-600 dark:hover:text-white' src={require('@tabler/icons/plus.svg')} />} />}
{visibleReactions.size < 8 && <EmojiPickerDropdown onPickEmoji={handleEmojiPick} />}
</div>
)}
</TransitionMotion>

Wyświetl plik

@ -0,0 +1,139 @@
import clsx from 'clsx';
import React, { useEffect, useRef, useState } from 'react';
import { FormattedMessage } from 'react-intl';
import { HStack, IconButton, Text } from 'soapbox/components/ui';
interface IAuthorizeRejectButtons {
onAuthorize(): Promise<unknown> | unknown
onReject(): Promise<unknown> | unknown
countdown?: number
}
/** Buttons to approve or reject a pending item, usually an account. */
const AuthorizeRejectButtons: React.FC<IAuthorizeRejectButtons> = ({ onAuthorize, onReject, countdown }) => {
const [state, setState] = useState<'authorizing' | 'rejecting' | 'authorized' | 'rejected' | 'pending'>('pending');
const timeout = useRef<NodeJS.Timeout>();
function handleAction(
present: 'authorizing' | 'rejecting',
past: 'authorized' | 'rejected',
action: () => Promise<unknown> | unknown,
): void {
if (state === present) {
if (timeout.current) {
clearTimeout(timeout.current);
}
setState('pending');
} else {
const doAction = async () => {
try {
await action();
setState(past);
} catch (e) {
console.error(e);
}
};
if (typeof countdown === 'number') {
setState(present);
timeout.current = setTimeout(doAction, countdown);
} else {
doAction();
}
}
}
const handleAuthorize = async () => handleAction('authorizing', 'authorized', onAuthorize);
const handleReject = async () => handleAction('rejecting', 'rejected', onReject);
useEffect(() => {
return () => {
if (timeout.current) {
clearTimeout(timeout.current);
}
};
}, []);
switch (state) {
case 'authorized':
return (
<ActionEmblem text={<FormattedMessage id='authorize.success' defaultMessage='Approved' />} />
);
case 'rejected':
return (
<ActionEmblem text={<FormattedMessage id='reject.success' defaultMessage='Rejected' />} />
);
default:
return (
<HStack space={3} alignItems='center'>
<AuthorizeRejectButton
theme='danger'
icon={require('@tabler/icons/x.svg')}
action={handleReject}
isLoading={state === 'rejecting'}
disabled={state === 'authorizing'}
/>
<AuthorizeRejectButton
theme='primary'
icon={require('@tabler/icons/check.svg')}
action={handleAuthorize}
isLoading={state === 'authorizing'}
disabled={state === 'rejecting'}
/>
</HStack>
);
}
};
interface IActionEmblem {
text: React.ReactNode
}
const ActionEmblem: React.FC<IActionEmblem> = ({ text }) => {
return (
<div className='rounded-full bg-gray-100 px-4 py-2 dark:bg-gray-800'>
<Text theme='muted' size='sm'>
{text}
</Text>
</div>
);
};
interface IAuthorizeRejectButton {
theme: 'primary' | 'danger'
icon: string
action(): void
isLoading?: boolean
disabled?: boolean
}
const AuthorizeRejectButton: React.FC<IAuthorizeRejectButton> = ({ theme, icon, action, isLoading, disabled }) => {
return (
<div className='relative'>
<IconButton
src={isLoading ? require('@tabler/icons/player-stop-filled.svg') : icon}
onClick={action}
theme='seamless'
className={clsx('h-10 w-10 items-center justify-center border-2', {
'border-primary-500/10 hover:border-primary-500': theme === 'primary',
'border-danger-600/10 hover:border-danger-600': theme === 'danger',
})}
iconClassName={clsx('h-6 w-6', {
'text-primary-500': theme === 'primary',
'text-danger-600': theme === 'danger',
})}
disabled={disabled}
/>
{(isLoading) && (
<div
className={clsx('pointer-events-none absolute inset-0 h-10 w-10 animate-spin rounded-full border-2 border-transparent', {
'border-t-primary-500': theme === 'primary',
'border-t-danger-600': theme === 'danger',
})}
/>
)}
</div>
);
};
export { AuthorizeRejectButtons };

Wyświetl plik

@ -12,15 +12,16 @@ import type { InputThemes } from 'soapbox/components/ui/input/input';
const noOp = () => { };
interface IAutosuggestAccountInput {
onChange: React.ChangeEventHandler<HTMLInputElement>,
onSelected: (accountId: string) => void,
value: string,
limit?: number,
className?: string,
autoSelect?: boolean,
menu?: Menu,
onKeyDown?: React.KeyboardEventHandler,
theme?: InputThemes,
onChange: React.ChangeEventHandler<HTMLInputElement>
onSelected: (accountId: string) => void
autoFocus?: boolean
value: string
limit?: number
className?: string
autoSelect?: boolean
menu?: Menu
onKeyDown?: React.KeyboardEventHandler
theme?: InputThemes
}
const AutosuggestAccountInput: React.FC<IAutosuggestAccountInput> = ({
@ -43,7 +44,7 @@ const AutosuggestAccountInput: React.FC<IAutosuggestAccountInput> = ({
setAccountIds(ImmutableOrderedSet());
};
const handleAccountSearch = useCallback(throttle(q => {
const handleAccountSearch = useCallback(throttle((q) => {
const params = { q, limit, resolve: false };
dispatch(accountSearch(params, controller.current.signal))
@ -52,7 +53,6 @@ const AutosuggestAccountInput: React.FC<IAutosuggestAccountInput> = ({
setAccountIds(ImmutableOrderedSet(accountIds));
})
.catch(noOp);
}, 900, { leading: true, trailing: true }), [limit]);
const handleChange: React.ChangeEventHandler<HTMLInputElement> = e => {
@ -67,6 +67,12 @@ const AutosuggestAccountInput: React.FC<IAutosuggestAccountInput> = ({
}
};
useEffect(() => {
if (rest.autoFocus) {
handleAccountSearch('');
}
}, []);
useEffect(() => {
if (value === '') {
clearResults();

Wyświetl plik

@ -1,38 +1,30 @@
import React from 'react';
import unicodeMapping from 'soapbox/features/emoji/emoji-unicode-mapping-light';
import { isCustomEmoji } from 'soapbox/features/emoji';
import unicodeMapping from 'soapbox/features/emoji/mapping';
import { joinPublicPath } from 'soapbox/utils/static';
export type Emoji = {
id: string,
custom: boolean,
imageUrl: string,
native: string,
colons: string,
}
type UnicodeMapping = {
filename: string,
}
import type { Emoji } from 'soapbox/features/emoji';
interface IAutosuggestEmoji {
emoji: Emoji,
emoji: Emoji
}
const AutosuggestEmoji: React.FC<IAutosuggestEmoji> = ({ emoji }) => {
let url;
let url, alt;
if (emoji.custom) {
if (isCustomEmoji(emoji)) {
url = emoji.imageUrl;
alt = emoji.colons;
} else {
// @ts-ignore
const mapping: UnicodeMapping = unicodeMapping[emoji.native] || unicodeMapping[emoji.native.replace(/\uFE0F$/, '')];
const mapping = unicodeMapping[emoji.native] || unicodeMapping[emoji.native.replace(/\uFE0F$/, '')];
if (!mapping) {
return null;
}
url = joinPublicPath(`packs/emoji/${mapping.filename}.svg`);
url = joinPublicPath(`packs/emoji/${mapping.unified}.svg`);
alt = emoji.native;
}
return (
@ -40,7 +32,7 @@ const AutosuggestEmoji: React.FC<IAutosuggestEmoji> = ({ emoji }) => {
<img
className='emojione'
src={url}
alt={emoji.native || emoji.colons}
alt={alt}
/>
{emoji.colons}

Wyświetl plik

@ -1,68 +1,39 @@
import { Portal } from '@reach/portal';
import classNames from 'clsx';
import clsx from 'clsx';
import { List as ImmutableList } from 'immutable';
import React from 'react';
import ImmutablePureComponent from 'react-immutable-pure-component';
import AutosuggestEmoji, { Emoji } from 'soapbox/components/autosuggest-emoji';
import AutosuggestEmoji from 'soapbox/components/autosuggest-emoji';
import Icon from 'soapbox/components/icon';
import { Input } from 'soapbox/components/ui';
import { Input, Portal } from 'soapbox/components/ui';
import AutosuggestAccount from 'soapbox/features/compose/components/autosuggest-account';
import { isRtl } from 'soapbox/rtl';
import { textAtCursorMatchesToken } from 'soapbox/utils/suggestions';
import type { Menu, MenuItem } from 'soapbox/components/dropdown-menu';
import type { InputThemes } from 'soapbox/components/ui/input/input';
type CursorMatch = [
tokenStart: number | null,
token: string | null,
];
import type { Emoji } from 'soapbox/features/emoji';
export type AutoSuggestion = string | Emoji;
const textAtCursorMatchesToken = (str: string, caretPosition: number, searchTokens: string[]): CursorMatch => {
let word: string;
const left: number = str.slice(0, caretPosition).search(/\S+$/);
const right: number = str.slice(caretPosition).search(/\s/);
if (right < 0) {
word = str.slice(left);
} else {
word = str.slice(left, right + caretPosition);
}
if (!word || word.trim().length < 3 || !searchTokens.includes(word[0])) {
return [null, null];
}
word = word.trim().toLowerCase();
if (word.length > 0) {
return [left + 1, word];
} else {
return [null, null];
}
};
export interface IAutosuggestInput extends Pick<React.HTMLAttributes<HTMLInputElement>, 'onChange' | 'onKeyUp' | 'onKeyDown'> {
value: string,
suggestions: ImmutableList<any>,
disabled?: boolean,
placeholder?: string,
onSuggestionSelected: (tokenStart: number, lastToken: string | null, suggestion: AutoSuggestion) => void,
onSuggestionsClearRequested: () => void,
onSuggestionsFetchRequested: (token: string) => void,
autoFocus: boolean,
autoSelect: boolean,
className?: string,
id?: string,
searchTokens: string[],
maxLength?: number,
menu?: Menu,
resultsPosition: string,
renderSuggestion?: React.FC<{ id: string }>,
theme?: InputThemes,
value: string
suggestions: ImmutableList<any>
disabled?: boolean
placeholder?: string
onSuggestionSelected: (tokenStart: number, lastToken: string | null, suggestion: AutoSuggestion) => void
onSuggestionsClearRequested: () => void
onSuggestionsFetchRequested: (token: string) => void
autoFocus: boolean
autoSelect: boolean
className?: string
id?: string
searchTokens: string[]
maxLength?: number
menu?: Menu
renderSuggestion?: React.FC<{ id: string }>
hidePortal?: boolean
theme?: InputThemes
}
export default class AutosuggestInput extends ImmutablePureComponent<IAutosuggestInput> {
@ -71,12 +42,11 @@ export default class AutosuggestInput extends ImmutablePureComponent<IAutosugges
autoFocus: false,
autoSelect: true,
searchTokens: ImmutableList(['@', ':', '#']),
resultsPosition: 'below',
};
getFirstIndex = () => {
return this.props.autoSelect ? 0 : -1;
}
};
state = {
suggestionsHidden: true,
@ -89,7 +59,11 @@ export default class AutosuggestInput extends ImmutablePureComponent<IAutosugges
input: HTMLInputElement | null = null;
onChange: React.ChangeEventHandler<HTMLInputElement> = (e) => {
const [tokenStart, token] = textAtCursorMatchesToken(e.target.value, e.target.selectionStart || 0, this.props.searchTokens);
const [tokenStart, token] = textAtCursorMatchesToken(
e.target.value,
e.target.selectionStart || 0,
this.props.searchTokens,
);
if (token !== null && this.state.lastToken !== token) {
this.setState({ lastToken: token, selectedSuggestion: 0, tokenStart });
@ -102,7 +76,7 @@ export default class AutosuggestInput extends ImmutablePureComponent<IAutosugges
if (this.props.onChange) {
this.props.onChange(e);
}
}
};
onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = (e) => {
const { suggestions, menu, disabled } = this.props;
@ -171,15 +145,15 @@ export default class AutosuggestInput extends ImmutablePureComponent<IAutosugges
if (this.props.onKeyDown) {
this.props.onKeyDown(e);
}
}
};
onBlur = () => {
this.setState({ suggestionsHidden: true, focused: false });
}
};
onFocus = () => {
this.setState({ focused: true });
}
};
onSuggestionClick: React.EventHandler<React.MouseEvent | React.TouchEvent> = (e) => {
const index = Number(e.currentTarget?.getAttribute('data-index'));
@ -187,7 +161,7 @@ export default class AutosuggestInput extends ImmutablePureComponent<IAutosugges
this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestion);
this.input?.focus();
e.preventDefault();
}
};
componentDidUpdate(prevProps: IAutosuggestInput, prevState: any) {
const { suggestions } = this.props;
@ -198,7 +172,7 @@ export default class AutosuggestInput extends ImmutablePureComponent<IAutosugges
setInput = (c: HTMLInputElement) => {
this.input = c;
}
};
renderSuggestion = (suggestion: AutoSuggestion, i: number) => {
const { selectedSuggestion } = this.state;
@ -225,7 +199,7 @@ export default class AutosuggestInput extends ImmutablePureComponent<IAutosugges
tabIndex={0}
key={key}
data-index={i}
className={classNames({
className={clsx({
'px-4 py-2.5 text-sm text-gray-700 dark:text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-800 focus:bg-gray-100 dark:focus:bg-primary-800 group': true,
'bg-gray-100 dark:bg-gray-800 hover:bg-gray-100 dark:hover:bg-gray-800': i === selectedSuggestion,
})}
@ -235,21 +209,21 @@ export default class AutosuggestInput extends ImmutablePureComponent<IAutosugges
{inner}
</div>
);
}
};
handleMenuItemAction = (item: MenuItem | null, e: React.MouseEvent | React.KeyboardEvent) => {
this.onBlur();
if (item?.action) {
item.action(e);
}
}
};
handleMenuItemClick = (item: MenuItem | null): React.MouseEventHandler => {
return e => {
e.preventDefault();
this.handleMenuItemAction(item, e);
};
}
};
renderMenu = () => {
const { menu, suggestions } = this.props;
@ -261,7 +235,7 @@ export default class AutosuggestInput extends ImmutablePureComponent<IAutosugges
return menu.map((item, i) => (
<a
className={classNames('flex items-center space-x-2 px-4 py-2.5 text-sm cursor-pointer text-gray-700 dark:text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-800 focus:bg-gray-100 dark:focus:bg-primary-800', { selected: suggestions.size - selectedSuggestion === i })}
className={clsx('flex cursor-pointer items-center space-x-2 px-4 py-2.5 text-sm text-gray-700 hover:bg-gray-100 focus:bg-gray-100 dark:text-gray-500 dark:hover:bg-gray-800 dark:focus:bg-primary-800', { selected: suggestions.size - selectedSuggestion === i })}
href='#'
role='button'
tabIndex={0}
@ -284,11 +258,7 @@ export default class AutosuggestInput extends ImmutablePureComponent<IAutosugges
const { top, height, left, width } = this.input.getBoundingClientRect();
if (this.props.resultsPosition === 'below') {
return { left, width, top: top + height };
}
return { left, width, top, transform: 'translate(0, -100%)' };
return { left, width, top: top + height };
}
render() {
@ -298,7 +268,8 @@ export default class AutosuggestInput extends ImmutablePureComponent<IAutosugges
const visible = !suggestionsHidden && (!suggestions.isEmpty() || (menu && value));
if (isRtl(value)) {
// TODO: convert to functional component and use `useLocale()` hook instead of checking placeholder text.
if (isRtl(value) || (!value && placeholder && isRtl(placeholder))) {
style.direction = 'rtl';
}
@ -331,7 +302,7 @@ export default class AutosuggestInput extends ImmutablePureComponent<IAutosugges
<Portal key='portal'>
<div
style={this.setPortalPosition()}
className={classNames({
className={clsx({
'fixed w-full z-[1001] shadow bg-white dark:bg-gray-900 rounded-lg py-1 dark:ring-2 dark:ring-primary-700 focus:outline-none': true,
hidden: !visible,
block: visible,

Wyświetl plik

@ -19,7 +19,7 @@ export const ADDRESS_ICONS: Record<string, string> = {
};
interface IAutosuggestLocation {
id: string,
id: string
}
const AutosuggestLocation: React.FC<IAutosuggestLocation> = ({ id }) => {
@ -32,7 +32,7 @@ const AutosuggestLocation: React.FC<IAutosuggestLocation> = ({ id }) => {
<Icon src={ADDRESS_ICONS[location.type] || mapPinIcon} />
<Stack>
<Text>{location.description}</Text>
<Text size='xs' theme='muted'>{[location.street, location.locality, location.country].filter(val => val.trim()).join(' · ')}</Text>
<Text size='xs' theme='muted'>{[location.street, location.locality, location.country].filter(val => val?.trim()).join(' · ')}</Text>
</Stack>
</HStack>
);

Wyświetl plik

@ -1,58 +1,36 @@
import { Portal } from '@reach/portal';
import classNames from 'clsx';
import clsx from 'clsx';
import React from 'react';
import ImmutablePureComponent from 'react-immutable-pure-component';
import Textarea from 'react-textarea-autosize';
import AutosuggestAccount from '../features/compose/components/autosuggest-account';
import { isRtl } from '../rtl';
import { Portal } from 'soapbox/components/ui';
import AutosuggestAccount from 'soapbox/features/compose/components/autosuggest-account';
import { isRtl } from 'soapbox/rtl';
import { textAtCursorMatchesToken } from 'soapbox/utils/suggestions';
import AutosuggestEmoji, { Emoji } from './autosuggest-emoji';
import AutosuggestEmoji from './autosuggest-emoji';
import type { List as ImmutableList } from 'immutable';
const textAtCursorMatchesToken = (str: string, caretPosition: number) => {
let word;
const left = str.slice(0, caretPosition).search(/\S+$/);
const right = str.slice(caretPosition).search(/\s/);
if (right < 0) {
word = str.slice(left);
} else {
word = str.slice(left, right + caretPosition);
}
if (!word || word.trim().length < 3 || !['@', ':', '#'].includes(word[0])) {
return [null, null];
}
word = word.trim().toLowerCase();
if (word.length > 0) {
return [left + 1, word];
} else {
return [null, null];
}
};
import type { Emoji } from 'soapbox/features/emoji';
interface IAutosuggesteTextarea {
id?: string,
value: string,
suggestions: ImmutableList<string>,
disabled: boolean,
placeholder: string,
onSuggestionSelected: (tokenStart: number, token: string | null, value: string | undefined) => void,
onSuggestionsClearRequested: () => void,
onSuggestionsFetchRequested: (token: string | number) => void,
onChange: React.ChangeEventHandler<HTMLTextAreaElement>,
onKeyUp?: React.KeyboardEventHandler<HTMLTextAreaElement>,
onKeyDown?: React.KeyboardEventHandler<HTMLTextAreaElement>,
onPaste: (files: FileList) => void,
autoFocus: boolean,
onFocus: () => void,
onBlur?: () => void,
condensed?: boolean,
id?: string
value: string
suggestions: ImmutableList<string>
disabled: boolean
placeholder: string
onSuggestionSelected: (tokenStart: number, token: string | null, value: string | undefined) => void
onSuggestionsClearRequested: () => void
onSuggestionsFetchRequested: (token: string | number) => void
onChange: React.ChangeEventHandler<HTMLTextAreaElement>
onKeyUp?: React.KeyboardEventHandler<HTMLTextAreaElement>
onKeyDown?: React.KeyboardEventHandler<HTMLTextAreaElement>
onPaste: (files: FileList) => void
autoFocus: boolean
onFocus: () => void
onBlur?: () => void
condensed?: boolean
children: React.ReactNode
}
class AutosuggestTextarea extends ImmutablePureComponent<IAutosuggesteTextarea> {
@ -72,7 +50,11 @@ class AutosuggestTextarea extends ImmutablePureComponent<IAutosuggesteTextarea>
};
onChange: React.ChangeEventHandler<HTMLTextAreaElement> = (e) => {
const [tokenStart, token] = textAtCursorMatchesToken(e.target.value, e.target.selectionStart);
const [tokenStart, token] = textAtCursorMatchesToken(
e.target.value,
e.target.selectionStart,
['@', ':', '#'],
);
if (token !== null && this.state.lastToken !== token) {
this.setState({ lastToken: token, selectedSuggestion: 0, tokenStart });
@ -83,7 +65,7 @@ class AutosuggestTextarea extends ImmutablePureComponent<IAutosuggesteTextarea>
}
this.props.onChange(e);
}
};
onKeyDown: React.KeyboardEventHandler<HTMLTextAreaElement> = (e) => {
const { suggestions, disabled } = this.props;
@ -141,7 +123,7 @@ class AutosuggestTextarea extends ImmutablePureComponent<IAutosuggesteTextarea>
}
this.props.onKeyDown(e);
}
};
onBlur = () => {
this.setState({ suggestionsHidden: true, focused: false });
@ -149,7 +131,7 @@ class AutosuggestTextarea extends ImmutablePureComponent<IAutosuggesteTextarea>
if (this.props.onBlur) {
this.props.onBlur();
}
}
};
onFocus = () => {
this.setState({ focused: true });
@ -157,14 +139,14 @@ class AutosuggestTextarea extends ImmutablePureComponent<IAutosuggesteTextarea>
if (this.props.onFocus) {
this.props.onFocus();
}
}
};
onSuggestionClick: React.MouseEventHandler<HTMLDivElement> = (e) => {
const suggestion = this.props.suggestions.get(e.currentTarget.getAttribute('data-index') as any);
e.preventDefault();
this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestion);
this.textarea?.focus();
}
};
shouldComponentUpdate(nextProps: IAutosuggesteTextarea, nextState: any) {
// Skip updating when only the lastToken changes so the
@ -175,7 +157,8 @@ class AutosuggestTextarea extends ImmutablePureComponent<IAutosuggesteTextarea>
if (lastTokenUpdated && !valueUpdated) {
return false;
} else {
return super.shouldComponentUpdate!(nextProps, nextState, undefined);
// https://stackoverflow.com/a/35962835
return super.shouldComponentUpdate!.bind(this)(nextProps, nextState, undefined);
}
}
@ -188,14 +171,14 @@ class AutosuggestTextarea extends ImmutablePureComponent<IAutosuggesteTextarea>
setTextarea: React.Ref<HTMLTextAreaElement> = (c) => {
this.textarea = c;
}
};
onPaste: React.ClipboardEventHandler<HTMLTextAreaElement> = (e) => {
if (e.clipboardData && e.clipboardData.files.length === 1) {
this.props.onPaste(e.clipboardData.files);
e.preventDefault();
}
}
};
renderSuggestion = (suggestion: string | Emoji, i: number) => {
const { selectedSuggestion } = this.state;
@ -218,7 +201,7 @@ class AutosuggestTextarea extends ImmutablePureComponent<IAutosuggesteTextarea>
tabIndex={0}
key={key}
data-index={i}
className={classNames({
className={clsx({
'px-4 py-2.5 text-sm text-gray-700 dark:text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-800 focus:bg-gray-100 dark:focus:bg-primary-800 group': true,
'bg-gray-100 dark:bg-gray-800 hover:bg-gray-100 dark:hover:bg-gray-800': i === selectedSuggestion,
})}
@ -227,7 +210,7 @@ class AutosuggestTextarea extends ImmutablePureComponent<IAutosuggesteTextarea>
{inner}
</div>
);
}
};
setPortalPosition() {
if (!this.textarea) {
@ -248,7 +231,8 @@ class AutosuggestTextarea extends ImmutablePureComponent<IAutosuggesteTextarea>
const { suggestionsHidden } = this.state;
const style = { direction: 'ltr', minRows: 10 };
if (isRtl(value)) {
// TODO: convert to functional component and use `useLocale()` hook instead of checking placeholder text.
if (isRtl(value) || (!value && placeholder && isRtl(placeholder))) {
style.direction = 'rtl';
}
@ -260,7 +244,7 @@ class AutosuggestTextarea extends ImmutablePureComponent<IAutosuggesteTextarea>
<Textarea
ref={this.setTextarea}
className={classNames('transition-[min-height] motion-reduce:transition-none dark:bg-transparent px-0 border-0 text-gray-800 dark:text-white placeholder:text-gray-600 dark:placeholder:text-gray-600 resize-none w-full focus:shadow-none focus:border-0 focus:ring-0', {
className={clsx('w-full resize-none border-0 px-0 text-gray-800 transition-[min-height] placeholder:text-gray-600 focus:border-0 focus:shadow-none focus:ring-0 motion-reduce:transition-none dark:bg-transparent dark:text-white dark:placeholder:text-gray-600', {
'min-h-[40px]': condensed,
'min-h-[100px]': !condensed,
})}
@ -287,7 +271,7 @@ class AutosuggestTextarea extends ImmutablePureComponent<IAutosuggesteTextarea>
<Portal key='portal'>
<div
style={this.setPortalPosition()}
className={classNames({
className={clsx({
'fixed z-1000 shadow bg-white dark:bg-gray-900 rounded-lg py-1 space-y-0 dark:ring-2 dark:ring-primary-700 focus:outline-none': true,
hidden: suggestionsHidden || suggestions.isEmpty(),
block: !suggestionsHidden && !suggestions.isEmpty(),

Wyświetl plik

@ -1,19 +0,0 @@
import React from 'react';
import StillImage from 'soapbox/components/still-image';
import type { Account as AccountEntity } from 'soapbox/types/entities';
interface IAvatarOverlay {
account: AccountEntity,
friend: AccountEntity,
}
const AvatarOverlay: React.FC<IAvatarOverlay> = ({ account, friend }) => (
<div className='account__avatar-overlay'>
<StillImage src={account.avatar} className='account__avatar-overlay-base' />
<StillImage src={friend.avatar} className='account__avatar-overlay-overlay' />
</div>
);
export default AvatarOverlay;

Wyświetl plik

@ -1,38 +0,0 @@
import classNames from 'clsx';
import React from 'react';
import StillImage from 'soapbox/components/still-image';
import type { Account } from 'soapbox/types/entities';
interface IAvatar {
account?: Account | null,
size?: number,
className?: string,
}
/**
* Legacy avatar component.
* @see soapbox/components/ui/avatar/avatar.tsx
* @deprecated
*/
const Avatar: React.FC<IAvatar> = ({ account, size, className }) => {
if (!account) return null;
// : TODO : remove inline and change all avatars to be sized using css
const style: React.CSSProperties = !size ? {} : {
width: `${size}px`,
height: `${size}px`,
};
return (
<StillImage
className={classNames('rounded-full overflow-hidden', className)}
style={style}
src={account.avatar}
alt=''
/>
);
};
export default Avatar;

Wyświetl plik

@ -1,9 +1,9 @@
import classNames from 'clsx';
import clsx from 'clsx';
import React from 'react';
interface IBadge {
title: React.ReactNode,
slug: string,
title: React.ReactNode
slug: string
}
/** Badge to display on a user's profile. */
const Badge: React.FC<IBadge> = ({ title, slug }) => {
@ -12,13 +12,13 @@ const Badge: React.FC<IBadge> = ({ title, slug }) => {
return (
<span
data-testid='badge'
className={classNames('inline-flex items-center px-2 py-0.5 rounded text-xs font-medium', {
className={clsx('inline-flex items-center rounded px-2 py-0.5 text-xs font-medium', {
'bg-fuchsia-700 text-white': slug === 'patron',
'bg-emerald-800 text-white': slug === 'badge:donor',
'bg-black text-white': slug === 'admin',
'bg-cyan-600 text-white': slug === 'moderator',
'bg-gray-100 dark:bg-gray-800 text-gray-900 dark:text-gray-100': fallback,
'bg-white bg-opacity-75 text-gray-900': slug === 'opaque',
'bg-white/75 text-gray-900': slug === 'opaque',
})}
>
{title}

Wyświetl plik

@ -15,9 +15,9 @@ const messages = defineMessages({
});
interface IBirthdayInput {
value?: string,
onChange: (value: string) => void,
required?: boolean,
value?: string
onChange: (value: string) => void
required?: boolean
}
const BirthdayInput: React.FC<IBirthdayInput> = ({ value, onChange, required }) => {
@ -56,21 +56,21 @@ const BirthdayInput: React.FC<IBirthdayInput> = ({ value, onChange, required })
nextYearButtonDisabled,
date,
}: {
decreaseMonth(): void,
increaseMonth(): void,
prevMonthButtonDisabled: boolean,
nextMonthButtonDisabled: boolean,
decreaseYear(): void,
increaseYear(): void,
prevYearButtonDisabled: boolean,
nextYearButtonDisabled: boolean,
date: Date,
decreaseMonth(): void
increaseMonth(): void
prevMonthButtonDisabled: boolean
nextMonthButtonDisabled: boolean
decreaseYear(): void
increaseYear(): void
prevYearButtonDisabled: boolean
nextYearButtonDisabled: boolean
date: Date
}) => {
return (
<div className='flex flex-col gap-2'>
<div className='flex items-center justify-between'>
<IconButton
className='datepicker__button'
className='datepicker__button rtl:rotate-180'
src={require('@tabler/icons/chevron-left.svg')}
onClick={decreaseMonth}
disabled={prevMonthButtonDisabled}
@ -79,7 +79,7 @@ const BirthdayInput: React.FC<IBirthdayInput> = ({ value, onChange, required })
/>
{intl.formatDate(date, { month: 'long' })}
<IconButton
className='datepicker__button'
className='datepicker__button rtl:rotate-180'
src={require('@tabler/icons/chevron-right.svg')}
onClick={increaseMonth}
disabled={nextMonthButtonDisabled}
@ -89,7 +89,7 @@ const BirthdayInput: React.FC<IBirthdayInput> = ({ value, onChange, required })
</div>
<div className='flex items-center justify-between'>
<IconButton
className='datepicker__button'
className='datepicker__button rtl:rotate-180'
src={require('@tabler/icons/chevron-left.svg')}
onClick={decreaseYear}
disabled={prevYearButtonDisabled}
@ -98,7 +98,7 @@ const BirthdayInput: React.FC<IBirthdayInput> = ({ value, onChange, required })
/>
{intl.formatDate(date, { year: 'numeric' })}
<IconButton
className='datepicker__button'
className='datepicker__button rtl:rotate-180'
src={require('@tabler/icons/chevron-right.svg')}
onClick={increaseYear}
disabled={nextYearButtonDisabled}
@ -113,7 +113,7 @@ const BirthdayInput: React.FC<IBirthdayInput> = ({ value, onChange, required })
const handleChange = (date: Date) => onChange(date ? new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toISOString().slice(0, 10) : '');
return (
<div className='mt-1 relative rounded-md shadow-sm'>
<div className='relative mt-1 rounded-md shadow-sm'>
<BundleContainer fetchComponent={DatePicker}>
{Component => (<Component
selected={selected}

Wyświetl plik

@ -3,18 +3,18 @@ import React, { useRef, useEffect } from 'react';
interface IBlurhash {
/** Hash to render */
hash: string | null | undefined,
hash: string | null | undefined
/** Width of the blurred region in pixels. Defaults to 32. */
width?: number,
width?: number
/** Height of the blurred region in pixels. Defaults to width. */
height?: number,
height?: number
/**
* Whether dummy mode is enabled. If enabled, nothing is rendered
* and canvas left untouched.
*/
dummy?: boolean,
dummy?: boolean
/** className of the canvas element. */
className?: string,
className?: string
}
/**

Wyświetl plik

@ -5,7 +5,7 @@ import { Button, HStack, Input } from './ui';
interface ICopyableInput {
/** Text to be copied. */
value: string,
value: string
}
/** An input with copy abilities. */
@ -29,7 +29,7 @@ const CopyableInput: React.FC<ICopyableInput> = ({ value }) => {
type='text'
value={value}
className='rounded-r-none rtl:rounded-l-none rtl:rounded-r-lg'
outerClassName='flex-grow'
outerClassName='grow'
onClick={selectInput}
readOnly
/>

Wyświetl plik

@ -5,8 +5,6 @@ import { useSoapboxConfig } from 'soapbox/hooks';
import { getAcct } from '../utils/accounts';
import Icon from './icon';
import RelativeTimestamp from './relative-timestamp';
import { HStack, Text } from './ui';
import VerificationBadge from './verification-badge';
@ -15,19 +13,12 @@ import type { Account } from 'soapbox/types/entities';
interface IDisplayName {
account: Account
withSuffix?: boolean
withDate?: boolean
children?: React.ReactNode
}
const DisplayName: React.FC<IDisplayName> = ({ account, children, withSuffix = true, withDate = false }) => {
const DisplayName: React.FC<IDisplayName> = ({ account, children, withSuffix = true }) => {
const { displayFqn = false } = useSoapboxConfig();
const { created_at: createdAt, verified } = account;
const joinedAt = createdAt ? (
<div className='account__joined-at'>
<Icon src={require('@tabler/icons/clock.svg')} />
<RelativeTimestamp timestamp={createdAt} />
</div>
) : null;
const { verified } = account;
const displayName = (
<HStack space={1} alignItems='center' grow>
@ -39,7 +30,6 @@ const DisplayName: React.FC<IDisplayName> = ({ account, children, withSuffix = t
/>
{verified && <VerificationBadge />}
{withDate && joinedAt}
</HStack>
);

Wyświetl plik

@ -1,8 +1,8 @@
import React from 'react';
import { defineMessages, useIntl } from 'react-intl';
import { useDispatch } from 'react-redux';
import { unblockDomain } from 'soapbox/actions/domain-blocks';
import { useAppDispatch } from 'soapbox/hooks';
import { HStack, IconButton, Text } from './ui';
@ -12,11 +12,11 @@ const messages = defineMessages({
});
interface IDomain {
domain: string,
domain: string
}
const Domain: React.FC<IDomain> = ({ domain }) => {
const dispatch = useDispatch();
const dispatch = useAppDispatch();
const intl = useIntl();
// const onBlockDomain = () => {

Wyświetl plik

@ -1,415 +0,0 @@
import classNames from 'clsx';
import { supportsPassiveEvents } from 'detect-passive-events';
import React from 'react';
import { spring } from 'react-motion';
// @ts-ignore: TODO: upgrade react-overlays. v3.1 and above have TS definitions
import Overlay from 'react-overlays/lib/Overlay';
import { withRouter, RouteComponentProps } from 'react-router-dom';
import { Counter, IconButton } from 'soapbox/components/ui';
import SvgIcon from 'soapbox/components/ui/icon/svg-icon';
import Motion from 'soapbox/features/ui/util/optional-motion';
import type { Status } from 'soapbox/types/entities';
const listenerOptions = supportsPassiveEvents ? { passive: true } : false;
let id = 0;
export interface MenuItem {
action?: React.EventHandler<React.KeyboardEvent | React.MouseEvent>,
middleClick?: React.EventHandler<React.MouseEvent>,
text: string,
href?: string,
to?: string,
newTab?: boolean,
isLogout?: boolean,
icon?: string,
count?: number,
destructive?: boolean,
meta?: string,
active?: boolean,
}
export type Menu = Array<MenuItem | null>;
interface IDropdownMenu extends RouteComponentProps {
items: Menu,
onClose: () => void,
style?: React.CSSProperties,
placement?: DropdownPlacement,
arrowOffsetLeft?: string,
arrowOffsetTop?: string,
openedViaKeyboard: boolean,
}
interface IDropdownMenuState {
mounted: boolean,
}
class DropdownMenu extends React.PureComponent<IDropdownMenu, IDropdownMenuState> {
static defaultProps: Partial<IDropdownMenu> = {
style: {},
placement: 'bottom',
};
state = {
mounted: false,
};
node: HTMLDivElement | null = null;
focusedItem: HTMLAnchorElement | null = null;
handleDocumentClick = (e: Event) => {
if (this.node && !this.node.contains(e.target as Node)) {
this.props.onClose();
}
}
componentDidMount() {
document.addEventListener('click', this.handleDocumentClick, false);
document.addEventListener('keydown', this.handleKeyDown, false);
document.addEventListener('touchend', this.handleDocumentClick, listenerOptions);
if (this.focusedItem && this.props.openedViaKeyboard) {
this.focusedItem.focus({ preventScroll: true });
}
this.setState({ mounted: true });
}
componentWillUnmount() {
document.removeEventListener('click', this.handleDocumentClick);
document.removeEventListener('keydown', this.handleKeyDown);
document.removeEventListener('touchend', this.handleDocumentClick);
}
setRef: React.RefCallback<HTMLDivElement> = c => {
this.node = c;
}
setFocusRef: React.RefCallback<HTMLAnchorElement> = c => {
this.focusedItem = c;
}
handleKeyDown = (e: KeyboardEvent) => {
if (!this.node) return;
const items = Array.from(this.node.getElementsByTagName('a'));
const index = items.indexOf(document.activeElement as any);
let element = null;
switch (e.key) {
case 'ArrowDown':
element = items[index + 1] || items[0];
break;
case 'ArrowUp':
element = items[index - 1] || items[items.length - 1];
break;
case 'Tab':
if (e.shiftKey) {
element = items[index - 1] || items[items.length - 1];
} else {
element = items[index + 1] || items[0];
}
break;
case 'Home':
element = items[0];
break;
case 'End':
element = items[items.length - 1];
break;
case 'Escape':
this.props.onClose();
break;
}
if (element) {
element.focus();
e.preventDefault();
e.stopPropagation();
}
}
handleItemKeyPress: React.EventHandler<React.KeyboardEvent> = e => {
if (e.key === 'Enter' || e.key === ' ') {
this.handleClick(e);
}
}
handleClick: React.EventHandler<React.MouseEvent | React.KeyboardEvent> = e => {
const i = Number(e.currentTarget.getAttribute('data-index'));
const item = this.props.items[i];
if (!item) return;
const { action, to } = item;
this.props.onClose();
e.stopPropagation();
if (to) {
e.preventDefault();
this.props.history.push(to);
} else if (typeof action === 'function') {
e.preventDefault();
action(e);
}
}
handleMiddleClick: React.EventHandler<React.MouseEvent> = e => {
const i = Number(e.currentTarget.getAttribute('data-index'));
const item = this.props.items[i];
if (!item) return;
const { middleClick } = item;
this.props.onClose();
if (e.button === 1 && typeof middleClick === 'function') {
e.preventDefault();
middleClick(e);
}
}
handleAuxClick: React.EventHandler<React.MouseEvent> = e => {
if (e.button === 1) {
this.handleMiddleClick(e);
}
}
renderItem(option: MenuItem | null, i: number): JSX.Element {
if (option === null) {
return <li key={`sep-${i}`} className='dropdown-menu__separator' />;
}
const { text, href, to, newTab, isLogout, icon, count, destructive } = option;
return (
<li className={classNames('dropdown-menu__item truncate', { destructive })} key={`${text}-${i}`}>
<a
href={href || to || '#'}
role='button'
tabIndex={0}
ref={i === 0 ? this.setFocusRef : null}
onClick={this.handleClick}
onAuxClick={this.handleAuxClick}
onKeyPress={this.handleItemKeyPress}
data-index={i}
target={newTab ? '_blank' : undefined}
data-method={isLogout ? 'delete' : undefined}
title={text}
>
{icon && <SvgIcon src={icon} className='mr-3 rtl:ml-3 rtl:mr-0 h-5 w-5 flex-none' />}
<span className='truncate'>{text}</span>
{count ? (
<span className='ml-auto h-5 w-5 flex-none'>
<Counter count={count} />
</span>
) : null}
</a>
</li>
);
}
render() {
const { items, style, placement, arrowOffsetLeft, arrowOffsetTop } = this.props;
const { mounted } = this.state;
return (
<Motion defaultStyle={{ opacity: 0, scaleX: 1, scaleY: 1 }} style={{ opacity: spring(1, { damping: 35, stiffness: 400 }), scaleX: spring(1, { damping: 35, stiffness: 400 }), scaleY: spring(1, { damping: 35, stiffness: 400 }) }}>
{({ opacity, scaleX, scaleY }) => (
// It should not be transformed when mounting because the resulting
// size will be used to determine the coordinate of the menu by
// react-overlays
<div className={`dropdown-menu ${placement}`} style={{ ...style, opacity: opacity, transform: mounted ? `scale(${scaleX}, ${scaleY})` : undefined }} ref={this.setRef}>
<div className={`dropdown-menu__arrow ${placement}`} style={{ left: arrowOffsetLeft, top: arrowOffsetTop }} />
<ul>
{items.map((option, i) => this.renderItem(option, i))}
</ul>
</div>
)}
</Motion>
);
}
}
const RouterDropdownMenu = withRouter(DropdownMenu);
export interface IDropdown extends RouteComponentProps {
icon?: string,
src?: string,
items: Menu,
size?: number,
active?: boolean,
pressed?: boolean,
title?: string,
disabled?: boolean,
status?: Status,
isUserTouching?: () => boolean,
isModalOpen?: boolean,
onOpen?: (
id: number,
onItemClick: React.EventHandler<React.MouseEvent | React.KeyboardEvent>,
dropdownPlacement: DropdownPlacement,
keyboard: boolean,
) => void,
onClose?: (id: number) => void,
dropdownPlacement?: string,
openDropdownId?: number | null,
openedViaKeyboard?: boolean,
text?: string,
onShiftClick?: React.EventHandler<React.MouseEvent | React.KeyboardEvent>,
children?: JSX.Element,
dropdownMenuStyle?: React.CSSProperties,
}
interface IDropdownState {
id: number,
open: boolean,
}
export type DropdownPlacement = 'top' | 'bottom';
class Dropdown extends React.PureComponent<IDropdown, IDropdownState> {
static defaultProps: Partial<IDropdown> = {
title: 'Menu',
};
state = {
id: id++,
open: false,
};
target: HTMLButtonElement | null = null;
activeElement: Element | null = null;
handleClick: React.EventHandler<React.MouseEvent<HTMLButtonElement> | React.KeyboardEvent<HTMLButtonElement>> = e => {
const { onOpen, onShiftClick, openDropdownId } = this.props;
e.stopPropagation();
if (onShiftClick && e.shiftKey) {
e.preventDefault();
onShiftClick(e);
} else if (this.state.id === openDropdownId) {
this.handleClose();
} else if (onOpen) {
const { top } = e.currentTarget.getBoundingClientRect();
const placement: DropdownPlacement = top * 2 < innerHeight ? 'bottom' : 'top';
onOpen(this.state.id, this.handleItemClick, placement, e.type !== 'click');
}
}
handleClose = () => {
if (this.activeElement && this.activeElement === this.target) {
(this.activeElement as HTMLButtonElement).focus();
this.activeElement = null;
}
if (this.props.onClose) {
this.props.onClose(this.state.id);
}
}
handleMouseDown: React.EventHandler<React.MouseEvent | React.KeyboardEvent> = () => {
if (!this.state.open) {
this.activeElement = document.activeElement;
}
}
handleButtonKeyDown: React.EventHandler<React.KeyboardEvent> = (e) => {
switch (e.key) {
case ' ':
case 'Enter':
this.handleMouseDown(e);
break;
}
}
handleKeyPress: React.EventHandler<React.KeyboardEvent<HTMLButtonElement>> = (e) => {
switch (e.key) {
case ' ':
case 'Enter':
this.handleClick(e);
e.stopPropagation();
e.preventDefault();
break;
}
}
handleItemClick: React.EventHandler<React.MouseEvent> = e => {
const i = Number(e.currentTarget.getAttribute('data-index'));
const item = this.props.items[i];
if (!item) return;
const { action, to } = item;
this.handleClose();
e.preventDefault();
e.stopPropagation();
if (typeof action === 'function') {
action(e);
} else if (to) {
this.props.history?.push(to);
}
}
setTargetRef: React.RefCallback<HTMLButtonElement> = c => {
this.target = c;
}
findTarget = () => {
return this.target;
}
componentWillUnmount = () => {
if (this.state.id === this.props.openDropdownId) {
this.handleClose();
}
}
render() {
const { src = require('@tabler/icons/dots.svg'), items, title, disabled, dropdownPlacement, openDropdownId, openedViaKeyboard = false, pressed, text, children, dropdownMenuStyle } = this.props;
const open = this.state.id === openDropdownId;
return (
<>
{children ? (
React.cloneElement(children, {
disabled,
onClick: this.handleClick,
onMouseDown: this.handleMouseDown,
onKeyDown: this.handleButtonKeyDown,
onKeyPress: this.handleKeyPress,
ref: this.setTargetRef,
})
) : (
<IconButton
disabled={disabled}
className={classNames({
'text-gray-600 hover:text-gray-700 dark:hover:text-gray-500': true,
'text-gray-700 dark:text-gray-500': open,
})}
title={title}
src={src}
aria-pressed={pressed}
text={text}
onClick={this.handleClick}
onMouseDown={this.handleMouseDown}
onKeyDown={this.handleButtonKeyDown}
onKeyPress={this.handleKeyPress}
ref={this.setTargetRef}
/>
)}
<Overlay show={open} placement={dropdownPlacement} target={this.findTarget}>
<RouterDropdownMenu items={items} onClose={this.handleClose} openedViaKeyboard={openedViaKeyboard} style={dropdownMenuStyle} />
</Overlay>
</>
);
}
}
export default withRouter(Dropdown);

Wyświetl plik

@ -0,0 +1,109 @@
import clsx from 'clsx';
import React, { useEffect, useRef } from 'react';
import { useHistory } from 'react-router-dom';
import { Counter, Icon } from '../ui';
export interface MenuItem {
action?: React.EventHandler<React.KeyboardEvent | React.MouseEvent>
active?: boolean
count?: number
destructive?: boolean
href?: string
icon?: string
meta?: string
middleClick?(event: React.MouseEvent): void
target?: React.HTMLAttributeAnchorTarget
text: string
to?: string
}
interface IDropdownMenuItem {
index: number
item: MenuItem | null
onClick?(): void
}
const DropdownMenuItem = ({ index, item, onClick }: IDropdownMenuItem) => {
const history = useHistory();
const itemRef = useRef<HTMLAnchorElement>(null);
const handleClick: React.EventHandler<React.MouseEvent | React.KeyboardEvent> = (event) => {
event.stopPropagation();
if (!item) return;
if (onClick) onClick();
if (item.to) {
event.preventDefault();
history.push(item.to);
} else if (typeof item.action === 'function') {
event.preventDefault();
item.action(event);
}
};
const handleAuxClick: React.EventHandler<React.MouseEvent> = (event) => {
if (!item) return;
if (onClick) onClick();
if (event.button === 1 && item.middleClick) {
item.middleClick(event);
}
};
const handleItemKeyPress: React.EventHandler<React.KeyboardEvent> = (event) => {
if (event.key === 'Enter' || event.key === ' ') {
handleClick(event);
}
};
useEffect(() => {
const firstItem = index === 0;
if (itemRef.current && firstItem) {
itemRef.current.focus({ preventScroll: true });
}
}, [itemRef.current, index]);
if (item === null) {
return <li className='my-1 mx-2 h-[2px] bg-gray-100 dark:bg-gray-800' />;
}
return (
<li className='truncate focus-visible:ring-2 focus-visible:ring-primary-500'>
<a
href={item.href || item.to || '#'}
role='button'
tabIndex={0}
ref={itemRef}
data-index={index}
onClick={handleClick}
onAuxClick={handleAuxClick}
onKeyPress={handleItemKeyPress}
target={item.target}
title={item.text}
className={
clsx({
'flex px-4 py-2.5 text-sm text-gray-700 dark:text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-800 focus:outline-none cursor-pointer': true,
'text-danger-600 dark:text-danger-400': item.destructive,
})
}
>
{item.icon && <Icon src={item.icon} className='mr-3 h-5 w-5 flex-none rtl:ml-3 rtl:mr-0' />}
<span className='truncate'>{item.text}</span>
{item.count ? (
<span className='ml-auto h-5 w-5 flex-none'>
<Counter count={item.count} />
</span>
) : null}
</a>
</li>
);
};
export default DropdownMenuItem;

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