From 155424e52f2d382ccaf4560b2d62aba347a8992b Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 3 Feb 2023 20:52:07 +0100 Subject: [Glitch] Run eslint --fix I don't like it changing files this way, but it's basically what c49213f0ea311daba590db1d7a14a641cbd9fe93 and a few others did. --- .../flavours/glitch/features/subscribed_languages_modal/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/javascript/flavours/glitch/features/subscribed_languages_modal') diff --git a/app/javascript/flavours/glitch/features/subscribed_languages_modal/index.js b/app/javascript/flavours/glitch/features/subscribed_languages_modal/index.js index fa69d82a4..35083503c 100644 --- a/app/javascript/flavours/glitch/features/subscribed_languages_modal/index.js +++ b/app/javascript/flavours/glitch/features/subscribed_languages_modal/index.js @@ -72,7 +72,7 @@ class SubscribedLanguagesModal extends ImmutablePureComponent { handleSubmit = () => { this.props.onSubmit(this.state.selectedLanguages.toArray()); this.props.onClose(); - } + }; renderItem (value) { const language = this.props.languages.find(language => language[0] === value); -- cgit From 81ef21a0c802f1d905f37a2a818544a8b400793c Mon Sep 17 00:00:00 2001 From: Renaud Chaput Date: Sat, 25 Feb 2023 14:34:32 +0100 Subject: [Glitch] Rename JSX files with proper `.jsx` extension Port 44a7d87cb1f5df953b6c14c16c59e2e4ead1bcb9 to glitch-soc Signed-off-by: Claire --- .../flavours/glitch/components/account.js | 186 ----- .../flavours/glitch/components/account.jsx | 186 +++++ .../flavours/glitch/components/admin/Counter.js | 117 --- .../flavours/glitch/components/admin/Counter.jsx | 117 +++ .../flavours/glitch/components/admin/Dimension.js | 93 --- .../flavours/glitch/components/admin/Dimension.jsx | 93 +++ .../components/admin/ReportReasonSelector.js | 159 ---- .../components/admin/ReportReasonSelector.jsx | 159 ++++ .../flavours/glitch/components/admin/Retention.js | 151 ---- .../flavours/glitch/components/admin/Retention.jsx | 151 ++++ .../flavours/glitch/components/admin/Trends.js | 73 -- .../flavours/glitch/components/admin/Trends.jsx | 73 ++ .../flavours/glitch/components/animated_number.js | 76 -- .../flavours/glitch/components/animated_number.jsx | 76 ++ .../flavours/glitch/components/attachment_list.js | 48 -- .../flavours/glitch/components/attachment_list.jsx | 48 ++ .../glitch/components/autosuggest_emoji.js | 42 -- .../glitch/components/autosuggest_emoji.jsx | 42 ++ .../glitch/components/autosuggest_hashtag.js | 42 -- .../glitch/components/autosuggest_hashtag.jsx | 42 ++ .../glitch/components/autosuggest_input.js | 227 ------ .../glitch/components/autosuggest_input.jsx | 227 ++++++ .../glitch/components/autosuggest_textarea.js | 235 ------ .../glitch/components/autosuggest_textarea.jsx | 235 ++++++ .../flavours/glitch/components/avatar.js | 79 -- .../flavours/glitch/components/avatar.jsx | 79 ++ .../flavours/glitch/components/avatar_composite.js | 110 --- .../glitch/components/avatar_composite.jsx | 110 +++ .../flavours/glitch/components/avatar_overlay.js | 37 - .../flavours/glitch/components/avatar_overlay.jsx | 37 + .../flavours/glitch/components/blurhash.js | 65 -- .../flavours/glitch/components/blurhash.jsx | 65 ++ .../flavours/glitch/components/button.js | 52 -- .../flavours/glitch/components/button.jsx | 52 ++ app/javascript/flavours/glitch/components/check.js | 9 - .../flavours/glitch/components/check.jsx | 9 + .../flavours/glitch/components/column.js | 64 -- .../flavours/glitch/components/column.jsx | 64 ++ .../glitch/components/column_back_button.js | 60 -- .../glitch/components/column_back_button.jsx | 60 ++ .../glitch/components/column_back_button_slim.js | 37 - .../glitch/components/column_back_button_slim.jsx | 37 + .../flavours/glitch/components/column_header.js | 220 ------ .../flavours/glitch/components/column_header.jsx | 220 ++++++ .../flavours/glitch/components/common_counter.js | 62 -- .../flavours/glitch/components/common_counter.jsx | 62 ++ .../glitch/components/dismissable_banner.js | 51 -- .../glitch/components/dismissable_banner.jsx | 51 ++ .../flavours/glitch/components/display_name.js | 102 --- .../flavours/glitch/components/display_name.jsx | 102 +++ .../flavours/glitch/components/domain.js | 42 -- .../flavours/glitch/components/domain.jsx | 42 ++ .../flavours/glitch/components/dropdown_menu.js | 335 --------- .../flavours/glitch/components/dropdown_menu.jsx | 335 +++++++++ .../glitch/components/edited_timestamp/index.js | 70 -- .../glitch/components/edited_timestamp/index.jsx | 70 ++ .../flavours/glitch/components/error_boundary.js | 134 ---- .../flavours/glitch/components/error_boundary.jsx | 134 ++++ app/javascript/flavours/glitch/components/gifv.js | 73 -- app/javascript/flavours/glitch/components/gifv.jsx | 73 ++ .../flavours/glitch/components/hashtag.js | 115 --- .../flavours/glitch/components/hashtag.jsx | 115 +++ app/javascript/flavours/glitch/components/icon.js | 21 - app/javascript/flavours/glitch/components/icon.jsx | 21 + .../flavours/glitch/components/icon_button.js | 177 ----- .../flavours/glitch/components/icon_button.jsx | 177 +++++ .../flavours/glitch/components/icon_with_badge.js | 22 - .../flavours/glitch/components/icon_with_badge.jsx | 22 + app/javascript/flavours/glitch/components/image.js | 33 - .../flavours/glitch/components/image.jsx | 33 + .../flavours/glitch/components/inline_account.js | 34 - .../flavours/glitch/components/inline_account.jsx | 34 + .../components/intersection_observer_article.js | 131 ---- .../components/intersection_observer_article.jsx | 131 ++++ app/javascript/flavours/glitch/components/link.js | 97 --- app/javascript/flavours/glitch/components/link.jsx | 97 +++ .../flavours/glitch/components/load_gap.js | 34 - .../flavours/glitch/components/load_gap.jsx | 34 + .../flavours/glitch/components/load_more.js | 27 - .../flavours/glitch/components/load_more.jsx | 27 + .../flavours/glitch/components/load_pending.js | 22 - .../flavours/glitch/components/load_pending.jsx | 22 + .../glitch/components/loading_indicator.js | 32 - .../glitch/components/loading_indicator.jsx | 32 + app/javascript/flavours/glitch/components/logo.js | 10 - app/javascript/flavours/glitch/components/logo.jsx | 10 + .../glitch/components/media_attachments.js | 119 --- .../glitch/components/media_attachments.jsx | 119 +++ .../flavours/glitch/components/media_gallery.js | 404 ---------- .../flavours/glitch/components/media_gallery.jsx | 404 ++++++++++ .../glitch/components/missing_indicator.js | 29 - .../glitch/components/missing_indicator.jsx | 29 + .../flavours/glitch/components/modal_root.js | 161 ---- .../flavours/glitch/components/modal_root.jsx | 161 ++++ .../glitch/components/navigation_portal.js | 35 - .../glitch/components/navigation_portal.jsx | 35 + .../glitch/components/not_signed_in_indicator.js | 12 - .../glitch/components/not_signed_in_indicator.jsx | 12 + .../components/notification_purge_buttons.js | 59 -- .../components/notification_purge_buttons.jsx | 59 ++ .../flavours/glitch/components/permalink.js | 51 -- .../flavours/glitch/components/permalink.jsx | 51 ++ .../components/picture_in_picture_placeholder.js | 69 -- .../components/picture_in_picture_placeholder.jsx | 69 ++ app/javascript/flavours/glitch/components/poll.js | 233 ------ app/javascript/flavours/glitch/components/poll.jsx | 233 ++++++ .../flavours/glitch/components/radio_button.js | 35 - .../flavours/glitch/components/radio_button.jsx | 35 + .../glitch/components/regeneration_indicator.js | 18 - .../glitch/components/regeneration_indicator.jsx | 18 + .../glitch/components/relative_timestamp.js | 199 ----- .../glitch/components/relative_timestamp.jsx | 199 +++++ .../flavours/glitch/components/scrollable_list.js | 354 --------- .../flavours/glitch/components/scrollable_list.jsx | 354 +++++++++ .../flavours/glitch/components/server_banner.js | 93 --- .../flavours/glitch/components/server_banner.jsx | 93 +++ .../flavours/glitch/components/setting_text.js | 34 - .../flavours/glitch/components/setting_text.jsx | 34 + .../flavours/glitch/components/short_number.js | 117 --- .../flavours/glitch/components/short_number.jsx | 117 +++ .../flavours/glitch/components/skeleton.js | 11 - .../flavours/glitch/components/skeleton.jsx | 11 + .../flavours/glitch/components/spoilers.js | 52 -- .../flavours/glitch/components/spoilers.jsx | 52 ++ .../flavours/glitch/components/status.js | 829 --------------------- .../flavours/glitch/components/status.jsx | 829 +++++++++++++++++++++ .../glitch/components/status_action_bar.js | 341 --------- .../glitch/components/status_action_bar.jsx | 341 +++++++++ .../flavours/glitch/components/status_content.js | 461 ------------ .../flavours/glitch/components/status_content.jsx | 461 ++++++++++++ .../flavours/glitch/components/status_header.js | 71 -- .../flavours/glitch/components/status_header.jsx | 71 ++ .../flavours/glitch/components/status_icons.js | 145 ---- .../flavours/glitch/components/status_icons.jsx | 145 ++++ .../flavours/glitch/components/status_list.js | 131 ---- .../flavours/glitch/components/status_list.jsx | 131 ++++ .../flavours/glitch/components/status_prepend.js | 144 ---- .../flavours/glitch/components/status_prepend.jsx | 144 ++++ .../glitch/components/status_visibility_icon.js | 51 -- .../glitch/components/status_visibility_icon.jsx | 51 ++ .../flavours/glitch/components/timeline_hint.js | 18 - .../flavours/glitch/components/timeline_hint.jsx | 18 + .../glitch/containers/account_container.js | 72 -- .../glitch/containers/account_container.jsx | 72 ++ .../flavours/glitch/containers/admin_component.js | 26 - .../flavours/glitch/containers/admin_component.jsx | 26 + .../glitch/containers/compose_container.js | 41 - .../glitch/containers/compose_container.jsx | 41 + .../flavours/glitch/containers/domain_container.js | 33 - .../glitch/containers/domain_container.jsx | 33 + .../flavours/glitch/containers/mastodon.js | 102 --- .../flavours/glitch/containers/mastodon.jsx | 102 +++ .../flavours/glitch/containers/media_container.js | 121 --- .../flavours/glitch/containers/media_container.jsx | 121 +++ .../flavours/glitch/features/about/index.js | 220 ------ .../flavours/glitch/features/about/index.jsx | 220 ++++++ .../features/account/components/account_note.js | 104 --- .../features/account/components/account_note.jsx | 104 +++ .../features/account/components/action_bar.js | 85 --- .../features/account/components/action_bar.jsx | 85 +++ .../features/account/components/featured_tags.js | 53 -- .../features/account/components/featured_tags.jsx | 53 ++ .../account/components/follow_request_note.js | 37 - .../account/components/follow_request_note.jsx | 37 + .../glitch/features/account/components/header.js | 405 ---------- .../glitch/features/account/components/header.jsx | 405 ++++++++++ .../account/components/profile_column_header.js | 33 - .../account/components/profile_column_header.jsx | 33 + .../flavours/glitch/features/account/navigation.js | 52 -- .../glitch/features/account/navigation.jsx | 52 ++ .../account_gallery/components/media_item.js | 146 ---- .../account_gallery/components/media_item.jsx | 146 ++++ .../glitch/features/account_gallery/index.js | 225 ------ .../glitch/features/account_gallery/index.jsx | 225 ++++++ .../features/account_timeline/components/header.js | 158 ---- .../account_timeline/components/header.jsx | 158 ++++ .../components/limited_account_hint.js | 36 - .../components/limited_account_hint.jsx | 36 + .../account_timeline/components/moved_note.js | 51 -- .../account_timeline/components/moved_note.jsx | 51 ++ .../containers/header_container.js | 173 ----- .../containers/header_container.jsx | 173 +++++ .../glitch/features/account_timeline/index.js | 209 ------ .../glitch/features/account_timeline/index.jsx | 209 ++++++ .../flavours/glitch/features/audio/index.js | 575 -------------- .../flavours/glitch/features/audio/index.jsx | 575 ++++++++++++++ .../flavours/glitch/features/blocks/index.js | 79 -- .../flavours/glitch/features/blocks/index.jsx | 79 ++ .../glitch/features/bookmarked_statuses/index.js | 108 --- .../glitch/features/bookmarked_statuses/index.jsx | 108 +++ .../features/closed_registrations_modal/index.js | 75 -- .../features/closed_registrations_modal/index.jsx | 75 ++ .../components/column_settings.js | 41 - .../components/column_settings.jsx | 41 + .../glitch/features/community_timeline/index.js | 164 ---- .../glitch/features/community_timeline/index.jsx | 164 ++++ .../features/compose/components/action_bar.js | 68 -- .../features/compose/components/action_bar.jsx | 68 ++ .../compose/components/autosuggest_account.js | 24 - .../compose/components/autosuggest_account.jsx | 24 + .../compose/components/character_counter.js | 25 - .../compose/components/character_counter.jsx | 25 + .../features/compose/components/compose_form.js | 391 ---------- .../features/compose/components/compose_form.jsx | 391 ++++++++++ .../glitch/features/compose/components/dropdown.js | 243 ------ .../features/compose/components/dropdown.jsx | 243 ++++++ .../features/compose/components/dropdown_menu.js | 199 ----- .../features/compose/components/dropdown_menu.jsx | 199 +++++ .../compose/components/emoji_picker_dropdown.js | 413 ---------- .../compose/components/emoji_picker_dropdown.jsx | 413 ++++++++++ .../glitch/features/compose/components/header.js | 136 ---- .../glitch/features/compose/components/header.jsx | 136 ++++ .../compose/components/language_dropdown.js | 327 -------- .../compose/components/language_dropdown.jsx | 327 ++++++++ .../features/compose/components/navigation_bar.js | 46 -- .../features/compose/components/navigation_bar.jsx | 46 ++ .../glitch/features/compose/components/options.js | 317 -------- .../glitch/features/compose/components/options.jsx | 317 ++++++++ .../features/compose/components/poll_form.js | 170 ----- .../features/compose/components/poll_form.jsx | 170 +++++ .../compose/components/privacy_dropdown.js | 88 --- .../compose/components/privacy_dropdown.jsx | 88 +++ .../features/compose/components/publisher.js | 99 --- .../features/compose/components/publisher.jsx | 99 +++ .../features/compose/components/reply_indicator.js | 82 -- .../compose/components/reply_indicator.jsx | 82 ++ .../glitch/features/compose/components/search.js | 168 ----- .../glitch/features/compose/components/search.jsx | 168 +++++ .../features/compose/components/search_results.js | 141 ---- .../features/compose/components/search_results.jsx | 141 ++++ .../compose/components/text_icon_button.js | 38 - .../compose/components/text_icon_button.jsx | 38 + .../features/compose/components/textarea_icons.js | 60 -- .../features/compose/components/textarea_icons.jsx | 60 ++ .../glitch/features/compose/components/upload.js | 67 -- .../glitch/features/compose/components/upload.jsx | 67 ++ .../features/compose/components/upload_form.js | 34 - .../features/compose/components/upload_form.jsx | 34 + .../features/compose/components/upload_progress.js | 52 -- .../compose/components/upload_progress.jsx | 52 ++ .../glitch/features/compose/components/warning.js | 26 - .../glitch/features/compose/components/warning.jsx | 26 + .../containers/sensitive_button_container.js | 75 -- .../containers/sensitive_button_container.jsx | 75 ++ .../compose/containers/warning_container.js | 68 -- .../compose/containers/warning_container.jsx | 68 ++ .../flavours/glitch/features/compose/index.js | 116 --- .../flavours/glitch/features/compose/index.jsx | 116 +++ .../direct_timeline/components/column_settings.js | 42 -- .../direct_timeline/components/column_settings.jsx | 42 ++ .../direct_timeline/components/conversation.js | 232 ------ .../direct_timeline/components/conversation.jsx | 232 ++++++ .../components/conversations_list.js | 75 -- .../components/conversations_list.jsx | 75 ++ .../glitch/features/direct_timeline/index.js | 156 ---- .../glitch/features/direct_timeline/index.jsx | 156 ++++ .../features/directory/components/account_card.js | 248 ------ .../features/directory/components/account_card.jsx | 248 ++++++ .../flavours/glitch/features/directory/index.js | 178 ----- .../flavours/glitch/features/directory/index.jsx | 178 +++++ .../glitch/features/domain_blocks/index.js | 83 --- .../glitch/features/domain_blocks/index.jsx | 83 +++ .../glitch/features/explore/components/story.js | 51 -- .../glitch/features/explore/components/story.jsx | 51 ++ .../flavours/glitch/features/explore/index.js | 107 --- .../flavours/glitch/features/explore/index.jsx | 107 +++ .../flavours/glitch/features/explore/links.js | 70 -- .../flavours/glitch/features/explore/links.jsx | 70 ++ .../flavours/glitch/features/explore/results.js | 126 ---- .../flavours/glitch/features/explore/results.jsx | 126 ++++ .../flavours/glitch/features/explore/statuses.js | 64 -- .../flavours/glitch/features/explore/statuses.jsx | 64 ++ .../glitch/features/explore/suggestions.js | 56 -- .../glitch/features/explore/suggestions.jsx | 56 ++ .../flavours/glitch/features/explore/tags.js | 62 -- .../flavours/glitch/features/explore/tags.jsx | 62 ++ .../glitch/features/favourited_statuses/index.js | 108 --- .../glitch/features/favourited_statuses/index.jsx | 108 +++ .../flavours/glitch/features/favourites/index.js | 103 --- .../flavours/glitch/features/favourites/index.jsx | 103 +++ .../glitch/features/filters/added_to_filter.js | 102 --- .../glitch/features/filters/added_to_filter.jsx | 102 +++ .../glitch/features/filters/select_filter.js | 192 ----- .../glitch/features/filters/select_filter.jsx | 192 +++++ .../follow_recommendations/components/account.js | 85 --- .../follow_recommendations/components/account.jsx | 85 +++ .../features/follow_recommendations/index.js | 116 --- .../features/follow_recommendations/index.jsx | 116 +++ .../components/account_authorize.js | 49 -- .../components/account_authorize.jsx | 49 ++ .../glitch/features/follow_requests/index.js | 92 --- .../glitch/features/follow_requests/index.jsx | 92 +++ .../glitch/features/followed_tags/index.js | 89 --- .../glitch/features/followed_tags/index.jsx | 89 +++ .../flavours/glitch/features/followers/index.js | 174 ----- .../flavours/glitch/features/followers/index.jsx | 174 +++++ .../flavours/glitch/features/following/index.js | 174 ----- .../flavours/glitch/features/following/index.jsx | 174 +++++ .../glitch/features/generic_not_found/index.js | 11 - .../glitch/features/generic_not_found/index.jsx | 11 + .../getting_started/components/announcements.js | 449 ----------- .../getting_started/components/announcements.jsx | 449 +++++++++++ .../features/getting_started/components/trends.js | 51 -- .../features/getting_started/components/trends.jsx | 51 ++ .../glitch/features/getting_started/index.js | 204 ----- .../glitch/features/getting_started/index.jsx | 204 +++++ .../glitch/features/getting_started_misc/index.js | 69 -- .../glitch/features/getting_started_misc/index.jsx | 69 ++ .../hashtag_timeline/components/column_settings.js | 133 ---- .../components/column_settings.jsx | 133 ++++ .../glitch/features/hashtag_timeline/index.js | 237 ------ .../glitch/features/hashtag_timeline/index.jsx | 237 ++++++ .../home_timeline/components/column_settings.js | 50 -- .../home_timeline/components/column_settings.jsx | 50 ++ .../glitch/features/home_timeline/index.js | 178 ----- .../glitch/features/home_timeline/index.jsx | 178 +++++ .../glitch/features/interaction_modal/index.js | 161 ---- .../glitch/features/interaction_modal/index.jsx | 161 ++++ .../glitch/features/keyboard_shortcuts/index.js | 149 ---- .../glitch/features/keyboard_shortcuts/index.jsx | 149 ++++ .../features/list_adder/components/account.js | 43 -- .../features/list_adder/components/account.jsx | 43 ++ .../glitch/features/list_adder/components/list.js | 69 -- .../glitch/features/list_adder/components/list.jsx | 69 ++ .../flavours/glitch/features/list_adder/index.js | 73 -- .../flavours/glitch/features/list_adder/index.jsx | 73 ++ .../features/list_editor/components/account.js | 56 -- .../features/list_editor/components/account.jsx | 56 ++ .../list_editor/components/edit_list_form.js | 70 -- .../list_editor/components/edit_list_form.jsx | 70 ++ .../features/list_editor/components/search.js | 62 -- .../features/list_editor/components/search.jsx | 62 ++ .../flavours/glitch/features/list_editor/index.js | 79 -- .../flavours/glitch/features/list_editor/index.jsx | 79 ++ .../glitch/features/list_timeline/index.js | 224 ------ .../glitch/features/list_timeline/index.jsx | 224 ++++++ .../features/lists/components/new_list_form.js | 78 -- .../features/lists/components/new_list_form.jsx | 78 ++ .../flavours/glitch/features/lists/index.js | 89 --- .../flavours/glitch/features/lists/index.jsx | 89 +++ .../glitch/features/local_settings/index.js | 65 -- .../glitch/features/local_settings/index.jsx | 65 ++ .../features/local_settings/navigation/index.js | 92 --- .../features/local_settings/navigation/index.jsx | 92 +++ .../local_settings/navigation/item/index.js | 74 -- .../local_settings/navigation/item/index.jsx | 74 ++ .../local_settings/page/deprecated_item/index.js | 83 --- .../local_settings/page/deprecated_item/index.jsx | 83 +++ .../glitch/features/local_settings/page/index.js | 515 ------------- .../glitch/features/local_settings/page/index.jsx | 515 +++++++++++++ .../features/local_settings/page/item/index.js | 119 --- .../features/local_settings/page/item/index.jsx | 119 +++ .../flavours/glitch/features/mutes/index.js | 84 --- .../flavours/glitch/features/mutes/index.jsx | 84 +++ .../notifications/components/admin_report.js | 112 --- .../notifications/components/admin_report.jsx | 112 +++ .../notifications/components/admin_signup.js | 101 --- .../notifications/components/admin_signup.jsx | 101 +++ .../components/clear_column_button.js | 18 - .../components/clear_column_button.jsx | 18 + .../notifications/components/column_settings.js | 203 ----- .../notifications/components/column_settings.jsx | 203 +++++ .../notifications/components/filter_bar.js | 110 --- .../notifications/components/filter_bar.jsx | 110 +++ .../features/notifications/components/follow.js | 101 --- .../features/notifications/components/follow.jsx | 101 +++ .../notifications/components/follow_request.js | 132 ---- .../notifications/components/follow_request.jsx | 132 ++++ .../components/grant_permission_button.js | 19 - .../components/grant_permission_button.jsx | 19 + .../notifications/components/notification.js | 234 ------ .../notifications/components/notification.jsx | 234 ++++++ .../components/notifications_permission_banner.js | 48 -- .../components/notifications_permission_banner.jsx | 48 ++ .../features/notifications/components/overlay.js | 58 -- .../features/notifications/components/overlay.jsx | 58 ++ .../notifications/components/pill_bar_button.js | 41 - .../notifications/components/pill_bar_button.jsx | 41 + .../features/notifications/components/report.js | 62 -- .../features/notifications/components/report.jsx | 62 ++ .../notifications/components/setting_toggle.js | 36 - .../notifications/components/setting_toggle.jsx | 36 + .../glitch/features/notifications/index.js | 382 ---------- .../glitch/features/notifications/index.jsx | 382 ++++++++++ .../picture_in_picture/components/footer.js | 217 ------ .../picture_in_picture/components/footer.jsx | 217 ++++++ .../picture_in_picture/components/header.js | 47 -- .../picture_in_picture/components/header.jsx | 47 ++ .../glitch/features/picture_in_picture/index.js | 88 --- .../glitch/features/picture_in_picture/index.jsx | 88 +++ .../features/pinned_accounts_editor/index.js | 78 -- .../features/pinned_accounts_editor/index.jsx | 78 ++ .../glitch/features/pinned_statuses/index.js | 65 -- .../glitch/features/pinned_statuses/index.jsx | 65 ++ .../glitch/features/privacy_policy/index.js | 61 -- .../glitch/features/privacy_policy/index.jsx | 61 ++ .../public_timeline/components/column_settings.js | 42 -- .../public_timeline/components/column_settings.jsx | 42 ++ .../glitch/features/public_timeline/index.js | 168 ----- .../glitch/features/public_timeline/index.jsx | 168 +++++ .../flavours/glitch/features/reblogs/index.js | 104 --- .../flavours/glitch/features/reblogs/index.jsx | 104 +++ .../flavours/glitch/features/report/category.js | 104 --- .../flavours/glitch/features/report/category.jsx | 104 +++ .../flavours/glitch/features/report/comment.js | 83 --- .../flavours/glitch/features/report/comment.jsx | 83 +++ .../glitch/features/report/components/option.js | 60 -- .../glitch/features/report/components/option.jsx | 60 ++ .../features/report/components/status_check_box.js | 60 -- .../report/components/status_check_box.jsx | 60 ++ .../flavours/glitch/features/report/rules.js | 64 -- .../flavours/glitch/features/report/rules.jsx | 64 ++ .../flavours/glitch/features/report/statuses.js | 61 -- .../flavours/glitch/features/report/statuses.jsx | 61 ++ .../flavours/glitch/features/report/thanks.js | 84 --- .../flavours/glitch/features/report/thanks.jsx | 84 +++ .../glitch/features/standalone/compose/index.js | 20 - .../glitch/features/standalone/compose/index.jsx | 20 + .../features/status/components/action_bar.js | 230 ------ .../features/status/components/action_bar.jsx | 230 ++++++ .../glitch/features/status/components/card.js | 281 ------- .../glitch/features/status/components/card.jsx | 281 +++++++ .../features/status/components/detailed_status.js | 335 --------- .../features/status/components/detailed_status.jsx | 335 +++++++++ .../flavours/glitch/features/status/index.js | 726 ------------------ .../flavours/glitch/features/status/index.jsx | 726 ++++++++++++++++++ .../features/subscribed_languages_modal/index.js | 125 ---- .../features/subscribed_languages_modal/index.jsx | 125 ++++ .../glitch/features/ui/components/actions_modal.js | 91 --- .../features/ui/components/actions_modal.jsx | 91 +++ .../glitch/features/ui/components/audio_modal.js | 58 -- .../glitch/features/ui/components/audio_modal.jsx | 58 ++ .../glitch/features/ui/components/block_modal.js | 103 --- .../glitch/features/ui/components/block_modal.jsx | 103 +++ .../glitch/features/ui/components/boost_modal.js | 139 ---- .../glitch/features/ui/components/boost_modal.jsx | 139 ++++ .../glitch/features/ui/components/bundle.js | 107 --- .../glitch/features/ui/components/bundle.jsx | 107 +++ .../features/ui/components/bundle_column_error.js | 162 ---- .../features/ui/components/bundle_column_error.jsx | 162 ++++ .../features/ui/components/bundle_modal_error.js | 53 -- .../features/ui/components/bundle_modal_error.jsx | 53 ++ .../glitch/features/ui/components/column.js | 75 -- .../glitch/features/ui/components/column.jsx | 75 ++ .../glitch/features/ui/components/column_header.js | 38 - .../features/ui/components/column_header.jsx | 38 + .../glitch/features/ui/components/column_link.js | 55 -- .../glitch/features/ui/components/column_link.jsx | 55 ++ .../features/ui/components/column_loading.js | 32 - .../features/ui/components/column_loading.jsx | 32 + .../features/ui/components/column_subheading.js | 16 - .../features/ui/components/column_subheading.jsx | 16 + .../glitch/features/ui/components/columns_area.js | 183 ----- .../glitch/features/ui/components/columns_area.jsx | 183 +++++ .../ui/components/compare_history_modal.js | 99 --- .../ui/components/compare_history_modal.jsx | 99 +++ .../glitch/features/ui/components/compose_panel.js | 58 -- .../features/ui/components/compose_panel.jsx | 58 ++ .../features/ui/components/confirmation_modal.js | 88 --- .../features/ui/components/confirmation_modal.jsx | 88 +++ .../ui/components/deprecated_settings_modal.js | 86 --- .../ui/components/deprecated_settings_modal.jsx | 86 +++ .../ui/components/disabled_account_banner.js | 92 --- .../ui/components/disabled_account_banner.jsx | 92 +++ .../glitch/features/ui/components/doodle_modal.js | 614 --------------- .../glitch/features/ui/components/doodle_modal.jsx | 614 +++++++++++++++ .../features/ui/components/drawer_loading.js | 11 - .../features/ui/components/drawer_loading.jsx | 11 + .../glitch/features/ui/components/embed_modal.js | 97 --- .../glitch/features/ui/components/embed_modal.jsx | 97 +++ .../features/ui/components/favourite_modal.js | 101 --- .../features/ui/components/favourite_modal.jsx | 101 +++ .../glitch/features/ui/components/filter_modal.js | 134 ---- .../glitch/features/ui/components/filter_modal.jsx | 134 ++++ .../features/ui/components/focal_point_modal.js | 418 ----------- .../features/ui/components/focal_point_modal.jsx | 418 +++++++++++ .../ui/components/follow_requests_column_link.js | 51 -- .../ui/components/follow_requests_column_link.jsx | 51 ++ .../glitch/features/ui/components/header.js | 88 --- .../glitch/features/ui/components/header.jsx | 88 +++ .../glitch/features/ui/components/image_loader.js | 168 ----- .../glitch/features/ui/components/image_loader.jsx | 168 +++++ .../glitch/features/ui/components/image_modal.js | 59 -- .../glitch/features/ui/components/image_modal.jsx | 59 ++ .../glitch/features/ui/components/link_footer.js | 102 --- .../glitch/features/ui/components/link_footer.jsx | 102 +++ .../glitch/features/ui/components/list_panel.js | 55 -- .../glitch/features/ui/components/list_panel.jsx | 55 ++ .../glitch/features/ui/components/media_modal.js | 252 ------- .../glitch/features/ui/components/media_modal.jsx | 252 +++++++ .../glitch/features/ui/components/modal_loading.js | 20 - .../features/ui/components/modal_loading.jsx | 20 + .../glitch/features/ui/components/modal_root.js | 144 ---- .../glitch/features/ui/components/modal_root.jsx | 144 ++++ .../glitch/features/ui/components/mute_modal.js | 140 ---- .../glitch/features/ui/components/mute_modal.jsx | 140 ++++ .../features/ui/components/navigation_panel.js | 104 --- .../features/ui/components/navigation_panel.jsx | 104 +++ .../features/ui/components/onboarding_modal.js | 321 -------- .../features/ui/components/onboarding_modal.jsx | 321 ++++++++ .../glitch/features/ui/components/report_modal.js | 221 ------ .../glitch/features/ui/components/report_modal.jsx | 221 ++++++ .../features/ui/components/sign_in_banner.js | 40 - .../features/ui/components/sign_in_banner.jsx | 40 + .../glitch/features/ui/components/upload_area.js | 52 -- .../glitch/features/ui/components/upload_area.jsx | 52 ++ .../glitch/features/ui/components/video_modal.js | 66 -- .../glitch/features/ui/components/video_modal.jsx | 66 ++ .../features/ui/components/zoomable_image.js | 450 ----------- .../features/ui/components/zoomable_image.jsx | 450 +++++++++++ .../flavours/glitch/features/ui/index.js | 684 ----------------- .../flavours/glitch/features/ui/index.jsx | 684 +++++++++++++++++ .../features/ui/util/react_router_helpers.js | 101 --- .../features/ui/util/react_router_helpers.jsx | 101 +++ .../glitch/features/ui/util/reduced_motion.js | 44 -- .../glitch/features/ui/util/reduced_motion.jsx | 44 ++ .../flavours/glitch/features/video/index.js | 673 ----------------- .../flavours/glitch/features/video/index.jsx | 673 +++++++++++++++++ app/javascript/flavours/glitch/main.js | 46 -- app/javascript/flavours/glitch/main.jsx | 46 ++ app/javascript/flavours/glitch/packs/admin.js | 24 - app/javascript/flavours/glitch/packs/admin.jsx | 24 + app/javascript/flavours/glitch/packs/public.js | 224 ------ app/javascript/flavours/glitch/packs/public.jsx | 224 ++++++ app/javascript/flavours/glitch/packs/share.js | 23 - app/javascript/flavours/glitch/packs/share.jsx | 23 + app/javascript/flavours/glitch/theme.yml | 12 +- app/javascript/flavours/glitch/utils/icons.js | 15 - app/javascript/flavours/glitch/utils/icons.jsx | 15 + 529 files changed, 33223 insertions(+), 33223 deletions(-) delete mode 100644 app/javascript/flavours/glitch/components/account.js create mode 100644 app/javascript/flavours/glitch/components/account.jsx delete mode 100644 app/javascript/flavours/glitch/components/admin/Counter.js create mode 100644 app/javascript/flavours/glitch/components/admin/Counter.jsx delete mode 100644 app/javascript/flavours/glitch/components/admin/Dimension.js create mode 100644 app/javascript/flavours/glitch/components/admin/Dimension.jsx delete mode 100644 app/javascript/flavours/glitch/components/admin/ReportReasonSelector.js create mode 100644 app/javascript/flavours/glitch/components/admin/ReportReasonSelector.jsx delete mode 100644 app/javascript/flavours/glitch/components/admin/Retention.js create mode 100644 app/javascript/flavours/glitch/components/admin/Retention.jsx delete mode 100644 app/javascript/flavours/glitch/components/admin/Trends.js create mode 100644 app/javascript/flavours/glitch/components/admin/Trends.jsx delete mode 100644 app/javascript/flavours/glitch/components/animated_number.js create mode 100644 app/javascript/flavours/glitch/components/animated_number.jsx delete mode 100644 app/javascript/flavours/glitch/components/attachment_list.js create mode 100644 app/javascript/flavours/glitch/components/attachment_list.jsx delete mode 100644 app/javascript/flavours/glitch/components/autosuggest_emoji.js create mode 100644 app/javascript/flavours/glitch/components/autosuggest_emoji.jsx delete mode 100644 app/javascript/flavours/glitch/components/autosuggest_hashtag.js create mode 100644 app/javascript/flavours/glitch/components/autosuggest_hashtag.jsx delete mode 100644 app/javascript/flavours/glitch/components/autosuggest_input.js create mode 100644 app/javascript/flavours/glitch/components/autosuggest_input.jsx delete mode 100644 app/javascript/flavours/glitch/components/autosuggest_textarea.js create mode 100644 app/javascript/flavours/glitch/components/autosuggest_textarea.jsx delete mode 100644 app/javascript/flavours/glitch/components/avatar.js create mode 100644 app/javascript/flavours/glitch/components/avatar.jsx delete mode 100644 app/javascript/flavours/glitch/components/avatar_composite.js create mode 100644 app/javascript/flavours/glitch/components/avatar_composite.jsx delete mode 100644 app/javascript/flavours/glitch/components/avatar_overlay.js create mode 100644 app/javascript/flavours/glitch/components/avatar_overlay.jsx delete mode 100644 app/javascript/flavours/glitch/components/blurhash.js create mode 100644 app/javascript/flavours/glitch/components/blurhash.jsx delete mode 100644 app/javascript/flavours/glitch/components/button.js create mode 100644 app/javascript/flavours/glitch/components/button.jsx delete mode 100644 app/javascript/flavours/glitch/components/check.js create mode 100644 app/javascript/flavours/glitch/components/check.jsx delete mode 100644 app/javascript/flavours/glitch/components/column.js create mode 100644 app/javascript/flavours/glitch/components/column.jsx delete mode 100644 app/javascript/flavours/glitch/components/column_back_button.js create mode 100644 app/javascript/flavours/glitch/components/column_back_button.jsx delete mode 100644 app/javascript/flavours/glitch/components/column_back_button_slim.js create mode 100644 app/javascript/flavours/glitch/components/column_back_button_slim.jsx delete mode 100644 app/javascript/flavours/glitch/components/column_header.js create mode 100644 app/javascript/flavours/glitch/components/column_header.jsx delete mode 100644 app/javascript/flavours/glitch/components/common_counter.js create mode 100644 app/javascript/flavours/glitch/components/common_counter.jsx delete mode 100644 app/javascript/flavours/glitch/components/dismissable_banner.js create mode 100644 app/javascript/flavours/glitch/components/dismissable_banner.jsx delete mode 100644 app/javascript/flavours/glitch/components/display_name.js create mode 100644 app/javascript/flavours/glitch/components/display_name.jsx delete mode 100644 app/javascript/flavours/glitch/components/domain.js create mode 100644 app/javascript/flavours/glitch/components/domain.jsx delete mode 100644 app/javascript/flavours/glitch/components/dropdown_menu.js create mode 100644 app/javascript/flavours/glitch/components/dropdown_menu.jsx delete mode 100644 app/javascript/flavours/glitch/components/edited_timestamp/index.js create mode 100644 app/javascript/flavours/glitch/components/edited_timestamp/index.jsx delete mode 100644 app/javascript/flavours/glitch/components/error_boundary.js create mode 100644 app/javascript/flavours/glitch/components/error_boundary.jsx delete mode 100644 app/javascript/flavours/glitch/components/gifv.js create mode 100644 app/javascript/flavours/glitch/components/gifv.jsx delete mode 100644 app/javascript/flavours/glitch/components/hashtag.js create mode 100644 app/javascript/flavours/glitch/components/hashtag.jsx delete mode 100644 app/javascript/flavours/glitch/components/icon.js create mode 100644 app/javascript/flavours/glitch/components/icon.jsx delete mode 100644 app/javascript/flavours/glitch/components/icon_button.js create mode 100644 app/javascript/flavours/glitch/components/icon_button.jsx delete mode 100644 app/javascript/flavours/glitch/components/icon_with_badge.js create mode 100644 app/javascript/flavours/glitch/components/icon_with_badge.jsx delete mode 100644 app/javascript/flavours/glitch/components/image.js create mode 100644 app/javascript/flavours/glitch/components/image.jsx delete mode 100644 app/javascript/flavours/glitch/components/inline_account.js create mode 100644 app/javascript/flavours/glitch/components/inline_account.jsx delete mode 100644 app/javascript/flavours/glitch/components/intersection_observer_article.js create mode 100644 app/javascript/flavours/glitch/components/intersection_observer_article.jsx delete mode 100644 app/javascript/flavours/glitch/components/link.js create mode 100644 app/javascript/flavours/glitch/components/link.jsx delete mode 100644 app/javascript/flavours/glitch/components/load_gap.js create mode 100644 app/javascript/flavours/glitch/components/load_gap.jsx delete mode 100644 app/javascript/flavours/glitch/components/load_more.js create mode 100644 app/javascript/flavours/glitch/components/load_more.jsx delete mode 100644 app/javascript/flavours/glitch/components/load_pending.js create mode 100644 app/javascript/flavours/glitch/components/load_pending.jsx delete mode 100644 app/javascript/flavours/glitch/components/loading_indicator.js create mode 100644 app/javascript/flavours/glitch/components/loading_indicator.jsx delete mode 100644 app/javascript/flavours/glitch/components/logo.js create mode 100644 app/javascript/flavours/glitch/components/logo.jsx delete mode 100644 app/javascript/flavours/glitch/components/media_attachments.js create mode 100644 app/javascript/flavours/glitch/components/media_attachments.jsx delete mode 100644 app/javascript/flavours/glitch/components/media_gallery.js create mode 100644 app/javascript/flavours/glitch/components/media_gallery.jsx delete mode 100644 app/javascript/flavours/glitch/components/missing_indicator.js create mode 100644 app/javascript/flavours/glitch/components/missing_indicator.jsx delete mode 100644 app/javascript/flavours/glitch/components/modal_root.js create mode 100644 app/javascript/flavours/glitch/components/modal_root.jsx delete mode 100644 app/javascript/flavours/glitch/components/navigation_portal.js create mode 100644 app/javascript/flavours/glitch/components/navigation_portal.jsx delete mode 100644 app/javascript/flavours/glitch/components/not_signed_in_indicator.js create mode 100644 app/javascript/flavours/glitch/components/not_signed_in_indicator.jsx delete mode 100644 app/javascript/flavours/glitch/components/notification_purge_buttons.js create mode 100644 app/javascript/flavours/glitch/components/notification_purge_buttons.jsx delete mode 100644 app/javascript/flavours/glitch/components/permalink.js create mode 100644 app/javascript/flavours/glitch/components/permalink.jsx delete mode 100644 app/javascript/flavours/glitch/components/picture_in_picture_placeholder.js create mode 100644 app/javascript/flavours/glitch/components/picture_in_picture_placeholder.jsx delete mode 100644 app/javascript/flavours/glitch/components/poll.js create mode 100644 app/javascript/flavours/glitch/components/poll.jsx delete mode 100644 app/javascript/flavours/glitch/components/radio_button.js create mode 100644 app/javascript/flavours/glitch/components/radio_button.jsx delete mode 100644 app/javascript/flavours/glitch/components/regeneration_indicator.js create mode 100644 app/javascript/flavours/glitch/components/regeneration_indicator.jsx delete mode 100644 app/javascript/flavours/glitch/components/relative_timestamp.js create mode 100644 app/javascript/flavours/glitch/components/relative_timestamp.jsx delete mode 100644 app/javascript/flavours/glitch/components/scrollable_list.js create mode 100644 app/javascript/flavours/glitch/components/scrollable_list.jsx delete mode 100644 app/javascript/flavours/glitch/components/server_banner.js create mode 100644 app/javascript/flavours/glitch/components/server_banner.jsx delete mode 100644 app/javascript/flavours/glitch/components/setting_text.js create mode 100644 app/javascript/flavours/glitch/components/setting_text.jsx delete mode 100644 app/javascript/flavours/glitch/components/short_number.js create mode 100644 app/javascript/flavours/glitch/components/short_number.jsx delete mode 100644 app/javascript/flavours/glitch/components/skeleton.js create mode 100644 app/javascript/flavours/glitch/components/skeleton.jsx delete mode 100644 app/javascript/flavours/glitch/components/spoilers.js create mode 100644 app/javascript/flavours/glitch/components/spoilers.jsx delete mode 100644 app/javascript/flavours/glitch/components/status.js create mode 100644 app/javascript/flavours/glitch/components/status.jsx delete mode 100644 app/javascript/flavours/glitch/components/status_action_bar.js create mode 100644 app/javascript/flavours/glitch/components/status_action_bar.jsx delete mode 100644 app/javascript/flavours/glitch/components/status_content.js create mode 100644 app/javascript/flavours/glitch/components/status_content.jsx delete mode 100644 app/javascript/flavours/glitch/components/status_header.js create mode 100644 app/javascript/flavours/glitch/components/status_header.jsx delete mode 100644 app/javascript/flavours/glitch/components/status_icons.js create mode 100644 app/javascript/flavours/glitch/components/status_icons.jsx delete mode 100644 app/javascript/flavours/glitch/components/status_list.js create mode 100644 app/javascript/flavours/glitch/components/status_list.jsx delete mode 100644 app/javascript/flavours/glitch/components/status_prepend.js create mode 100644 app/javascript/flavours/glitch/components/status_prepend.jsx delete mode 100644 app/javascript/flavours/glitch/components/status_visibility_icon.js create mode 100644 app/javascript/flavours/glitch/components/status_visibility_icon.jsx delete mode 100644 app/javascript/flavours/glitch/components/timeline_hint.js create mode 100644 app/javascript/flavours/glitch/components/timeline_hint.jsx delete mode 100644 app/javascript/flavours/glitch/containers/account_container.js create mode 100644 app/javascript/flavours/glitch/containers/account_container.jsx delete mode 100644 app/javascript/flavours/glitch/containers/admin_component.js create mode 100644 app/javascript/flavours/glitch/containers/admin_component.jsx delete mode 100644 app/javascript/flavours/glitch/containers/compose_container.js create mode 100644 app/javascript/flavours/glitch/containers/compose_container.jsx delete mode 100644 app/javascript/flavours/glitch/containers/domain_container.js create mode 100644 app/javascript/flavours/glitch/containers/domain_container.jsx delete mode 100644 app/javascript/flavours/glitch/containers/mastodon.js create mode 100644 app/javascript/flavours/glitch/containers/mastodon.jsx delete mode 100644 app/javascript/flavours/glitch/containers/media_container.js create mode 100644 app/javascript/flavours/glitch/containers/media_container.jsx delete mode 100644 app/javascript/flavours/glitch/features/about/index.js create mode 100644 app/javascript/flavours/glitch/features/about/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/account/components/account_note.js create mode 100644 app/javascript/flavours/glitch/features/account/components/account_note.jsx delete mode 100644 app/javascript/flavours/glitch/features/account/components/action_bar.js create mode 100644 app/javascript/flavours/glitch/features/account/components/action_bar.jsx delete mode 100644 app/javascript/flavours/glitch/features/account/components/featured_tags.js create mode 100644 app/javascript/flavours/glitch/features/account/components/featured_tags.jsx delete mode 100644 app/javascript/flavours/glitch/features/account/components/follow_request_note.js create mode 100644 app/javascript/flavours/glitch/features/account/components/follow_request_note.jsx delete mode 100644 app/javascript/flavours/glitch/features/account/components/header.js create mode 100644 app/javascript/flavours/glitch/features/account/components/header.jsx delete mode 100644 app/javascript/flavours/glitch/features/account/components/profile_column_header.js create mode 100644 app/javascript/flavours/glitch/features/account/components/profile_column_header.jsx delete mode 100644 app/javascript/flavours/glitch/features/account/navigation.js create mode 100644 app/javascript/flavours/glitch/features/account/navigation.jsx delete mode 100644 app/javascript/flavours/glitch/features/account_gallery/components/media_item.js create mode 100644 app/javascript/flavours/glitch/features/account_gallery/components/media_item.jsx delete mode 100644 app/javascript/flavours/glitch/features/account_gallery/index.js create mode 100644 app/javascript/flavours/glitch/features/account_gallery/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/account_timeline/components/header.js create mode 100644 app/javascript/flavours/glitch/features/account_timeline/components/header.jsx delete mode 100644 app/javascript/flavours/glitch/features/account_timeline/components/limited_account_hint.js create mode 100644 app/javascript/flavours/glitch/features/account_timeline/components/limited_account_hint.jsx delete mode 100644 app/javascript/flavours/glitch/features/account_timeline/components/moved_note.js create mode 100644 app/javascript/flavours/glitch/features/account_timeline/components/moved_note.jsx delete mode 100644 app/javascript/flavours/glitch/features/account_timeline/containers/header_container.js create mode 100644 app/javascript/flavours/glitch/features/account_timeline/containers/header_container.jsx delete mode 100644 app/javascript/flavours/glitch/features/account_timeline/index.js create mode 100644 app/javascript/flavours/glitch/features/account_timeline/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/audio/index.js create mode 100644 app/javascript/flavours/glitch/features/audio/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/blocks/index.js create mode 100644 app/javascript/flavours/glitch/features/blocks/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/bookmarked_statuses/index.js create mode 100644 app/javascript/flavours/glitch/features/bookmarked_statuses/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/closed_registrations_modal/index.js create mode 100644 app/javascript/flavours/glitch/features/closed_registrations_modal/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/community_timeline/components/column_settings.js create mode 100644 app/javascript/flavours/glitch/features/community_timeline/components/column_settings.jsx delete mode 100644 app/javascript/flavours/glitch/features/community_timeline/index.js create mode 100644 app/javascript/flavours/glitch/features/community_timeline/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/compose/components/action_bar.js create mode 100644 app/javascript/flavours/glitch/features/compose/components/action_bar.jsx delete mode 100644 app/javascript/flavours/glitch/features/compose/components/autosuggest_account.js create mode 100644 app/javascript/flavours/glitch/features/compose/components/autosuggest_account.jsx delete mode 100644 app/javascript/flavours/glitch/features/compose/components/character_counter.js create mode 100644 app/javascript/flavours/glitch/features/compose/components/character_counter.jsx delete mode 100644 app/javascript/flavours/glitch/features/compose/components/compose_form.js create mode 100644 app/javascript/flavours/glitch/features/compose/components/compose_form.jsx delete mode 100644 app/javascript/flavours/glitch/features/compose/components/dropdown.js create mode 100644 app/javascript/flavours/glitch/features/compose/components/dropdown.jsx delete mode 100644 app/javascript/flavours/glitch/features/compose/components/dropdown_menu.js create mode 100644 app/javascript/flavours/glitch/features/compose/components/dropdown_menu.jsx delete mode 100644 app/javascript/flavours/glitch/features/compose/components/emoji_picker_dropdown.js create mode 100644 app/javascript/flavours/glitch/features/compose/components/emoji_picker_dropdown.jsx delete mode 100644 app/javascript/flavours/glitch/features/compose/components/header.js create mode 100644 app/javascript/flavours/glitch/features/compose/components/header.jsx delete mode 100644 app/javascript/flavours/glitch/features/compose/components/language_dropdown.js create mode 100644 app/javascript/flavours/glitch/features/compose/components/language_dropdown.jsx delete mode 100644 app/javascript/flavours/glitch/features/compose/components/navigation_bar.js create mode 100644 app/javascript/flavours/glitch/features/compose/components/navigation_bar.jsx delete mode 100644 app/javascript/flavours/glitch/features/compose/components/options.js create mode 100644 app/javascript/flavours/glitch/features/compose/components/options.jsx delete mode 100644 app/javascript/flavours/glitch/features/compose/components/poll_form.js create mode 100644 app/javascript/flavours/glitch/features/compose/components/poll_form.jsx delete mode 100644 app/javascript/flavours/glitch/features/compose/components/privacy_dropdown.js create mode 100644 app/javascript/flavours/glitch/features/compose/components/privacy_dropdown.jsx delete mode 100644 app/javascript/flavours/glitch/features/compose/components/publisher.js create mode 100644 app/javascript/flavours/glitch/features/compose/components/publisher.jsx delete mode 100644 app/javascript/flavours/glitch/features/compose/components/reply_indicator.js create mode 100644 app/javascript/flavours/glitch/features/compose/components/reply_indicator.jsx delete mode 100644 app/javascript/flavours/glitch/features/compose/components/search.js create mode 100644 app/javascript/flavours/glitch/features/compose/components/search.jsx delete mode 100644 app/javascript/flavours/glitch/features/compose/components/search_results.js create mode 100644 app/javascript/flavours/glitch/features/compose/components/search_results.jsx delete mode 100644 app/javascript/flavours/glitch/features/compose/components/text_icon_button.js create mode 100644 app/javascript/flavours/glitch/features/compose/components/text_icon_button.jsx delete mode 100644 app/javascript/flavours/glitch/features/compose/components/textarea_icons.js create mode 100644 app/javascript/flavours/glitch/features/compose/components/textarea_icons.jsx delete mode 100644 app/javascript/flavours/glitch/features/compose/components/upload.js create mode 100644 app/javascript/flavours/glitch/features/compose/components/upload.jsx delete mode 100644 app/javascript/flavours/glitch/features/compose/components/upload_form.js create mode 100644 app/javascript/flavours/glitch/features/compose/components/upload_form.jsx delete mode 100644 app/javascript/flavours/glitch/features/compose/components/upload_progress.js create mode 100644 app/javascript/flavours/glitch/features/compose/components/upload_progress.jsx delete mode 100644 app/javascript/flavours/glitch/features/compose/components/warning.js create mode 100644 app/javascript/flavours/glitch/features/compose/components/warning.jsx delete mode 100644 app/javascript/flavours/glitch/features/compose/containers/sensitive_button_container.js create mode 100644 app/javascript/flavours/glitch/features/compose/containers/sensitive_button_container.jsx delete mode 100644 app/javascript/flavours/glitch/features/compose/containers/warning_container.js create mode 100644 app/javascript/flavours/glitch/features/compose/containers/warning_container.jsx delete mode 100644 app/javascript/flavours/glitch/features/compose/index.js create mode 100644 app/javascript/flavours/glitch/features/compose/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/direct_timeline/components/column_settings.js create mode 100644 app/javascript/flavours/glitch/features/direct_timeline/components/column_settings.jsx delete mode 100644 app/javascript/flavours/glitch/features/direct_timeline/components/conversation.js create mode 100644 app/javascript/flavours/glitch/features/direct_timeline/components/conversation.jsx delete mode 100644 app/javascript/flavours/glitch/features/direct_timeline/components/conversations_list.js create mode 100644 app/javascript/flavours/glitch/features/direct_timeline/components/conversations_list.jsx delete mode 100644 app/javascript/flavours/glitch/features/direct_timeline/index.js create mode 100644 app/javascript/flavours/glitch/features/direct_timeline/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/directory/components/account_card.js create mode 100644 app/javascript/flavours/glitch/features/directory/components/account_card.jsx delete mode 100644 app/javascript/flavours/glitch/features/directory/index.js create mode 100644 app/javascript/flavours/glitch/features/directory/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/domain_blocks/index.js create mode 100644 app/javascript/flavours/glitch/features/domain_blocks/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/explore/components/story.js create mode 100644 app/javascript/flavours/glitch/features/explore/components/story.jsx delete mode 100644 app/javascript/flavours/glitch/features/explore/index.js create mode 100644 app/javascript/flavours/glitch/features/explore/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/explore/links.js create mode 100644 app/javascript/flavours/glitch/features/explore/links.jsx delete mode 100644 app/javascript/flavours/glitch/features/explore/results.js create mode 100644 app/javascript/flavours/glitch/features/explore/results.jsx delete mode 100644 app/javascript/flavours/glitch/features/explore/statuses.js create mode 100644 app/javascript/flavours/glitch/features/explore/statuses.jsx delete mode 100644 app/javascript/flavours/glitch/features/explore/suggestions.js create mode 100644 app/javascript/flavours/glitch/features/explore/suggestions.jsx delete mode 100644 app/javascript/flavours/glitch/features/explore/tags.js create mode 100644 app/javascript/flavours/glitch/features/explore/tags.jsx delete mode 100644 app/javascript/flavours/glitch/features/favourited_statuses/index.js create mode 100644 app/javascript/flavours/glitch/features/favourited_statuses/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/favourites/index.js create mode 100644 app/javascript/flavours/glitch/features/favourites/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/filters/added_to_filter.js create mode 100644 app/javascript/flavours/glitch/features/filters/added_to_filter.jsx delete mode 100644 app/javascript/flavours/glitch/features/filters/select_filter.js create mode 100644 app/javascript/flavours/glitch/features/filters/select_filter.jsx delete mode 100644 app/javascript/flavours/glitch/features/follow_recommendations/components/account.js create mode 100644 app/javascript/flavours/glitch/features/follow_recommendations/components/account.jsx delete mode 100644 app/javascript/flavours/glitch/features/follow_recommendations/index.js create mode 100644 app/javascript/flavours/glitch/features/follow_recommendations/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/follow_requests/components/account_authorize.js create mode 100644 app/javascript/flavours/glitch/features/follow_requests/components/account_authorize.jsx delete mode 100644 app/javascript/flavours/glitch/features/follow_requests/index.js create mode 100644 app/javascript/flavours/glitch/features/follow_requests/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/followed_tags/index.js create mode 100644 app/javascript/flavours/glitch/features/followed_tags/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/followers/index.js create mode 100644 app/javascript/flavours/glitch/features/followers/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/following/index.js create mode 100644 app/javascript/flavours/glitch/features/following/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/generic_not_found/index.js create mode 100644 app/javascript/flavours/glitch/features/generic_not_found/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/getting_started/components/announcements.js create mode 100644 app/javascript/flavours/glitch/features/getting_started/components/announcements.jsx delete mode 100644 app/javascript/flavours/glitch/features/getting_started/components/trends.js create mode 100644 app/javascript/flavours/glitch/features/getting_started/components/trends.jsx delete mode 100644 app/javascript/flavours/glitch/features/getting_started/index.js create mode 100644 app/javascript/flavours/glitch/features/getting_started/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/getting_started_misc/index.js create mode 100644 app/javascript/flavours/glitch/features/getting_started_misc/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/hashtag_timeline/components/column_settings.js create mode 100644 app/javascript/flavours/glitch/features/hashtag_timeline/components/column_settings.jsx delete mode 100644 app/javascript/flavours/glitch/features/hashtag_timeline/index.js create mode 100644 app/javascript/flavours/glitch/features/hashtag_timeline/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/home_timeline/components/column_settings.js create mode 100644 app/javascript/flavours/glitch/features/home_timeline/components/column_settings.jsx delete mode 100644 app/javascript/flavours/glitch/features/home_timeline/index.js create mode 100644 app/javascript/flavours/glitch/features/home_timeline/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/interaction_modal/index.js create mode 100644 app/javascript/flavours/glitch/features/interaction_modal/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/keyboard_shortcuts/index.js create mode 100644 app/javascript/flavours/glitch/features/keyboard_shortcuts/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/list_adder/components/account.js create mode 100644 app/javascript/flavours/glitch/features/list_adder/components/account.jsx delete mode 100644 app/javascript/flavours/glitch/features/list_adder/components/list.js create mode 100644 app/javascript/flavours/glitch/features/list_adder/components/list.jsx delete mode 100644 app/javascript/flavours/glitch/features/list_adder/index.js create mode 100644 app/javascript/flavours/glitch/features/list_adder/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/list_editor/components/account.js create mode 100644 app/javascript/flavours/glitch/features/list_editor/components/account.jsx delete mode 100644 app/javascript/flavours/glitch/features/list_editor/components/edit_list_form.js create mode 100644 app/javascript/flavours/glitch/features/list_editor/components/edit_list_form.jsx delete mode 100644 app/javascript/flavours/glitch/features/list_editor/components/search.js create mode 100644 app/javascript/flavours/glitch/features/list_editor/components/search.jsx delete mode 100644 app/javascript/flavours/glitch/features/list_editor/index.js create mode 100644 app/javascript/flavours/glitch/features/list_editor/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/list_timeline/index.js create mode 100644 app/javascript/flavours/glitch/features/list_timeline/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/lists/components/new_list_form.js create mode 100644 app/javascript/flavours/glitch/features/lists/components/new_list_form.jsx delete mode 100644 app/javascript/flavours/glitch/features/lists/index.js create mode 100644 app/javascript/flavours/glitch/features/lists/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/local_settings/index.js create mode 100644 app/javascript/flavours/glitch/features/local_settings/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/local_settings/navigation/index.js create mode 100644 app/javascript/flavours/glitch/features/local_settings/navigation/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/local_settings/navigation/item/index.js create mode 100644 app/javascript/flavours/glitch/features/local_settings/navigation/item/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/local_settings/page/deprecated_item/index.js create mode 100644 app/javascript/flavours/glitch/features/local_settings/page/deprecated_item/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/local_settings/page/index.js create mode 100644 app/javascript/flavours/glitch/features/local_settings/page/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/local_settings/page/item/index.js create mode 100644 app/javascript/flavours/glitch/features/local_settings/page/item/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/mutes/index.js create mode 100644 app/javascript/flavours/glitch/features/mutes/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/notifications/components/admin_report.js create mode 100644 app/javascript/flavours/glitch/features/notifications/components/admin_report.jsx delete mode 100644 app/javascript/flavours/glitch/features/notifications/components/admin_signup.js create mode 100644 app/javascript/flavours/glitch/features/notifications/components/admin_signup.jsx delete mode 100644 app/javascript/flavours/glitch/features/notifications/components/clear_column_button.js create mode 100644 app/javascript/flavours/glitch/features/notifications/components/clear_column_button.jsx delete mode 100644 app/javascript/flavours/glitch/features/notifications/components/column_settings.js create mode 100644 app/javascript/flavours/glitch/features/notifications/components/column_settings.jsx delete mode 100644 app/javascript/flavours/glitch/features/notifications/components/filter_bar.js create mode 100644 app/javascript/flavours/glitch/features/notifications/components/filter_bar.jsx delete mode 100644 app/javascript/flavours/glitch/features/notifications/components/follow.js create mode 100644 app/javascript/flavours/glitch/features/notifications/components/follow.jsx delete mode 100644 app/javascript/flavours/glitch/features/notifications/components/follow_request.js create mode 100644 app/javascript/flavours/glitch/features/notifications/components/follow_request.jsx delete mode 100644 app/javascript/flavours/glitch/features/notifications/components/grant_permission_button.js create mode 100644 app/javascript/flavours/glitch/features/notifications/components/grant_permission_button.jsx delete mode 100644 app/javascript/flavours/glitch/features/notifications/components/notification.js create mode 100644 app/javascript/flavours/glitch/features/notifications/components/notification.jsx delete mode 100644 app/javascript/flavours/glitch/features/notifications/components/notifications_permission_banner.js create mode 100644 app/javascript/flavours/glitch/features/notifications/components/notifications_permission_banner.jsx delete mode 100644 app/javascript/flavours/glitch/features/notifications/components/overlay.js create mode 100644 app/javascript/flavours/glitch/features/notifications/components/overlay.jsx delete mode 100644 app/javascript/flavours/glitch/features/notifications/components/pill_bar_button.js create mode 100644 app/javascript/flavours/glitch/features/notifications/components/pill_bar_button.jsx delete mode 100644 app/javascript/flavours/glitch/features/notifications/components/report.js create mode 100644 app/javascript/flavours/glitch/features/notifications/components/report.jsx delete mode 100644 app/javascript/flavours/glitch/features/notifications/components/setting_toggle.js create mode 100644 app/javascript/flavours/glitch/features/notifications/components/setting_toggle.jsx delete mode 100644 app/javascript/flavours/glitch/features/notifications/index.js create mode 100644 app/javascript/flavours/glitch/features/notifications/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/picture_in_picture/components/footer.js create mode 100644 app/javascript/flavours/glitch/features/picture_in_picture/components/footer.jsx delete mode 100644 app/javascript/flavours/glitch/features/picture_in_picture/components/header.js create mode 100644 app/javascript/flavours/glitch/features/picture_in_picture/components/header.jsx delete mode 100644 app/javascript/flavours/glitch/features/picture_in_picture/index.js create mode 100644 app/javascript/flavours/glitch/features/picture_in_picture/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/pinned_accounts_editor/index.js create mode 100644 app/javascript/flavours/glitch/features/pinned_accounts_editor/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/pinned_statuses/index.js create mode 100644 app/javascript/flavours/glitch/features/pinned_statuses/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/privacy_policy/index.js create mode 100644 app/javascript/flavours/glitch/features/privacy_policy/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/public_timeline/components/column_settings.js create mode 100644 app/javascript/flavours/glitch/features/public_timeline/components/column_settings.jsx delete mode 100644 app/javascript/flavours/glitch/features/public_timeline/index.js create mode 100644 app/javascript/flavours/glitch/features/public_timeline/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/reblogs/index.js create mode 100644 app/javascript/flavours/glitch/features/reblogs/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/report/category.js create mode 100644 app/javascript/flavours/glitch/features/report/category.jsx delete mode 100644 app/javascript/flavours/glitch/features/report/comment.js create mode 100644 app/javascript/flavours/glitch/features/report/comment.jsx delete mode 100644 app/javascript/flavours/glitch/features/report/components/option.js create mode 100644 app/javascript/flavours/glitch/features/report/components/option.jsx delete mode 100644 app/javascript/flavours/glitch/features/report/components/status_check_box.js create mode 100644 app/javascript/flavours/glitch/features/report/components/status_check_box.jsx delete mode 100644 app/javascript/flavours/glitch/features/report/rules.js create mode 100644 app/javascript/flavours/glitch/features/report/rules.jsx delete mode 100644 app/javascript/flavours/glitch/features/report/statuses.js create mode 100644 app/javascript/flavours/glitch/features/report/statuses.jsx delete mode 100644 app/javascript/flavours/glitch/features/report/thanks.js create mode 100644 app/javascript/flavours/glitch/features/report/thanks.jsx delete mode 100644 app/javascript/flavours/glitch/features/standalone/compose/index.js create mode 100644 app/javascript/flavours/glitch/features/standalone/compose/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/status/components/action_bar.js create mode 100644 app/javascript/flavours/glitch/features/status/components/action_bar.jsx delete mode 100644 app/javascript/flavours/glitch/features/status/components/card.js create mode 100644 app/javascript/flavours/glitch/features/status/components/card.jsx delete mode 100644 app/javascript/flavours/glitch/features/status/components/detailed_status.js create mode 100644 app/javascript/flavours/glitch/features/status/components/detailed_status.jsx delete mode 100644 app/javascript/flavours/glitch/features/status/index.js create mode 100644 app/javascript/flavours/glitch/features/status/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/subscribed_languages_modal/index.js create mode 100644 app/javascript/flavours/glitch/features/subscribed_languages_modal/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/actions_modal.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/actions_modal.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/audio_modal.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/audio_modal.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/block_modal.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/block_modal.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/boost_modal.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/boost_modal.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/bundle.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/bundle.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/bundle_column_error.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/bundle_column_error.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/bundle_modal_error.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/bundle_modal_error.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/column.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/column.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/column_header.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/column_header.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/column_link.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/column_link.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/column_loading.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/column_loading.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/column_subheading.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/column_subheading.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/columns_area.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/columns_area.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/compare_history_modal.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/compare_history_modal.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/compose_panel.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/compose_panel.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/confirmation_modal.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/confirmation_modal.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/deprecated_settings_modal.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/deprecated_settings_modal.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/disabled_account_banner.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/disabled_account_banner.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/doodle_modal.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/doodle_modal.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/drawer_loading.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/drawer_loading.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/embed_modal.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/embed_modal.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/favourite_modal.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/favourite_modal.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/filter_modal.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/filter_modal.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/focal_point_modal.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/focal_point_modal.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/follow_requests_column_link.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/follow_requests_column_link.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/header.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/header.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/image_loader.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/image_loader.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/image_modal.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/image_modal.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/link_footer.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/link_footer.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/list_panel.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/list_panel.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/media_modal.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/media_modal.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/modal_loading.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/modal_loading.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/modal_root.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/modal_root.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/mute_modal.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/mute_modal.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/navigation_panel.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/navigation_panel.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/onboarding_modal.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/onboarding_modal.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/report_modal.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/report_modal.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/sign_in_banner.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/sign_in_banner.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/upload_area.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/upload_area.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/video_modal.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/video_modal.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/components/zoomable_image.js create mode 100644 app/javascript/flavours/glitch/features/ui/components/zoomable_image.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/index.js create mode 100644 app/javascript/flavours/glitch/features/ui/index.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/util/react_router_helpers.js create mode 100644 app/javascript/flavours/glitch/features/ui/util/react_router_helpers.jsx delete mode 100644 app/javascript/flavours/glitch/features/ui/util/reduced_motion.js create mode 100644 app/javascript/flavours/glitch/features/ui/util/reduced_motion.jsx delete mode 100644 app/javascript/flavours/glitch/features/video/index.js create mode 100644 app/javascript/flavours/glitch/features/video/index.jsx delete mode 100644 app/javascript/flavours/glitch/main.js create mode 100644 app/javascript/flavours/glitch/main.jsx delete mode 100644 app/javascript/flavours/glitch/packs/admin.js create mode 100644 app/javascript/flavours/glitch/packs/admin.jsx delete mode 100644 app/javascript/flavours/glitch/packs/public.js create mode 100644 app/javascript/flavours/glitch/packs/public.jsx delete mode 100644 app/javascript/flavours/glitch/packs/share.js create mode 100644 app/javascript/flavours/glitch/packs/share.jsx delete mode 100644 app/javascript/flavours/glitch/utils/icons.js create mode 100644 app/javascript/flavours/glitch/utils/icons.jsx (limited to 'app/javascript/flavours/glitch/features/subscribed_languages_modal') diff --git a/app/javascript/flavours/glitch/components/account.js b/app/javascript/flavours/glitch/components/account.js deleted file mode 100644 index 7ce4b65aa..000000000 --- a/app/javascript/flavours/glitch/components/account.js +++ /dev/null @@ -1,186 +0,0 @@ -import React, { Fragment } from 'react'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import PropTypes from 'prop-types'; -import Avatar from './avatar'; -import DisplayName from './display_name'; -import Permalink from './permalink'; -import IconButton from './icon_button'; -import { defineMessages, injectIntl } from 'react-intl'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import { me } from 'flavours/glitch/initial_state'; -import RelativeTimestamp from './relative_timestamp'; -import Skeleton from 'flavours/glitch/components/skeleton'; - -const messages = defineMessages({ - follow: { id: 'account.follow', defaultMessage: 'Follow' }, - unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' }, - requested: { id: 'account.requested', defaultMessage: 'Awaiting approval' }, - unblock: { id: 'account.unblock', defaultMessage: 'Unblock @{name}' }, - unmute: { id: 'account.unmute', defaultMessage: 'Unmute @{name}' }, - mute_notifications: { id: 'account.mute_notifications', defaultMessage: 'Mute notifications from @{name}' }, - unmute_notifications: { id: 'account.unmute_notifications', defaultMessage: 'Unmute notifications from @{name}' }, - mute: { id: 'account.mute', defaultMessage: 'Mute @{name}' }, - block: { id: 'account.block', defaultMessage: 'Block @{name}' }, -}); - -export default @injectIntl -class Account extends ImmutablePureComponent { - - static propTypes = { - size: PropTypes.number, - account: ImmutablePropTypes.map, - onFollow: PropTypes.func.isRequired, - onBlock: PropTypes.func.isRequired, - onMute: PropTypes.func.isRequired, - onMuteNotifications: PropTypes.func.isRequired, - intl: PropTypes.object.isRequired, - hidden: PropTypes.bool, - small: PropTypes.bool, - actionIcon: PropTypes.string, - actionTitle: PropTypes.string, - defaultAction: PropTypes.string, - onActionClick: PropTypes.func, - }; - - static defaultProps = { - size: 36, - }; - - handleFollow = () => { - this.props.onFollow(this.props.account); - }; - - handleBlock = () => { - this.props.onBlock(this.props.account); - }; - - handleMute = () => { - this.props.onMute(this.props.account); - }; - - handleMuteNotifications = () => { - this.props.onMuteNotifications(this.props.account, true); - }; - - handleUnmuteNotifications = () => { - this.props.onMuteNotifications(this.props.account, false); - }; - - handleAction = () => { - this.props.onActionClick(this.props.account); - }; - - render () { - const { - account, - hidden, - intl, - small, - onActionClick, - actionIcon, - actionTitle, - defaultAction, - size, - } = this.props; - - if (!account) { - return ( -
-
-
-
- -
-
-
- ); - } - - if (hidden) { - return ( - - {account.get('display_name')} - {account.get('username')} - - ); - } - - let buttons; - - if (onActionClick) { - if (actionIcon) { - buttons = ; - } - } else if (account.get('id') !== me && !small && account.get('relationship', null) !== null) { - const following = account.getIn(['relationship', 'following']); - const requested = account.getIn(['relationship', 'requested']); - const blocking = account.getIn(['relationship', 'blocking']); - const muting = account.getIn(['relationship', 'muting']); - - if (requested) { - buttons = ; - } else if (blocking) { - buttons = ; - } else if (muting) { - let hidingNotificationsButton; - if (account.getIn(['relationship', 'muting_notifications'])) { - hidingNotificationsButton = ; - } else { - hidingNotificationsButton = ; - } - buttons = ( - - - {hidingNotificationsButton} - - ); - } else if (defaultAction === 'mute') { - buttons = ; - } else if (defaultAction === 'block') { - buttons = ; - } else if (!account.get('moved') || following) { - buttons = ; - } - } - - let mute_expires_at; - if (account.get('mute_expires_at')) { - mute_expires_at =
; - } - - return small ? ( - -
- -
- -
- ) : ( -
-
- -
- {mute_expires_at} - -
- {buttons ? -
- {buttons} -
- : null} -
-
- ); - } - -} diff --git a/app/javascript/flavours/glitch/components/account.jsx b/app/javascript/flavours/glitch/components/account.jsx new file mode 100644 index 000000000..7ce4b65aa --- /dev/null +++ b/app/javascript/flavours/glitch/components/account.jsx @@ -0,0 +1,186 @@ +import React, { Fragment } from 'react'; +import ImmutablePropTypes from 'react-immutable-proptypes'; +import PropTypes from 'prop-types'; +import Avatar from './avatar'; +import DisplayName from './display_name'; +import Permalink from './permalink'; +import IconButton from './icon_button'; +import { defineMessages, injectIntl } from 'react-intl'; +import ImmutablePureComponent from 'react-immutable-pure-component'; +import { me } from 'flavours/glitch/initial_state'; +import RelativeTimestamp from './relative_timestamp'; +import Skeleton from 'flavours/glitch/components/skeleton'; + +const messages = defineMessages({ + follow: { id: 'account.follow', defaultMessage: 'Follow' }, + unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' }, + requested: { id: 'account.requested', defaultMessage: 'Awaiting approval' }, + unblock: { id: 'account.unblock', defaultMessage: 'Unblock @{name}' }, + unmute: { id: 'account.unmute', defaultMessage: 'Unmute @{name}' }, + mute_notifications: { id: 'account.mute_notifications', defaultMessage: 'Mute notifications from @{name}' }, + unmute_notifications: { id: 'account.unmute_notifications', defaultMessage: 'Unmute notifications from @{name}' }, + mute: { id: 'account.mute', defaultMessage: 'Mute @{name}' }, + block: { id: 'account.block', defaultMessage: 'Block @{name}' }, +}); + +export default @injectIntl +class Account extends ImmutablePureComponent { + + static propTypes = { + size: PropTypes.number, + account: ImmutablePropTypes.map, + onFollow: PropTypes.func.isRequired, + onBlock: PropTypes.func.isRequired, + onMute: PropTypes.func.isRequired, + onMuteNotifications: PropTypes.func.isRequired, + intl: PropTypes.object.isRequired, + hidden: PropTypes.bool, + small: PropTypes.bool, + actionIcon: PropTypes.string, + actionTitle: PropTypes.string, + defaultAction: PropTypes.string, + onActionClick: PropTypes.func, + }; + + static defaultProps = { + size: 36, + }; + + handleFollow = () => { + this.props.onFollow(this.props.account); + }; + + handleBlock = () => { + this.props.onBlock(this.props.account); + }; + + handleMute = () => { + this.props.onMute(this.props.account); + }; + + handleMuteNotifications = () => { + this.props.onMuteNotifications(this.props.account, true); + }; + + handleUnmuteNotifications = () => { + this.props.onMuteNotifications(this.props.account, false); + }; + + handleAction = () => { + this.props.onActionClick(this.props.account); + }; + + render () { + const { + account, + hidden, + intl, + small, + onActionClick, + actionIcon, + actionTitle, + defaultAction, + size, + } = this.props; + + if (!account) { + return ( +
+
+
+
+ +
+
+
+ ); + } + + if (hidden) { + return ( + + {account.get('display_name')} + {account.get('username')} + + ); + } + + let buttons; + + if (onActionClick) { + if (actionIcon) { + buttons = ; + } + } else if (account.get('id') !== me && !small && account.get('relationship', null) !== null) { + const following = account.getIn(['relationship', 'following']); + const requested = account.getIn(['relationship', 'requested']); + const blocking = account.getIn(['relationship', 'blocking']); + const muting = account.getIn(['relationship', 'muting']); + + if (requested) { + buttons = ; + } else if (blocking) { + buttons = ; + } else if (muting) { + let hidingNotificationsButton; + if (account.getIn(['relationship', 'muting_notifications'])) { + hidingNotificationsButton = ; + } else { + hidingNotificationsButton = ; + } + buttons = ( + + + {hidingNotificationsButton} + + ); + } else if (defaultAction === 'mute') { + buttons = ; + } else if (defaultAction === 'block') { + buttons = ; + } else if (!account.get('moved') || following) { + buttons = ; + } + } + + let mute_expires_at; + if (account.get('mute_expires_at')) { + mute_expires_at =
; + } + + return small ? ( + +
+ +
+ +
+ ) : ( +
+
+ +
+ {mute_expires_at} + +
+ {buttons ? +
+ {buttons} +
+ : null} +
+
+ ); + } + +} diff --git a/app/javascript/flavours/glitch/components/admin/Counter.js b/app/javascript/flavours/glitch/components/admin/Counter.js deleted file mode 100644 index 5b6a19f8d..000000000 --- a/app/javascript/flavours/glitch/components/admin/Counter.js +++ /dev/null @@ -1,117 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import api from 'flavours/glitch/api'; -import { FormattedNumber } from 'react-intl'; -import { Sparklines, SparklinesCurve } from 'react-sparklines'; -import classNames from 'classnames'; -import Skeleton from 'flavours/glitch/components/skeleton'; - -const percIncrease = (a, b) => { - let percent; - - if (b !== 0) { - if (a !== 0) { - percent = (b - a) / a; - } else { - percent = 1; - } - } else if (b === 0 && a === 0) { - percent = 0; - } else { - percent = - 1; - } - - return percent; -}; - -export default class Counter extends React.PureComponent { - - static propTypes = { - measure: PropTypes.string.isRequired, - start_at: PropTypes.string.isRequired, - end_at: PropTypes.string.isRequired, - label: PropTypes.string.isRequired, - href: PropTypes.string, - params: PropTypes.object, - target: PropTypes.string, - }; - - state = { - loading: true, - data: null, - }; - - componentDidMount () { - const { measure, start_at, end_at, params } = this.props; - - api().post('/api/v1/admin/measures', { keys: [measure], start_at, end_at, [measure]: params }).then(res => { - this.setState({ - loading: false, - data: res.data, - }); - }).catch(err => { - console.error(err); - }); - } - - render () { - const { label, href, target } = this.props; - const { loading, data } = this.state; - - let content; - - if (loading) { - content = ( - - - - - ); - } else { - const measure = data[0]; - const percentChange = measure.previous_total && percIncrease(measure.previous_total * 1, measure.total * 1); - - content = ( - - {measure.human_value || } - {measure.previous_total && ( 0, negative: percentChange < 0 })}>{percentChange > 0 && '+'})} - - ); - } - - const inner = ( - -
- {content} -
- -
- {label} -
- -
- {!loading && ( - x.value * 1)}> - - - )} -
-
- ); - - if (href) { - return ( - - {inner} - - ); - } else { - return ( -
- {inner} -
- ); - } - } - -} diff --git a/app/javascript/flavours/glitch/components/admin/Counter.jsx b/app/javascript/flavours/glitch/components/admin/Counter.jsx new file mode 100644 index 000000000..5b6a19f8d --- /dev/null +++ b/app/javascript/flavours/glitch/components/admin/Counter.jsx @@ -0,0 +1,117 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import api from 'flavours/glitch/api'; +import { FormattedNumber } from 'react-intl'; +import { Sparklines, SparklinesCurve } from 'react-sparklines'; +import classNames from 'classnames'; +import Skeleton from 'flavours/glitch/components/skeleton'; + +const percIncrease = (a, b) => { + let percent; + + if (b !== 0) { + if (a !== 0) { + percent = (b - a) / a; + } else { + percent = 1; + } + } else if (b === 0 && a === 0) { + percent = 0; + } else { + percent = - 1; + } + + return percent; +}; + +export default class Counter extends React.PureComponent { + + static propTypes = { + measure: PropTypes.string.isRequired, + start_at: PropTypes.string.isRequired, + end_at: PropTypes.string.isRequired, + label: PropTypes.string.isRequired, + href: PropTypes.string, + params: PropTypes.object, + target: PropTypes.string, + }; + + state = { + loading: true, + data: null, + }; + + componentDidMount () { + const { measure, start_at, end_at, params } = this.props; + + api().post('/api/v1/admin/measures', { keys: [measure], start_at, end_at, [measure]: params }).then(res => { + this.setState({ + loading: false, + data: res.data, + }); + }).catch(err => { + console.error(err); + }); + } + + render () { + const { label, href, target } = this.props; + const { loading, data } = this.state; + + let content; + + if (loading) { + content = ( + + + + + ); + } else { + const measure = data[0]; + const percentChange = measure.previous_total && percIncrease(measure.previous_total * 1, measure.total * 1); + + content = ( + + {measure.human_value || } + {measure.previous_total && ( 0, negative: percentChange < 0 })}>{percentChange > 0 && '+'})} + + ); + } + + const inner = ( + +
+ {content} +
+ +
+ {label} +
+ +
+ {!loading && ( + x.value * 1)}> + + + )} +
+
+ ); + + if (href) { + return ( + + {inner} + + ); + } else { + return ( +
+ {inner} +
+ ); + } + } + +} diff --git a/app/javascript/flavours/glitch/components/admin/Dimension.js b/app/javascript/flavours/glitch/components/admin/Dimension.js deleted file mode 100644 index 3dac8c6c2..000000000 --- a/app/javascript/flavours/glitch/components/admin/Dimension.js +++ /dev/null @@ -1,93 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import api from 'flavours/glitch/api'; -import { FormattedNumber } from 'react-intl'; -import { roundTo10 } from 'flavours/glitch/utils/numbers'; -import Skeleton from 'flavours/glitch/components/skeleton'; - -export default class Dimension extends React.PureComponent { - - static propTypes = { - dimension: PropTypes.string.isRequired, - start_at: PropTypes.string.isRequired, - end_at: PropTypes.string.isRequired, - limit: PropTypes.number.isRequired, - label: PropTypes.string.isRequired, - params: PropTypes.object, - }; - - state = { - loading: true, - data: null, - }; - - componentDidMount () { - const { start_at, end_at, dimension, limit, params } = this.props; - - api().post('/api/v1/admin/dimensions', { keys: [dimension], start_at, end_at, limit, [dimension]: params }).then(res => { - this.setState({ - loading: false, - data: res.data, - }); - }).catch(err => { - console.error(err); - }); - } - - render () { - const { label, limit } = this.props; - const { loading, data } = this.state; - - let content; - - if (loading) { - content = ( - - - {Array.from(Array(limit)).map((_, i) => ( - - - - - - ))} - -
- - - -
- ); - } else { - const sum = data[0].data.reduce((sum, cur) => sum + (cur.value * 1), 0); - - content = ( - - - {data[0].data.map(item => ( - - - - - - ))} - -
- - {item.human_key} - - {typeof item.human_value !== 'undefined' ? item.human_value : } -
- ); - } - - return ( -
-

{label}

- - {content} -
- ); - } - -} diff --git a/app/javascript/flavours/glitch/components/admin/Dimension.jsx b/app/javascript/flavours/glitch/components/admin/Dimension.jsx new file mode 100644 index 000000000..3dac8c6c2 --- /dev/null +++ b/app/javascript/flavours/glitch/components/admin/Dimension.jsx @@ -0,0 +1,93 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import api from 'flavours/glitch/api'; +import { FormattedNumber } from 'react-intl'; +import { roundTo10 } from 'flavours/glitch/utils/numbers'; +import Skeleton from 'flavours/glitch/components/skeleton'; + +export default class Dimension extends React.PureComponent { + + static propTypes = { + dimension: PropTypes.string.isRequired, + start_at: PropTypes.string.isRequired, + end_at: PropTypes.string.isRequired, + limit: PropTypes.number.isRequired, + label: PropTypes.string.isRequired, + params: PropTypes.object, + }; + + state = { + loading: true, + data: null, + }; + + componentDidMount () { + const { start_at, end_at, dimension, limit, params } = this.props; + + api().post('/api/v1/admin/dimensions', { keys: [dimension], start_at, end_at, limit, [dimension]: params }).then(res => { + this.setState({ + loading: false, + data: res.data, + }); + }).catch(err => { + console.error(err); + }); + } + + render () { + const { label, limit } = this.props; + const { loading, data } = this.state; + + let content; + + if (loading) { + content = ( + + + {Array.from(Array(limit)).map((_, i) => ( + + + + + + ))} + +
+ + + +
+ ); + } else { + const sum = data[0].data.reduce((sum, cur) => sum + (cur.value * 1), 0); + + content = ( + + + {data[0].data.map(item => ( + + + + + + ))} + +
+ + {item.human_key} + + {typeof item.human_value !== 'undefined' ? item.human_value : } +
+ ); + } + + return ( +
+

{label}

+ + {content} +
+ ); + } + +} diff --git a/app/javascript/flavours/glitch/components/admin/ReportReasonSelector.js b/app/javascript/flavours/glitch/components/admin/ReportReasonSelector.js deleted file mode 100644 index 771dbb452..000000000 --- a/app/javascript/flavours/glitch/components/admin/ReportReasonSelector.js +++ /dev/null @@ -1,159 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import api from 'flavours/glitch/api'; -import { injectIntl, defineMessages } from 'react-intl'; -import classNames from 'classnames'; - -const messages = defineMessages({ - other: { id: 'report.categories.other', defaultMessage: 'Other' }, - spam: { id: 'report.categories.spam', defaultMessage: 'Spam' }, - violation: { id: 'report.categories.violation', defaultMessage: 'Content violates one or more server rules' }, -}); - -class Category extends React.PureComponent { - - static propTypes = { - id: PropTypes.string.isRequired, - text: PropTypes.string.isRequired, - selected: PropTypes.bool, - disabled: PropTypes.bool, - onSelect: PropTypes.func, - children: PropTypes.node, - }; - - handleClick = () => { - const { id, disabled, onSelect } = this.props; - - if (!disabled) { - onSelect(id); - } - }; - - render () { - const { id, text, disabled, selected, children } = this.props; - - return ( -
- {selected && } - -
- - {text} -
- - {(selected && children) && ( -
- {children} -
- )} -
- ); - } - -} - -class Rule extends React.PureComponent { - - static propTypes = { - id: PropTypes.string.isRequired, - text: PropTypes.string.isRequired, - selected: PropTypes.bool, - disabled: PropTypes.bool, - onToggle: PropTypes.func, - }; - - handleClick = () => { - const { id, disabled, onToggle } = this.props; - - if (!disabled) { - onToggle(id); - } - }; - - render () { - const { id, text, disabled, selected } = this.props; - - return ( -
- - {selected && } - {text} -
- ); - } - -} - -export default @injectIntl -class ReportReasonSelector extends React.PureComponent { - - static propTypes = { - id: PropTypes.string.isRequired, - category: PropTypes.string.isRequired, - rule_ids: PropTypes.arrayOf(PropTypes.string), - disabled: PropTypes.bool, - intl: PropTypes.object.isRequired, - }; - - state = { - category: this.props.category, - rule_ids: this.props.rule_ids || [], - rules: [], - }; - - componentDidMount() { - api().get('/api/v1/instance').then(res => { - this.setState({ - rules: res.data.rules, - }); - }).catch(err => { - console.error(err); - }); - } - - _save = () => { - const { id, disabled } = this.props; - const { category, rule_ids } = this.state; - - if (disabled) { - return; - } - - api().put(`/api/v1/admin/reports/${id}`, { - category, - rule_ids, - }).catch(err => { - console.error(err); - }); - }; - - handleSelect = id => { - this.setState({ category: id }, () => this._save()); - }; - - handleToggle = id => { - const { rule_ids } = this.state; - - if (rule_ids.includes(id)) { - this.setState({ rule_ids: rule_ids.filter(x => x !== id ) }, () => this._save()); - } else { - this.setState({ rule_ids: [...rule_ids, id] }, () => this._save()); - } - }; - - render () { - const { disabled, intl } = this.props; - const { rules, category, rule_ids } = this.state; - - return ( -
- - - - {rules.map(rule => )} - -
- ); - } - -} diff --git a/app/javascript/flavours/glitch/components/admin/ReportReasonSelector.jsx b/app/javascript/flavours/glitch/components/admin/ReportReasonSelector.jsx new file mode 100644 index 000000000..771dbb452 --- /dev/null +++ b/app/javascript/flavours/glitch/components/admin/ReportReasonSelector.jsx @@ -0,0 +1,159 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import api from 'flavours/glitch/api'; +import { injectIntl, defineMessages } from 'react-intl'; +import classNames from 'classnames'; + +const messages = defineMessages({ + other: { id: 'report.categories.other', defaultMessage: 'Other' }, + spam: { id: 'report.categories.spam', defaultMessage: 'Spam' }, + violation: { id: 'report.categories.violation', defaultMessage: 'Content violates one or more server rules' }, +}); + +class Category extends React.PureComponent { + + static propTypes = { + id: PropTypes.string.isRequired, + text: PropTypes.string.isRequired, + selected: PropTypes.bool, + disabled: PropTypes.bool, + onSelect: PropTypes.func, + children: PropTypes.node, + }; + + handleClick = () => { + const { id, disabled, onSelect } = this.props; + + if (!disabled) { + onSelect(id); + } + }; + + render () { + const { id, text, disabled, selected, children } = this.props; + + return ( +
+ {selected && } + +
+ + {text} +
+ + {(selected && children) && ( +
+ {children} +
+ )} +
+ ); + } + +} + +class Rule extends React.PureComponent { + + static propTypes = { + id: PropTypes.string.isRequired, + text: PropTypes.string.isRequired, + selected: PropTypes.bool, + disabled: PropTypes.bool, + onToggle: PropTypes.func, + }; + + handleClick = () => { + const { id, disabled, onToggle } = this.props; + + if (!disabled) { + onToggle(id); + } + }; + + render () { + const { id, text, disabled, selected } = this.props; + + return ( +
+ + {selected && } + {text} +
+ ); + } + +} + +export default @injectIntl +class ReportReasonSelector extends React.PureComponent { + + static propTypes = { + id: PropTypes.string.isRequired, + category: PropTypes.string.isRequired, + rule_ids: PropTypes.arrayOf(PropTypes.string), + disabled: PropTypes.bool, + intl: PropTypes.object.isRequired, + }; + + state = { + category: this.props.category, + rule_ids: this.props.rule_ids || [], + rules: [], + }; + + componentDidMount() { + api().get('/api/v1/instance').then(res => { + this.setState({ + rules: res.data.rules, + }); + }).catch(err => { + console.error(err); + }); + } + + _save = () => { + const { id, disabled } = this.props; + const { category, rule_ids } = this.state; + + if (disabled) { + return; + } + + api().put(`/api/v1/admin/reports/${id}`, { + category, + rule_ids, + }).catch(err => { + console.error(err); + }); + }; + + handleSelect = id => { + this.setState({ category: id }, () => this._save()); + }; + + handleToggle = id => { + const { rule_ids } = this.state; + + if (rule_ids.includes(id)) { + this.setState({ rule_ids: rule_ids.filter(x => x !== id ) }, () => this._save()); + } else { + this.setState({ rule_ids: [...rule_ids, id] }, () => this._save()); + } + }; + + render () { + const { disabled, intl } = this.props; + const { rules, category, rule_ids } = this.state; + + return ( +
+ + + + {rules.map(rule => )} + +
+ ); + } + +} diff --git a/app/javascript/flavours/glitch/components/admin/Retention.js b/app/javascript/flavours/glitch/components/admin/Retention.js deleted file mode 100644 index e1ba3f6c9..000000000 --- a/app/javascript/flavours/glitch/components/admin/Retention.js +++ /dev/null @@ -1,151 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import api from 'flavours/glitch/api'; -import { FormattedMessage, FormattedNumber, FormattedDate } from 'react-intl'; -import classNames from 'classnames'; -import { roundTo10 } from 'flavours/glitch/utils/numbers'; - -const dateForCohort = cohort => { - switch(cohort.frequency) { - case 'day': - return ; - default: - return ; - } -}; - -export default class Retention extends React.PureComponent { - - static propTypes = { - start_at: PropTypes.string, - end_at: PropTypes.string, - frequency: PropTypes.string, - }; - - state = { - loading: true, - data: null, - }; - - componentDidMount () { - const { start_at, end_at, frequency } = this.props; - - api().post('/api/v1/admin/retention', { start_at, end_at, frequency }).then(res => { - this.setState({ - loading: false, - data: res.data, - }); - }).catch(err => { - console.error(err); - }); - } - - render () { - const { loading, data } = this.state; - const { frequency } = this.props; - - let content; - - if (loading) { - content = ; - } else { - content = ( - - - - - - - - {data[0].data.slice(1).map((retention, i) => ( - - ))} - - - - - - - - {data[0].data.slice(1).map((retention, i) => { - const average = data.reduce((sum, cohort, k) => cohort.data[i + 1] ? sum + (cohort.data[i + 1].rate - sum)/(k + 1) : sum, 0); - - return ( - - ); - })} - - - - - {data.slice(0, -1).map(cohort => ( - - - - - - {cohort.data.slice(1).map(retention => ( - - ))} - - ))} - -
-
- -
-
-
- -
-
-
- {i + 1} -
-
-
- -
-
-
- sum + ((cohort.data[0].value * 1) - sum) / (i + 1), 0)} maximumFractionDigits={0} /> -
-
-
- -
-
-
- {dateForCohort(cohort)} -
-
-
- -
-
-
- -
-
- ); - } - - let title = null; - switch(frequency) { - case 'day': - title = ; - break; - default: - title = ; - } - - return ( -
-

{title}

- - {content} -
- ); - } - -} diff --git a/app/javascript/flavours/glitch/components/admin/Retention.jsx b/app/javascript/flavours/glitch/components/admin/Retention.jsx new file mode 100644 index 000000000..e1ba3f6c9 --- /dev/null +++ b/app/javascript/flavours/glitch/components/admin/Retention.jsx @@ -0,0 +1,151 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import api from 'flavours/glitch/api'; +import { FormattedMessage, FormattedNumber, FormattedDate } from 'react-intl'; +import classNames from 'classnames'; +import { roundTo10 } from 'flavours/glitch/utils/numbers'; + +const dateForCohort = cohort => { + switch(cohort.frequency) { + case 'day': + return ; + default: + return ; + } +}; + +export default class Retention extends React.PureComponent { + + static propTypes = { + start_at: PropTypes.string, + end_at: PropTypes.string, + frequency: PropTypes.string, + }; + + state = { + loading: true, + data: null, + }; + + componentDidMount () { + const { start_at, end_at, frequency } = this.props; + + api().post('/api/v1/admin/retention', { start_at, end_at, frequency }).then(res => { + this.setState({ + loading: false, + data: res.data, + }); + }).catch(err => { + console.error(err); + }); + } + + render () { + const { loading, data } = this.state; + const { frequency } = this.props; + + let content; + + if (loading) { + content = ; + } else { + content = ( + + + + + + + + {data[0].data.slice(1).map((retention, i) => ( + + ))} + + + + + + + + {data[0].data.slice(1).map((retention, i) => { + const average = data.reduce((sum, cohort, k) => cohort.data[i + 1] ? sum + (cohort.data[i + 1].rate - sum)/(k + 1) : sum, 0); + + return ( + + ); + })} + + + + + {data.slice(0, -1).map(cohort => ( + + + + + + {cohort.data.slice(1).map(retention => ( + + ))} + + ))} + +
+
+ +
+
+
+ +
+
+
+ {i + 1} +
+
+
+ +
+
+
+ sum + ((cohort.data[0].value * 1) - sum) / (i + 1), 0)} maximumFractionDigits={0} /> +
+
+
+ +
+
+
+ {dateForCohort(cohort)} +
+
+
+ +
+
+
+ +
+
+ ); + } + + let title = null; + switch(frequency) { + case 'day': + title = ; + break; + default: + title = ; + } + + return ( +
+

{title}

+ + {content} +
+ ); + } + +} diff --git a/app/javascript/flavours/glitch/components/admin/Trends.js b/app/javascript/flavours/glitch/components/admin/Trends.js deleted file mode 100644 index 774bf36e6..000000000 --- a/app/javascript/flavours/glitch/components/admin/Trends.js +++ /dev/null @@ -1,73 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import api from 'flavours/glitch/api'; -import { FormattedMessage } from 'react-intl'; -import classNames from 'classnames'; -import Hashtag from 'flavours/glitch/components/hashtag'; - -export default class Trends extends React.PureComponent { - - static propTypes = { - limit: PropTypes.number.isRequired, - }; - - state = { - loading: true, - data: null, - }; - - componentDidMount () { - const { limit } = this.props; - - api().get('/api/v1/admin/trends/tags', { params: { limit } }).then(res => { - this.setState({ - loading: false, - data: res.data, - }); - }).catch(err => { - console.error(err); - }); - } - - render () { - const { limit } = this.props; - const { loading, data } = this.state; - - let content; - - if (loading) { - content = ( -
- {Array.from(Array(limit)).map((_, i) => ( - - ))} -
- ); - } else { - content = ( -
- {data.map(hashtag => ( - day.uses)} - className={classNames(hashtag.requires_review && 'trends__item--requires-review', !hashtag.trendable && !hashtag.requires_review && 'trends__item--disabled')} - /> - ))} -
- ); - } - - return ( -
-

- - {content} -
- ); - } - -} diff --git a/app/javascript/flavours/glitch/components/admin/Trends.jsx b/app/javascript/flavours/glitch/components/admin/Trends.jsx new file mode 100644 index 000000000..774bf36e6 --- /dev/null +++ b/app/javascript/flavours/glitch/components/admin/Trends.jsx @@ -0,0 +1,73 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import api from 'flavours/glitch/api'; +import { FormattedMessage } from 'react-intl'; +import classNames from 'classnames'; +import Hashtag from 'flavours/glitch/components/hashtag'; + +export default class Trends extends React.PureComponent { + + static propTypes = { + limit: PropTypes.number.isRequired, + }; + + state = { + loading: true, + data: null, + }; + + componentDidMount () { + const { limit } = this.props; + + api().get('/api/v1/admin/trends/tags', { params: { limit } }).then(res => { + this.setState({ + loading: false, + data: res.data, + }); + }).catch(err => { + console.error(err); + }); + } + + render () { + const { limit } = this.props; + const { loading, data } = this.state; + + let content; + + if (loading) { + content = ( +
+ {Array.from(Array(limit)).map((_, i) => ( + + ))} +
+ ); + } else { + content = ( +
+ {data.map(hashtag => ( + day.uses)} + className={classNames(hashtag.requires_review && 'trends__item--requires-review', !hashtag.trendable && !hashtag.requires_review && 'trends__item--disabled')} + /> + ))} +
+ ); + } + + return ( +
+

+ + {content} +
+ ); + } + +} diff --git a/app/javascript/flavours/glitch/components/animated_number.js b/app/javascript/flavours/glitch/components/animated_number.js deleted file mode 100644 index dd21d97f0..000000000 --- a/app/javascript/flavours/glitch/components/animated_number.js +++ /dev/null @@ -1,76 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import ShortNumber from 'mastodon/components/short_number'; -import TransitionMotion from 'react-motion/lib/TransitionMotion'; -import spring from 'react-motion/lib/spring'; -import { reduceMotion } from 'flavours/glitch/initial_state'; - -const obfuscatedCount = count => { - if (count < 0) { - return 0; - } else if (count <= 1) { - return count; - } else { - return '1+'; - } -}; - -export default class AnimatedNumber extends React.PureComponent { - - static propTypes = { - value: PropTypes.number.isRequired, - obfuscate: PropTypes.bool, - }; - - state = { - direction: 1, - }; - - componentWillReceiveProps (nextProps) { - if (nextProps.value > this.props.value) { - this.setState({ direction: 1 }); - } else if (nextProps.value < this.props.value) { - this.setState({ direction: -1 }); - } - } - - willEnter = () => { - const { direction } = this.state; - - return { y: -1 * direction }; - }; - - willLeave = () => { - const { direction } = this.state; - - return { y: spring(1 * direction, { damping: 35, stiffness: 400 }) }; - }; - - render () { - const { value, obfuscate } = this.props; - const { direction } = this.state; - - if (reduceMotion) { - return obfuscate ? obfuscatedCount(value) : ; - } - - const styles = [{ - key: `${value}`, - data: value, - style: { y: spring(0, { damping: 35, stiffness: 400 }) }, - }]; - - return ( - - {items => ( - - {items.map(({ key, data, style }) => ( - 0 ? 'absolute' : 'static', transform: `translateY(${style.y * 100}%)` }}>{obfuscate ? obfuscatedCount(data) : } - ))} - - )} - - ); - } - -} diff --git a/app/javascript/flavours/glitch/components/animated_number.jsx b/app/javascript/flavours/glitch/components/animated_number.jsx new file mode 100644 index 000000000..dd21d97f0 --- /dev/null +++ b/app/javascript/flavours/glitch/components/animated_number.jsx @@ -0,0 +1,76 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import ShortNumber from 'mastodon/components/short_number'; +import TransitionMotion from 'react-motion/lib/TransitionMotion'; +import spring from 'react-motion/lib/spring'; +import { reduceMotion } from 'flavours/glitch/initial_state'; + +const obfuscatedCount = count => { + if (count < 0) { + return 0; + } else if (count <= 1) { + return count; + } else { + return '1+'; + } +}; + +export default class AnimatedNumber extends React.PureComponent { + + static propTypes = { + value: PropTypes.number.isRequired, + obfuscate: PropTypes.bool, + }; + + state = { + direction: 1, + }; + + componentWillReceiveProps (nextProps) { + if (nextProps.value > this.props.value) { + this.setState({ direction: 1 }); + } else if (nextProps.value < this.props.value) { + this.setState({ direction: -1 }); + } + } + + willEnter = () => { + const { direction } = this.state; + + return { y: -1 * direction }; + }; + + willLeave = () => { + const { direction } = this.state; + + return { y: spring(1 * direction, { damping: 35, stiffness: 400 }) }; + }; + + render () { + const { value, obfuscate } = this.props; + const { direction } = this.state; + + if (reduceMotion) { + return obfuscate ? obfuscatedCount(value) : ; + } + + const styles = [{ + key: `${value}`, + data: value, + style: { y: spring(0, { damping: 35, stiffness: 400 }) }, + }]; + + return ( + + {items => ( + + {items.map(({ key, data, style }) => ( + 0 ? 'absolute' : 'static', transform: `translateY(${style.y * 100}%)` }}>{obfuscate ? obfuscatedCount(data) : } + ))} + + )} + + ); + } + +} diff --git a/app/javascript/flavours/glitch/components/attachment_list.js b/app/javascript/flavours/glitch/components/attachment_list.js deleted file mode 100644 index 68b80b19f..000000000 --- a/app/javascript/flavours/glitch/components/attachment_list.js +++ /dev/null @@ -1,48 +0,0 @@ -import React from 'react'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import PropTypes from 'prop-types'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import { FormattedMessage } from 'react-intl'; -import classNames from 'classnames'; -import Icon from 'flavours/glitch/components/icon'; - -const filename = url => url.split('/').pop().split('#')[0].split('?')[0]; - -export default class AttachmentList extends ImmutablePureComponent { - - static propTypes = { - media: ImmutablePropTypes.list.isRequired, - compact: PropTypes.bool, - }; - - render () { - const { media, compact } = this.props; - - return ( -
- {!compact && ( -
- -
- )} - - -
- ); - } - -} diff --git a/app/javascript/flavours/glitch/components/attachment_list.jsx b/app/javascript/flavours/glitch/components/attachment_list.jsx new file mode 100644 index 000000000..68b80b19f --- /dev/null +++ b/app/javascript/flavours/glitch/components/attachment_list.jsx @@ -0,0 +1,48 @@ +import React from 'react'; +import ImmutablePropTypes from 'react-immutable-proptypes'; +import PropTypes from 'prop-types'; +import ImmutablePureComponent from 'react-immutable-pure-component'; +import { FormattedMessage } from 'react-intl'; +import classNames from 'classnames'; +import Icon from 'flavours/glitch/components/icon'; + +const filename = url => url.split('/').pop().split('#')[0].split('?')[0]; + +export default class AttachmentList extends ImmutablePureComponent { + + static propTypes = { + media: ImmutablePropTypes.list.isRequired, + compact: PropTypes.bool, + }; + + render () { + const { media, compact } = this.props; + + return ( +
+ {!compact && ( +
+ +
+ )} + + +
+ ); + } + +} diff --git a/app/javascript/flavours/glitch/components/autosuggest_emoji.js b/app/javascript/flavours/glitch/components/autosuggest_emoji.js deleted file mode 100644 index 83fafbd10..000000000 --- a/app/javascript/flavours/glitch/components/autosuggest_emoji.js +++ /dev/null @@ -1,42 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import unicodeMapping from 'flavours/glitch/features/emoji/emoji_unicode_mapping_light'; - -import { assetHost } from 'flavours/glitch/utils/config'; - -export default class AutosuggestEmoji extends React.PureComponent { - - static propTypes = { - emoji: PropTypes.object.isRequired, - }; - - render () { - const { emoji } = this.props; - let url; - - if (emoji.custom) { - url = emoji.imageUrl; - } else { - const mapping = unicodeMapping[emoji.native] || unicodeMapping[emoji.native.replace(/\uFE0F$/, '')]; - - if (!mapping) { - return null; - } - - url = `${assetHost}/emoji/${mapping.filename}.svg`; - } - - return ( -
- {emoji.native - - {emoji.colons} -
- ); - } - -} diff --git a/app/javascript/flavours/glitch/components/autosuggest_emoji.jsx b/app/javascript/flavours/glitch/components/autosuggest_emoji.jsx new file mode 100644 index 000000000..83fafbd10 --- /dev/null +++ b/app/javascript/flavours/glitch/components/autosuggest_emoji.jsx @@ -0,0 +1,42 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import unicodeMapping from 'flavours/glitch/features/emoji/emoji_unicode_mapping_light'; + +import { assetHost } from 'flavours/glitch/utils/config'; + +export default class AutosuggestEmoji extends React.PureComponent { + + static propTypes = { + emoji: PropTypes.object.isRequired, + }; + + render () { + const { emoji } = this.props; + let url; + + if (emoji.custom) { + url = emoji.imageUrl; + } else { + const mapping = unicodeMapping[emoji.native] || unicodeMapping[emoji.native.replace(/\uFE0F$/, '')]; + + if (!mapping) { + return null; + } + + url = `${assetHost}/emoji/${mapping.filename}.svg`; + } + + return ( +
+ {emoji.native + + {emoji.colons} +
+ ); + } + +} diff --git a/app/javascript/flavours/glitch/components/autosuggest_hashtag.js b/app/javascript/flavours/glitch/components/autosuggest_hashtag.js deleted file mode 100644 index d787ed07a..000000000 --- a/app/javascript/flavours/glitch/components/autosuggest_hashtag.js +++ /dev/null @@ -1,42 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import ShortNumber from 'flavours/glitch/components/short_number'; -import { FormattedMessage } from 'react-intl'; - -export default class AutosuggestHashtag extends React.PureComponent { - - static propTypes = { - tag: PropTypes.shape({ - name: PropTypes.string.isRequired, - url: PropTypes.string, - history: PropTypes.array, - }).isRequired, - }; - - render() { - const { tag } = this.props; - const weeklyUses = tag.history && ( - total + day.uses * 1, 0)} - /> - ); - - return ( -
-
- #{tag.name} -
- {tag.history !== undefined && ( -
- -
- )} -
- ); - } - -} diff --git a/app/javascript/flavours/glitch/components/autosuggest_hashtag.jsx b/app/javascript/flavours/glitch/components/autosuggest_hashtag.jsx new file mode 100644 index 000000000..d787ed07a --- /dev/null +++ b/app/javascript/flavours/glitch/components/autosuggest_hashtag.jsx @@ -0,0 +1,42 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import ShortNumber from 'flavours/glitch/components/short_number'; +import { FormattedMessage } from 'react-intl'; + +export default class AutosuggestHashtag extends React.PureComponent { + + static propTypes = { + tag: PropTypes.shape({ + name: PropTypes.string.isRequired, + url: PropTypes.string, + history: PropTypes.array, + }).isRequired, + }; + + render() { + const { tag } = this.props; + const weeklyUses = tag.history && ( + total + day.uses * 1, 0)} + /> + ); + + return ( +
+
+ #{tag.name} +
+ {tag.history !== undefined && ( +
+ +
+ )} +
+ ); + } + +} diff --git a/app/javascript/flavours/glitch/components/autosuggest_input.js b/app/javascript/flavours/glitch/components/autosuggest_input.js deleted file mode 100644 index 90ff298c0..000000000 --- a/app/javascript/flavours/glitch/components/autosuggest_input.js +++ /dev/null @@ -1,227 +0,0 @@ -import React from 'react'; -import AutosuggestAccountContainer from 'flavours/glitch/features/compose/containers/autosuggest_account_container'; -import AutosuggestEmoji from './autosuggest_emoji'; -import AutosuggestHashtag from './autosuggest_hashtag'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import PropTypes from 'prop-types'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import classNames from 'classnames'; - -const textAtCursorMatchesToken = (str, caretPosition, searchTokens) => { - let word; - - let left = str.slice(0, caretPosition).search(/[^\s\u200B]+$/); - let right = str.slice(caretPosition).search(/[\s\u200B]/); - - if (right < 0) { - word = str.slice(left); - } else { - word = str.slice(left, right + caretPosition); - } - - if (!word || word.trim().length < 3 || searchTokens.indexOf(word[0]) === -1) { - return [null, null]; - } - - word = word.trim().toLowerCase(); - - if (word.length > 0) { - return [left, word]; - } else { - return [null, null]; - } -}; - -export default class AutosuggestInput extends ImmutablePureComponent { - - static propTypes = { - value: PropTypes.string, - suggestions: ImmutablePropTypes.list, - disabled: PropTypes.bool, - placeholder: PropTypes.string, - onSuggestionSelected: PropTypes.func.isRequired, - onSuggestionsClearRequested: PropTypes.func.isRequired, - onSuggestionsFetchRequested: PropTypes.func.isRequired, - onChange: PropTypes.func.isRequired, - onKeyUp: PropTypes.func, - onKeyDown: PropTypes.func, - autoFocus: PropTypes.bool, - className: PropTypes.string, - id: PropTypes.string, - searchTokens: PropTypes.arrayOf(PropTypes.string), - maxLength: PropTypes.number, - lang: PropTypes.string, - spellCheck: PropTypes.bool, - }; - - static defaultProps = { - autoFocus: true, - searchTokens: ['@', ':', '#'], - }; - - state = { - suggestionsHidden: true, - focused: false, - selectedSuggestion: 0, - lastToken: null, - tokenStart: 0, - }; - - onChange = (e) => { - const [ tokenStart, token ] = textAtCursorMatchesToken(e.target.value, e.target.selectionStart, this.props.searchTokens); - - if (token !== null && this.state.lastToken !== token) { - this.setState({ lastToken: token, selectedSuggestion: 0, tokenStart }); - this.props.onSuggestionsFetchRequested(token); - } else if (token === null) { - this.setState({ lastToken: null }); - this.props.onSuggestionsClearRequested(); - } - - this.props.onChange(e); - }; - - onKeyDown = (e) => { - const { suggestions, disabled } = this.props; - const { selectedSuggestion, suggestionsHidden } = this.state; - - if (disabled) { - e.preventDefault(); - return; - } - - if (e.which === 229 || e.isComposing) { - // Ignore key events during text composition - // e.key may be a name of the physical key even in this case (e.x. Safari / Chrome on Mac) - return; - } - - switch(e.key) { - case 'Escape': - if (suggestions.size === 0 || suggestionsHidden) { - document.querySelector('.ui').parentElement.focus(); - } else { - e.preventDefault(); - this.setState({ suggestionsHidden: true }); - } - - break; - case 'ArrowDown': - if (suggestions.size > 0 && !suggestionsHidden) { - e.preventDefault(); - this.setState({ selectedSuggestion: Math.min(selectedSuggestion + 1, suggestions.size - 1) }); - } - - break; - case 'ArrowUp': - if (suggestions.size > 0 && !suggestionsHidden) { - e.preventDefault(); - this.setState({ selectedSuggestion: Math.max(selectedSuggestion - 1, 0) }); - } - - break; - case 'Enter': - case 'Tab': - // Select suggestion - if (this.state.lastToken !== null && suggestions.size > 0 && !suggestionsHidden) { - e.preventDefault(); - e.stopPropagation(); - this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestions.get(selectedSuggestion)); - } - - break; - } - - if (e.defaultPrevented || !this.props.onKeyDown) { - return; - } - - this.props.onKeyDown(e); - }; - - onBlur = () => { - this.setState({ suggestionsHidden: true, focused: false }); - }; - - onFocus = () => { - this.setState({ focused: true }); - }; - - onSuggestionClick = (e) => { - const suggestion = this.props.suggestions.get(e.currentTarget.getAttribute('data-index')); - e.preventDefault(); - this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestion); - this.input.focus(); - }; - - componentWillReceiveProps (nextProps) { - if (nextProps.suggestions !== this.props.suggestions && nextProps.suggestions.size > 0 && this.state.suggestionsHidden && this.state.focused) { - this.setState({ suggestionsHidden: false }); - } - } - - setInput = (c) => { - this.input = c; - }; - - renderSuggestion = (suggestion, i) => { - const { selectedSuggestion } = this.state; - let inner, key; - - if (suggestion.type === 'emoji') { - inner = ; - key = suggestion.id; - } else if (suggestion.type ==='hashtag') { - inner = ; - key = suggestion.name; - } else if (suggestion.type === 'account') { - inner = ; - key = suggestion.id; - } - - return ( -
- {inner} -
- ); - }; - - render () { - const { value, suggestions, disabled, placeholder, onKeyUp, autoFocus, className, id, maxLength, lang, spellCheck } = this.props; - const { suggestionsHidden } = this.state; - - return ( -
- - -
- {suggestions.map(this.renderSuggestion)} -
-
- ); - } - -} diff --git a/app/javascript/flavours/glitch/components/autosuggest_input.jsx b/app/javascript/flavours/glitch/components/autosuggest_input.jsx new file mode 100644 index 000000000..90ff298c0 --- /dev/null +++ b/app/javascript/flavours/glitch/components/autosuggest_input.jsx @@ -0,0 +1,227 @@ +import React from 'react'; +import AutosuggestAccountContainer from 'flavours/glitch/features/compose/containers/autosuggest_account_container'; +import AutosuggestEmoji from './autosuggest_emoji'; +import AutosuggestHashtag from './autosuggest_hashtag'; +import ImmutablePropTypes from 'react-immutable-proptypes'; +import PropTypes from 'prop-types'; +import ImmutablePureComponent from 'react-immutable-pure-component'; +import classNames from 'classnames'; + +const textAtCursorMatchesToken = (str, caretPosition, searchTokens) => { + let word; + + let left = str.slice(0, caretPosition).search(/[^\s\u200B]+$/); + let right = str.slice(caretPosition).search(/[\s\u200B]/); + + if (right < 0) { + word = str.slice(left); + } else { + word = str.slice(left, right + caretPosition); + } + + if (!word || word.trim().length < 3 || searchTokens.indexOf(word[0]) === -1) { + return [null, null]; + } + + word = word.trim().toLowerCase(); + + if (word.length > 0) { + return [left, word]; + } else { + return [null, null]; + } +}; + +export default class AutosuggestInput extends ImmutablePureComponent { + + static propTypes = { + value: PropTypes.string, + suggestions: ImmutablePropTypes.list, + disabled: PropTypes.bool, + placeholder: PropTypes.string, + onSuggestionSelected: PropTypes.func.isRequired, + onSuggestionsClearRequested: PropTypes.func.isRequired, + onSuggestionsFetchRequested: PropTypes.func.isRequired, + onChange: PropTypes.func.isRequired, + onKeyUp: PropTypes.func, + onKeyDown: PropTypes.func, + autoFocus: PropTypes.bool, + className: PropTypes.string, + id: PropTypes.string, + searchTokens: PropTypes.arrayOf(PropTypes.string), + maxLength: PropTypes.number, + lang: PropTypes.string, + spellCheck: PropTypes.bool, + }; + + static defaultProps = { + autoFocus: true, + searchTokens: ['@', ':', '#'], + }; + + state = { + suggestionsHidden: true, + focused: false, + selectedSuggestion: 0, + lastToken: null, + tokenStart: 0, + }; + + onChange = (e) => { + const [ tokenStart, token ] = textAtCursorMatchesToken(e.target.value, e.target.selectionStart, this.props.searchTokens); + + if (token !== null && this.state.lastToken !== token) { + this.setState({ lastToken: token, selectedSuggestion: 0, tokenStart }); + this.props.onSuggestionsFetchRequested(token); + } else if (token === null) { + this.setState({ lastToken: null }); + this.props.onSuggestionsClearRequested(); + } + + this.props.onChange(e); + }; + + onKeyDown = (e) => { + const { suggestions, disabled } = this.props; + const { selectedSuggestion, suggestionsHidden } = this.state; + + if (disabled) { + e.preventDefault(); + return; + } + + if (e.which === 229 || e.isComposing) { + // Ignore key events during text composition + // e.key may be a name of the physical key even in this case (e.x. Safari / Chrome on Mac) + return; + } + + switch(e.key) { + case 'Escape': + if (suggestions.size === 0 || suggestionsHidden) { + document.querySelector('.ui').parentElement.focus(); + } else { + e.preventDefault(); + this.setState({ suggestionsHidden: true }); + } + + break; + case 'ArrowDown': + if (suggestions.size > 0 && !suggestionsHidden) { + e.preventDefault(); + this.setState({ selectedSuggestion: Math.min(selectedSuggestion + 1, suggestions.size - 1) }); + } + + break; + case 'ArrowUp': + if (suggestions.size > 0 && !suggestionsHidden) { + e.preventDefault(); + this.setState({ selectedSuggestion: Math.max(selectedSuggestion - 1, 0) }); + } + + break; + case 'Enter': + case 'Tab': + // Select suggestion + if (this.state.lastToken !== null && suggestions.size > 0 && !suggestionsHidden) { + e.preventDefault(); + e.stopPropagation(); + this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestions.get(selectedSuggestion)); + } + + break; + } + + if (e.defaultPrevented || !this.props.onKeyDown) { + return; + } + + this.props.onKeyDown(e); + }; + + onBlur = () => { + this.setState({ suggestionsHidden: true, focused: false }); + }; + + onFocus = () => { + this.setState({ focused: true }); + }; + + onSuggestionClick = (e) => { + const suggestion = this.props.suggestions.get(e.currentTarget.getAttribute('data-index')); + e.preventDefault(); + this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestion); + this.input.focus(); + }; + + componentWillReceiveProps (nextProps) { + if (nextProps.suggestions !== this.props.suggestions && nextProps.suggestions.size > 0 && this.state.suggestionsHidden && this.state.focused) { + this.setState({ suggestionsHidden: false }); + } + } + + setInput = (c) => { + this.input = c; + }; + + renderSuggestion = (suggestion, i) => { + const { selectedSuggestion } = this.state; + let inner, key; + + if (suggestion.type === 'emoji') { + inner = ; + key = suggestion.id; + } else if (suggestion.type ==='hashtag') { + inner = ; + key = suggestion.name; + } else if (suggestion.type === 'account') { + inner = ; + key = suggestion.id; + } + + return ( +
+ {inner} +
+ ); + }; + + render () { + const { value, suggestions, disabled, placeholder, onKeyUp, autoFocus, className, id, maxLength, lang, spellCheck } = this.props; + const { suggestionsHidden } = this.state; + + return ( +
+ + +
+ {suggestions.map(this.renderSuggestion)} +
+
+ ); + } + +} diff --git a/app/javascript/flavours/glitch/components/autosuggest_textarea.js b/app/javascript/flavours/glitch/components/autosuggest_textarea.js deleted file mode 100644 index 6e6e567b9..000000000 --- a/app/javascript/flavours/glitch/components/autosuggest_textarea.js +++ /dev/null @@ -1,235 +0,0 @@ -import React from 'react'; -import AutosuggestAccountContainer from 'flavours/glitch/features/compose/containers/autosuggest_account_container'; -import AutosuggestEmoji from './autosuggest_emoji'; -import AutosuggestHashtag from './autosuggest_hashtag'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import PropTypes from 'prop-types'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import Textarea from 'react-textarea-autosize'; -import classNames from 'classnames'; - -const textAtCursorMatchesToken = (str, caretPosition) => { - let word; - - let left = str.slice(0, caretPosition).search(/[^\s\u200B]+$/); - let right = str.slice(caretPosition).search(/[\s\u200B]/); - - if (right < 0) { - word = str.slice(left); - } else { - word = str.slice(left, right + caretPosition); - } - - if (!word || word.trim().length < 3 || ['@', ':', '#'].indexOf(word[0]) === -1) { - return [null, null]; - } - - word = word.trim().toLowerCase(); - - if (word.length > 0) { - return [left, word]; - } else { - return [null, null]; - } -}; - -export default class AutosuggestTextarea extends ImmutablePureComponent { - - static propTypes = { - value: PropTypes.string, - suggestions: ImmutablePropTypes.list, - disabled: PropTypes.bool, - placeholder: PropTypes.string, - onSuggestionSelected: PropTypes.func.isRequired, - onSuggestionsClearRequested: PropTypes.func.isRequired, - onSuggestionsFetchRequested: PropTypes.func.isRequired, - onChange: PropTypes.func.isRequired, - onKeyUp: PropTypes.func, - onKeyDown: PropTypes.func, - onPaste: PropTypes.func.isRequired, - autoFocus: PropTypes.bool, - lang: PropTypes.string, - }; - - static defaultProps = { - autoFocus: true, - }; - - state = { - suggestionsHidden: true, - focused: false, - selectedSuggestion: 0, - lastToken: null, - tokenStart: 0, - }; - - onChange = (e) => { - const [ tokenStart, token ] = textAtCursorMatchesToken(e.target.value, e.target.selectionStart); - - if (token !== null && this.state.lastToken !== token) { - this.setState({ lastToken: token, selectedSuggestion: 0, tokenStart }); - this.props.onSuggestionsFetchRequested(token); - } else if (token === null) { - this.setState({ lastToken: null }); - this.props.onSuggestionsClearRequested(); - } - - this.props.onChange(e); - }; - - onKeyDown = (e) => { - const { suggestions, disabled } = this.props; - const { selectedSuggestion, suggestionsHidden } = this.state; - - if (disabled) { - e.preventDefault(); - return; - } - - if (e.which === 229 || e.isComposing) { - // Ignore key events during text composition - // e.key may be a name of the physical key even in this case (e.x. Safari / Chrome on Mac) - return; - } - - switch(e.key) { - case 'Escape': - if (suggestions.size === 0 || suggestionsHidden) { - document.querySelector('.ui').parentElement.focus(); - } else { - e.preventDefault(); - this.setState({ suggestionsHidden: true }); - } - - break; - case 'ArrowDown': - if (suggestions.size > 0 && !suggestionsHidden) { - e.preventDefault(); - this.setState({ selectedSuggestion: Math.min(selectedSuggestion + 1, suggestions.size - 1) }); - } - - break; - case 'ArrowUp': - if (suggestions.size > 0 && !suggestionsHidden) { - e.preventDefault(); - this.setState({ selectedSuggestion: Math.max(selectedSuggestion - 1, 0) }); - } - - break; - case 'Enter': - case 'Tab': - // Select suggestion - if (this.state.lastToken !== null && suggestions.size > 0 && !suggestionsHidden) { - e.preventDefault(); - e.stopPropagation(); - this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestions.get(selectedSuggestion)); - } - - break; - } - - if (e.defaultPrevented || !this.props.onKeyDown) { - return; - } - - this.props.onKeyDown(e); - }; - - onBlur = () => { - this.setState({ suggestionsHidden: true, focused: false }); - }; - - onFocus = (e) => { - this.setState({ focused: true }); - if (this.props.onFocus) { - this.props.onFocus(e); - } - }; - - onSuggestionClick = (e) => { - const suggestion = this.props.suggestions.get(e.currentTarget.getAttribute('data-index')); - e.preventDefault(); - this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestion); - this.textarea.focus(); - }; - - componentWillReceiveProps (nextProps) { - if (nextProps.suggestions !== this.props.suggestions && nextProps.suggestions.size > 0 && this.state.suggestionsHidden && this.state.focused) { - this.setState({ suggestionsHidden: false }); - } - } - - setTextarea = (c) => { - this.textarea = c; - }; - - onPaste = (e) => { - if (e.clipboardData && e.clipboardData.files.length === 1) { - this.props.onPaste(e.clipboardData.files); - e.preventDefault(); - } - }; - - renderSuggestion = (suggestion, i) => { - const { selectedSuggestion } = this.state; - let inner, key; - - if (suggestion.type === 'emoji') { - inner = ; - key = suggestion.id; - } else if (suggestion.type === 'hashtag') { - inner = ; - key = suggestion.name; - } else if (suggestion.type === 'account') { - inner = ; - key = suggestion.id; - } - - return ( -
- {inner} -
- ); - }; - - render () { - const { value, suggestions, disabled, placeholder, onKeyUp, autoFocus, lang, children } = this.props; - const { suggestionsHidden } = this.state; - - return [ -
-
-