diff --git a/README.md b/README.md index 07ba0d7a7..754e68d4c 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,8 @@ busybox unzip soapbox.zip -o -d /opt/pleroma/instance The change will take effect immediately, just refresh your browser tab. It's not necessary to restart the Pleroma service. +***For OTP releases,*** *unpack to /var/lib/pleroma instead.* + To remove Soapbox and revert to the default pleroma-fe, simply `rm /opt/pleroma/instance/static/index.html` (you can delete other stuff in there too, but be careful not to delete your own HTML files). ## :elephant: Deploy on Mastodon diff --git a/app/application.ts b/app/application.ts index 38dc08993..9610b4f9a 100644 --- a/app/application.ts +++ b/app/application.ts @@ -1,10 +1,10 @@ -import loadPolyfills from './soapbox/load_polyfills'; +import loadPolyfills from './soapbox/load-polyfills'; // Load iframe event listener require('./soapbox/iframe'); // @ts-ignore -require.context('./images/', true); +require.context('./assets/images/', true); // Load stylesheet require('react-datepicker/dist/react-datepicker.css'); diff --git a/app/fonts/OpenDyslexic/LICENSE b/app/assets/fonts/OpenDyslexic/LICENSE similarity index 100% rename from app/fonts/OpenDyslexic/LICENSE rename to app/assets/fonts/OpenDyslexic/LICENSE diff --git a/app/fonts/OpenDyslexic/OpenDyslexic-Bold-Italic.woff2 b/app/assets/fonts/OpenDyslexic/OpenDyslexic-Bold-Italic.woff2 similarity index 100% rename from app/fonts/OpenDyslexic/OpenDyslexic-Bold-Italic.woff2 rename to app/assets/fonts/OpenDyslexic/OpenDyslexic-Bold-Italic.woff2 diff --git a/app/fonts/OpenDyslexic/OpenDyslexic-Bold.woff2 b/app/assets/fonts/OpenDyslexic/OpenDyslexic-Bold.woff2 similarity index 100% rename from app/fonts/OpenDyslexic/OpenDyslexic-Bold.woff2 rename to app/assets/fonts/OpenDyslexic/OpenDyslexic-Bold.woff2 diff --git a/app/fonts/OpenDyslexic/OpenDyslexic-Italic.woff2 b/app/assets/fonts/OpenDyslexic/OpenDyslexic-Italic.woff2 similarity index 100% rename from app/fonts/OpenDyslexic/OpenDyslexic-Italic.woff2 rename to app/assets/fonts/OpenDyslexic/OpenDyslexic-Italic.woff2 diff --git a/app/fonts/OpenDyslexic/OpenDyslexic-Regular.woff2 b/app/assets/fonts/OpenDyslexic/OpenDyslexic-Regular.woff2 similarity index 100% rename from app/fonts/OpenDyslexic/OpenDyslexic-Regular.woff2 rename to app/assets/fonts/OpenDyslexic/OpenDyslexic-Regular.woff2 diff --git a/app/fonts/soapbox/soapbox.eot b/app/assets/fonts/soapbox/soapbox.eot similarity index 100% rename from app/fonts/soapbox/soapbox.eot rename to app/assets/fonts/soapbox/soapbox.eot diff --git a/app/fonts/soapbox/soapbox.svg b/app/assets/fonts/soapbox/soapbox.svg similarity index 100% rename from app/fonts/soapbox/soapbox.svg rename to app/assets/fonts/soapbox/soapbox.svg diff --git a/app/fonts/soapbox/soapbox.ttf b/app/assets/fonts/soapbox/soapbox.ttf similarity index 100% rename from app/fonts/soapbox/soapbox.ttf rename to app/assets/fonts/soapbox/soapbox.ttf diff --git a/app/fonts/soapbox/soapbox.woff b/app/assets/fonts/soapbox/soapbox.woff similarity index 100% rename from app/fonts/soapbox/soapbox.woff rename to app/assets/fonts/soapbox/soapbox.woff diff --git a/app/icons/COPYING.md b/app/assets/icons/COPYING.md similarity index 100% rename from app/icons/COPYING.md rename to app/assets/icons/COPYING.md diff --git a/app/icons/fediverse.svg b/app/assets/icons/fediverse.svg similarity index 100% rename from app/icons/fediverse.svg rename to app/assets/icons/fediverse.svg diff --git a/app/icons/verified.svg b/app/assets/icons/verified.svg similarity index 100% rename from app/icons/verified.svg rename to app/assets/icons/verified.svg diff --git a/app/images/audio-placeholder.png b/app/assets/images/audio-placeholder.png similarity index 100% rename from app/images/audio-placeholder.png rename to app/assets/images/audio-placeholder.png diff --git a/app/images/avatar-missing.png b/app/assets/images/avatar-missing.png similarity index 100% rename from app/images/avatar-missing.png rename to app/assets/images/avatar-missing.png diff --git a/app/images/avatar-missing.svg b/app/assets/images/avatar-missing.svg similarity index 100% rename from app/images/avatar-missing.svg rename to app/assets/images/avatar-missing.svg diff --git a/app/images/header-missing.png b/app/assets/images/header-missing.png similarity index 100% rename from app/images/header-missing.png rename to app/assets/images/header-missing.png diff --git a/app/images/soapbox-logo-white.svg b/app/assets/images/soapbox-logo-white.svg similarity index 100% rename from app/images/soapbox-logo-white.svg rename to app/assets/images/soapbox-logo-white.svg diff --git a/app/images/soapbox-logo.svg b/app/assets/images/soapbox-logo.svg similarity index 100% rename from app/images/soapbox-logo.svg rename to app/assets/images/soapbox-logo.svg diff --git a/app/images/video-placeholder.png b/app/assets/images/video-placeholder.png similarity index 100% rename from app/images/video-placeholder.png rename to app/assets/images/video-placeholder.png diff --git a/app/images/void.png b/app/assets/images/void.png similarity index 100% rename from app/images/void.png rename to app/assets/images/void.png diff --git a/app/images/web-push/web-push-icon_expand.png b/app/assets/images/web-push/web-push-icon_expand.png similarity index 100% rename from app/images/web-push/web-push-icon_expand.png rename to app/assets/images/web-push/web-push-icon_expand.png diff --git a/app/images/web-push/web-push-icon_favourite.png b/app/assets/images/web-push/web-push-icon_favourite.png similarity index 100% rename from app/images/web-push/web-push-icon_favourite.png rename to app/assets/images/web-push/web-push-icon_favourite.png diff --git a/app/images/web-push/web-push-icon_reblog.png b/app/assets/images/web-push/web-push-icon_reblog.png similarity index 100% rename from app/images/web-push/web-push-icon_reblog.png rename to app/assets/images/web-push/web-push-icon_reblog.png diff --git a/app/sounds/boop.mp3 b/app/assets/sounds/boop.mp3 similarity index 100% rename from app/sounds/boop.mp3 rename to app/assets/sounds/boop.mp3 diff --git a/app/sounds/boop.ogg b/app/assets/sounds/boop.ogg similarity index 100% rename from app/sounds/boop.ogg rename to app/assets/sounds/boop.ogg diff --git a/app/sounds/chat.mp3 b/app/assets/sounds/chat.mp3 similarity index 100% rename from app/sounds/chat.mp3 rename to app/assets/sounds/chat.mp3 diff --git a/app/sounds/chat.oga b/app/assets/sounds/chat.oga similarity index 100% rename from app/sounds/chat.oga rename to app/assets/sounds/chat.oga diff --git a/app/images/halloween/clouds.png b/app/images/halloween/clouds.png deleted file mode 100644 index 29962c104..000000000 Binary files a/app/images/halloween/clouds.png and /dev/null differ diff --git a/app/images/halloween/halloween-emblem.svg b/app/images/halloween/halloween-emblem.svg deleted file mode 100644 index ad23be14c..000000000 --- a/app/images/halloween/halloween-emblem.svg +++ /dev/null @@ -1,311 +0,0 @@ - - - - Flying Witch during Full Moon - - - - - image/svg+xml - - Flying Witch during Full Moon - 2017-10-10 - - - Urs Roesch - - - - - - OpenClipart - - - - - remix+287475 - remix+288242 - remix+170669 - yellow - moon - yellow moon - full moon - moon - witch - cat - silhouette - bat - bats - flying bat - flying witch - black - dark - night - halloween - walpurgis night - walpurgis - - - Flying witch with cat flying during full moon. - - - gnokii - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/images/halloween/spider.svg b/app/images/halloween/spider.svg deleted file mode 100644 index 077b60d65..000000000 --- a/app/images/halloween/spider.svg +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - diff --git a/app/images/halloween/spiderweb.svg b/app/images/halloween/spiderweb.svg deleted file mode 100644 index 16ae81984..000000000 --- a/app/images/halloween/spiderweb.svg +++ /dev/null @@ -1,78 +0,0 @@ - - - - - Realistic spider web - - - - - - - image/svg+xml - - - - - Openclipart - - - Realistic spider web - - - - - - - - - diff --git a/app/images/halloween/starfield.png b/app/images/halloween/starfield.png deleted file mode 100644 index 1e7995895..000000000 Binary files a/app/images/halloween/starfield.png and /dev/null differ diff --git a/app/images/halloween/twinkle.svg b/app/images/halloween/twinkle.svg deleted file mode 100644 index 9869cb094..000000000 --- a/app/images/halloween/twinkle.svg +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - diff --git a/app/images/sprite-post-functions.png b/app/images/sprite-post-functions.png deleted file mode 100644 index aea7f57ba..000000000 Binary files a/app/images/sprite-post-functions.png and /dev/null differ diff --git a/app/soapbox/__fixtures__/intlMessages.json b/app/soapbox/__fixtures__/intlMessages.json index 54c919e6a..30ce6f35c 100644 --- a/app/soapbox/__fixtures__/intlMessages.json +++ b/app/soapbox/__fixtures__/intlMessages.json @@ -87,7 +87,7 @@ "compose_form.poll.add_option": "Add a choice", "compose_form.poll.duration": "Poll duration", "compose_form.poll.option_placeholder": "Choice {number}", - "compose_form.poll.remove_option": "Remove this choice", + "compose_form.poll.remove_option": "Delete", "compose_form.poll.type.hint": "Click to toggle poll type. Radio button (default) is single. Checkbox is multiple.", "compose_form.publish": "Publish", "compose_form.publish_loud": "{publish}!", @@ -319,6 +319,7 @@ "poll_button.add_poll": "Add a poll", "poll_button.remove_poll": "Remove poll", "preferences.fields.auto_play_gif_label": "Auto-play animated GIFs", + "preferences.fields.auto_play_video_label": "Auto-play videos", "preferences.fields.boost_modal_label": "Show confirmation dialog before reposting", "preferences.fields.delete_modal_label": "Show confirmation dialog before deleting a post", "preferences.fields.demetricator_label": "Use Demetricator", @@ -565,7 +566,7 @@ "compose_form.poll.add_option": "Add a choice", "compose_form.poll.duration": "Poll duration", "compose_form.poll.option_placeholder": "Choice {number}", - "compose_form.poll.remove_option": "Remove this choice", + "compose_form.poll.remove_option": "Delete", "compose_form.poll.type.hint": "Click to toggle poll type. Radio button (default) is single. Checkbox is multiple.", "compose_form.publish": "Publish", "compose_form.publish_loud": "{publish}!", diff --git a/app/soapbox/actions/__tests__/account-notes.test.ts b/app/soapbox/actions/__tests__/account-notes.test.ts index 61e0c20b0..8b85eecc5 100644 --- a/app/soapbox/actions/__tests__/account-notes.test.ts +++ b/app/soapbox/actions/__tests__/account-notes.test.ts @@ -2,7 +2,7 @@ import { Map as ImmutableMap } from 'immutable'; import { __stub } from 'soapbox/api'; import { mockStore, rootState } from 'soapbox/jest/test-helpers'; -import { ReducerRecord, EditRecord } from 'soapbox/reducers/account_notes'; +import { ReducerRecord, EditRecord } from 'soapbox/reducers/account-notes'; import { normalizeAccount, normalizeRelationship } from '../../normalizers'; import { changeAccountNoteComment, initAccountNoteModal, submitAccountNote } from '../account-notes'; diff --git a/app/soapbox/actions/__tests__/accounts.test.ts b/app/soapbox/actions/__tests__/accounts.test.ts index 0793e36f7..d9faa0213 100644 --- a/app/soapbox/actions/__tests__/accounts.test.ts +++ b/app/soapbox/actions/__tests__/accounts.test.ts @@ -2,7 +2,7 @@ import { Map as ImmutableMap } from 'immutable'; import { __stub } from 'soapbox/api'; import { mockStore, rootState } from 'soapbox/jest/test-helpers'; -import { ListRecord, ReducerRecord } from 'soapbox/reducers/user_lists'; +import { ListRecord, ReducerRecord } from 'soapbox/reducers/user-lists'; import { normalizeAccount, normalizeInstance, normalizeRelationship } from '../../normalizers'; import { diff --git a/app/soapbox/actions/__tests__/blocks.test.ts b/app/soapbox/actions/__tests__/blocks.test.ts index 8b4c040b3..49f649ab6 100644 --- a/app/soapbox/actions/__tests__/blocks.test.ts +++ b/app/soapbox/actions/__tests__/blocks.test.ts @@ -1,6 +1,6 @@ import { __stub } from 'soapbox/api'; import { mockStore, rootState } from 'soapbox/jest/test-helpers'; -import { ListRecord, ReducerRecord as UserListsRecord } from 'soapbox/reducers/user_lists'; +import { ListRecord, ReducerRecord as UserListsRecord } from 'soapbox/reducers/user-lists'; import { expandBlocks, fetchBlocks } from '../blocks'; diff --git a/app/soapbox/actions/__tests__/me.test.ts b/app/soapbox/actions/__tests__/me.test.ts index 6d37fc68c..c75d128f0 100644 --- a/app/soapbox/actions/__tests__/me.test.ts +++ b/app/soapbox/actions/__tests__/me.test.ts @@ -7,7 +7,7 @@ import { fetchMe, patchMe, } from '../me'; -jest.mock('../../storage/kv_store', () => ({ +jest.mock('../../storage/kv-store', () => ({ __esModule: true, default: { getItemOrError: jest.fn().mockReturnValue(Promise.resolve({})), diff --git a/app/soapbox/actions/auth.ts b/app/soapbox/actions/auth.ts index 5a686d045..d588db80a 100644 --- a/app/soapbox/actions/auth.ts +++ b/app/soapbox/actions/auth.ts @@ -16,7 +16,8 @@ import { obtainOAuthToken, revokeOAuthToken } from 'soapbox/actions/oauth'; import { startOnboarding } from 'soapbox/actions/onboarding'; import snackbar from 'soapbox/actions/snackbar'; import { custom } from 'soapbox/custom'; -import KVStore from 'soapbox/storage/kv_store'; +import { queryClient } from 'soapbox/queries/client'; +import KVStore from 'soapbox/storage/kv-store'; import { getLoggedInAccount, parseBaseURL } from 'soapbox/utils/auth'; import sourceCode from 'soapbox/utils/code'; import { getFeatures } from 'soapbox/utils/features'; @@ -239,15 +240,25 @@ export const logOut = () => token: state.auth.getIn(['users', account.url, 'access_token']), }; - return dispatch(revokeOAuthToken(params)).finally(() => { - dispatch({ type: AUTH_LOGGED_OUT, account, standalone }); - return dispatch(snackbar.success(messages.loggedOut)); - }); + return dispatch(revokeOAuthToken(params)) + .finally(() => { + // Clear all stored cache from React Query + queryClient.invalidateQueries(); + queryClient.clear(); + + dispatch({ type: AUTH_LOGGED_OUT, account, standalone }); + + return dispatch(snackbar.success(messages.loggedOut)); + }); }; export const switchAccount = (accountId: string, background = false) => (dispatch: AppDispatch, getState: () => RootState) => { const account = getState().accounts.get(accountId); + // Clear all stored cache from React Query + queryClient.invalidateQueries(); + queryClient.clear(); + return dispatch({ type: SWITCH_ACCOUNT, account, background }); }; diff --git a/app/soapbox/actions/compose.ts b/app/soapbox/actions/compose.ts index 57e7909a1..3010ae3fd 100644 --- a/app/soapbox/actions/compose.ts +++ b/app/soapbox/actions/compose.ts @@ -5,12 +5,12 @@ import { defineMessages, IntlShape } from 'react-intl'; import snackbar from 'soapbox/actions/snackbar'; import api from 'soapbox/api'; -import { search as emojiSearch } from 'soapbox/features/emoji/emoji_mart_search_light'; +import { search as emojiSearch } from 'soapbox/features/emoji/emoji-mart-search-light'; import { tagHistory } from 'soapbox/settings'; import { isLoggedIn } from 'soapbox/utils/auth'; import { getFeatures, parseVersion } from 'soapbox/utils/features'; import { formatBytes, getVideoDuration } from 'soapbox/utils/media'; -import resizeImage from 'soapbox/utils/resize_image'; +import resizeImage from 'soapbox/utils/resize-image'; import { showAlert, showAlertForError } from './alerts'; import { useEmoji } from './emojis'; @@ -21,8 +21,8 @@ import { getSettings } from './settings'; import { createStatus } from './statuses'; import type { History } from 'history'; -import type { Emoji } from 'soapbox/components/autosuggest_emoji'; -import type { AutoSuggestion } from 'soapbox/components/autosuggest_input'; +import type { Emoji } from 'soapbox/components/autosuggest-emoji'; +import type { AutoSuggestion } from 'soapbox/components/autosuggest-input'; import type { AppDispatch, RootState } from 'soapbox/store'; import type { Account, APIEntity, Status, Tag } from 'soapbox/types/entities'; diff --git a/app/soapbox/actions/consumer-auth.ts b/app/soapbox/actions/consumer-auth.ts index b669c6393..171941577 100644 --- a/app/soapbox/actions/consumer-auth.ts +++ b/app/soapbox/actions/consumer-auth.ts @@ -1,6 +1,6 @@ import axios from 'axios'; -import * as BuildConfig from 'soapbox/build_config'; +import * as BuildConfig from 'soapbox/build-config'; import { isURL } from 'soapbox/utils/auth'; import sourceCode from 'soapbox/utils/code'; import { getFeatures } from 'soapbox/utils/features'; diff --git a/app/soapbox/actions/custom_emojis.ts b/app/soapbox/actions/custom-emojis.ts similarity index 100% rename from app/soapbox/actions/custom_emojis.ts rename to app/soapbox/actions/custom-emojis.ts diff --git a/app/soapbox/actions/domain_blocks.ts b/app/soapbox/actions/domain-blocks.ts similarity index 100% rename from app/soapbox/actions/domain_blocks.ts rename to app/soapbox/actions/domain-blocks.ts diff --git a/app/soapbox/actions/dropdown_menu.ts b/app/soapbox/actions/dropdown-menu.ts similarity index 97% rename from app/soapbox/actions/dropdown_menu.ts rename to app/soapbox/actions/dropdown-menu.ts index 2c19735a1..0c6fc8536 100644 --- a/app/soapbox/actions/dropdown_menu.ts +++ b/app/soapbox/actions/dropdown-menu.ts @@ -1,4 +1,4 @@ -import type { DropdownPlacement } from 'soapbox/components/dropdown_menu'; +import type { DropdownPlacement } from 'soapbox/components/dropdown-menu'; const DROPDOWN_MENU_OPEN = 'DROPDOWN_MENU_OPEN'; const DROPDOWN_MENU_CLOSE = 'DROPDOWN_MENU_CLOSE'; diff --git a/app/soapbox/actions/email_list.ts b/app/soapbox/actions/email-list.ts similarity index 100% rename from app/soapbox/actions/email_list.ts rename to app/soapbox/actions/email-list.ts diff --git a/app/soapbox/actions/emoji_reacts.ts b/app/soapbox/actions/emoji-reacts.ts similarity index 100% rename from app/soapbox/actions/emoji_reacts.ts rename to app/soapbox/actions/emoji-reacts.ts diff --git a/app/soapbox/actions/emojis.ts b/app/soapbox/actions/emojis.ts index 04bda6c89..46f591b06 100644 --- a/app/soapbox/actions/emojis.ts +++ b/app/soapbox/actions/emojis.ts @@ -1,6 +1,6 @@ import { saveSettings } from './settings'; -import type { Emoji } from 'soapbox/components/autosuggest_emoji'; +import type { Emoji } from 'soapbox/components/autosuggest-emoji'; import type { AppDispatch } from 'soapbox/store'; const EMOJI_USE = 'EMOJI_USE'; diff --git a/app/soapbox/actions/export_data.ts b/app/soapbox/actions/export-data.ts similarity index 100% rename from app/soapbox/actions/export_data.ts rename to app/soapbox/actions/export-data.ts diff --git a/app/soapbox/actions/external_auth.ts b/app/soapbox/actions/external-auth.ts similarity index 100% rename from app/soapbox/actions/external_auth.ts rename to app/soapbox/actions/external-auth.ts diff --git a/app/soapbox/actions/familiar_followers.ts b/app/soapbox/actions/familiar-followers.ts similarity index 100% rename from app/soapbox/actions/familiar_followers.ts rename to app/soapbox/actions/familiar-followers.ts diff --git a/app/soapbox/actions/import_data.ts b/app/soapbox/actions/import-data.ts similarity index 100% rename from app/soapbox/actions/import_data.ts rename to app/soapbox/actions/import-data.ts diff --git a/app/soapbox/actions/instance.ts b/app/soapbox/actions/instance.ts index 151ad3672..ca1fc3ef5 100644 --- a/app/soapbox/actions/instance.ts +++ b/app/soapbox/actions/instance.ts @@ -1,7 +1,7 @@ import { createAsyncThunk } from '@reduxjs/toolkit'; import get from 'lodash/get'; -import KVStore from 'soapbox/storage/kv_store'; +import KVStore from 'soapbox/storage/kv-store'; import { RootState } from 'soapbox/store'; import { getAuthUserUrl } from 'soapbox/utils/auth'; import { parseVersion } from 'soapbox/utils/features'; diff --git a/app/soapbox/actions/me.ts b/app/soapbox/actions/me.ts index e76399d21..17beae21d 100644 --- a/app/soapbox/actions/me.ts +++ b/app/soapbox/actions/me.ts @@ -1,4 +1,4 @@ -import KVStore from 'soapbox/storage/kv_store'; +import KVStore from 'soapbox/storage/kv-store'; import { getAuthUserId, getAuthUserUrl } from 'soapbox/utils/auth'; import api from '../api'; diff --git a/app/soapbox/actions/modals.ts b/app/soapbox/actions/modals.ts index 3e1a106cf..83b52cb3e 100644 --- a/app/soapbox/actions/modals.ts +++ b/app/soapbox/actions/modals.ts @@ -1,8 +1,10 @@ +import type { ModalType } from 'soapbox/features/ui/components/modal-root'; + export const MODAL_OPEN = 'MODAL_OPEN'; export const MODAL_CLOSE = 'MODAL_CLOSE'; /** Open a modal of the given type */ -export function openModal(type: string, props?: any) { +export function openModal(type: ModalType, props?: any) { return { type: MODAL_OPEN, modalType: type, @@ -11,7 +13,7 @@ export function openModal(type: string, props?: any) { } /** Close the modal */ -export function closeModal(type?: string) { +export function closeModal(type?: ModalType) { return { type: MODAL_CLOSE, modalType: type, diff --git a/app/soapbox/actions/moderation.tsx b/app/soapbox/actions/moderation.tsx index bf0ccf332..1791500b5 100644 --- a/app/soapbox/actions/moderation.tsx +++ b/app/soapbox/actions/moderation.tsx @@ -7,7 +7,7 @@ import { openModal } from 'soapbox/actions/modals'; import snackbar from 'soapbox/actions/snackbar'; import OutlineBox from 'soapbox/components/outline-box'; import { Stack, Text } from 'soapbox/components/ui'; -import AccountContainer from 'soapbox/containers/account_container'; +import AccountContainer from 'soapbox/containers/account-container'; import { isLocal } from 'soapbox/utils/accounts'; import type { AppDispatch, RootState } from 'soapbox/store'; diff --git a/app/soapbox/actions/mrf.ts b/app/soapbox/actions/mrf.ts index e2cef5938..1b9cbad93 100644 --- a/app/soapbox/actions/mrf.ts +++ b/app/soapbox/actions/mrf.ts @@ -1,11 +1,11 @@ import { Map as ImmutableMap, Set as ImmutableSet } from 'immutable'; -import ConfigDB from 'soapbox/utils/config_db'; +import ConfigDB from 'soapbox/utils/config-db'; import { fetchConfig, updateConfig } from './admin'; import type { AppDispatch, RootState } from 'soapbox/store'; -import type { Policy } from 'soapbox/utils/config_db'; +import type { Policy } from 'soapbox/utils/config-db'; const simplePolicyMerge = (simplePolicy: Policy, host: string, restrictions: ImmutableMap) => { return simplePolicy.map((hosts, key) => { diff --git a/app/soapbox/actions/notifications.ts b/app/soapbox/actions/notifications.ts index db8fd688f..068e65dc4 100644 --- a/app/soapbox/actions/notifications.ts +++ b/app/soapbox/actions/notifications.ts @@ -1,14 +1,11 @@ -import { - Map as ImmutableMap, -} from 'immutable'; import IntlMessageFormat from 'intl-messageformat'; import 'intl-pluralrules'; import { defineMessages } from 'react-intl'; import api, { getLinks } from 'soapbox/api'; -import compareId from 'soapbox/compare_id'; import { getFilters, regexFromFilters } from 'soapbox/selectors'; import { isLoggedIn } from 'soapbox/utils/auth'; +import { compareId } from 'soapbox/utils/comparators'; import { getFeatures, parseVersion, PLEROMA } from 'soapbox/utils/features'; import { unescapeHTML } from 'soapbox/utils/html'; import { EXCLUDE_TYPES, NOTIFICATION_TYPES } from 'soapbox/utils/notification'; @@ -149,13 +146,13 @@ const updateNotificationsQueue = (notification: APIEntity, intlMessages: Record< const dequeueNotifications = () => (dispatch: AppDispatch, getState: () => RootState) => { - const queuedNotifications = getState().notifications.get('queuedNotifications'); - const totalQueuedNotificationsCount = getState().notifications.get('totalQueuedNotificationsCount'); + const queuedNotifications = getState().notifications.queuedNotifications; + const totalQueuedNotificationsCount = getState().notifications.totalQueuedNotificationsCount; if (totalQueuedNotificationsCount === 0) { return; } else if (totalQueuedNotificationsCount > 0 && totalQueuedNotificationsCount <= MAX_QUEUED_NOTIFICATIONS) { - queuedNotifications.forEach((block: APIEntity) => { + queuedNotifications.forEach((block) => { dispatch(updateNotifications(block.notification)); }); } else { @@ -184,7 +181,7 @@ const expandNotifications = ({ maxId }: Record = {}, done: () => an const notifications = state.notifications; const isLoadingMore = !!maxId; - if (notifications.get('isLoading')) { + if (notifications.isLoading) { done(); return dispatch(noOp); } @@ -207,7 +204,7 @@ const expandNotifications = ({ maxId }: Record = {}, done: () => an } } - if (!maxId && notifications.get('items').size > 0) { + if (!maxId && notifications.items.size > 0) { params.since_id = notifications.getIn(['items', 0, 'id']); } @@ -306,8 +303,8 @@ const markReadNotifications = () => if (!isLoggedIn(getState)) return; const state = getState(); - const topNotificationId: string | undefined = state.notifications.get('items').first(ImmutableMap()).get('id'); - const lastReadId: string | -1 = state.notifications.get('lastRead'); + const topNotificationId = state.notifications.items.first()?.id; + const lastReadId = state.notifications.lastRead; const v = parseVersion(state.instance.version); if (topNotificationId && (lastReadId === -1 || compareId(topNotificationId, lastReadId) > 0)) { diff --git a/app/soapbox/actions/pin_statuses.ts b/app/soapbox/actions/pin-statuses.ts similarity index 100% rename from app/soapbox/actions/pin_statuses.ts rename to app/soapbox/actions/pin-statuses.ts diff --git a/app/soapbox/actions/profile_hover_card.ts b/app/soapbox/actions/profile-hover-card.ts similarity index 100% rename from app/soapbox/actions/profile_hover_card.ts rename to app/soapbox/actions/profile-hover-card.ts diff --git a/app/soapbox/actions/push_notifications/index.ts b/app/soapbox/actions/push-notifications/index.ts similarity index 100% rename from app/soapbox/actions/push_notifications/index.ts rename to app/soapbox/actions/push-notifications/index.ts diff --git a/app/soapbox/actions/push_notifications/registerer.ts b/app/soapbox/actions/push-notifications/registerer.ts similarity index 99% rename from app/soapbox/actions/push_notifications/registerer.ts rename to app/soapbox/actions/push-notifications/registerer.ts index e66e3a01a..3a9d4fb9e 100644 --- a/app/soapbox/actions/push_notifications/registerer.ts +++ b/app/soapbox/actions/push-notifications/registerer.ts @@ -1,4 +1,4 @@ -import { createPushSubscription, updatePushSubscription } from 'soapbox/actions/push_subscriptions'; +import { createPushSubscription, updatePushSubscription } from 'soapbox/actions/push-subscriptions'; import { pushNotificationsSetting } from 'soapbox/settings'; import { getVapidKey } from 'soapbox/utils/auth'; import { decode as decodeBase64 } from 'soapbox/utils/base64'; diff --git a/app/soapbox/actions/push_notifications/setter.ts b/app/soapbox/actions/push-notifications/setter.ts similarity index 100% rename from app/soapbox/actions/push_notifications/setter.ts rename to app/soapbox/actions/push-notifications/setter.ts diff --git a/app/soapbox/actions/push_subscriptions.ts b/app/soapbox/actions/push-subscriptions.ts similarity index 100% rename from app/soapbox/actions/push_subscriptions.ts rename to app/soapbox/actions/push-subscriptions.ts diff --git a/app/soapbox/actions/remote_timeline.ts b/app/soapbox/actions/remote-timeline.ts similarity index 100% rename from app/soapbox/actions/remote_timeline.ts rename to app/soapbox/actions/remote-timeline.ts diff --git a/app/soapbox/actions/scheduled_statuses.ts b/app/soapbox/actions/scheduled-statuses.ts similarity index 100% rename from app/soapbox/actions/scheduled_statuses.ts rename to app/soapbox/actions/scheduled-statuses.ts diff --git a/app/soapbox/actions/soapbox.ts b/app/soapbox/actions/soapbox.ts index 89d3080d8..725ff1ae3 100644 --- a/app/soapbox/actions/soapbox.ts +++ b/app/soapbox/actions/soapbox.ts @@ -2,7 +2,7 @@ import { createSelector } from 'reselect'; import { getHost } from 'soapbox/actions/instance'; import { normalizeSoapboxConfig } from 'soapbox/normalizers'; -import KVStore from 'soapbox/storage/kv_store'; +import KVStore from 'soapbox/storage/kv-store'; import { removeVS16s } from 'soapbox/utils/emoji'; import { getFeatures } from 'soapbox/utils/features'; diff --git a/app/soapbox/actions/trending_statuses.ts b/app/soapbox/actions/trending-statuses.ts similarity index 100% rename from app/soapbox/actions/trending_statuses.ts rename to app/soapbox/actions/trending-statuses.ts diff --git a/app/soapbox/__mocks__/api.ts b/app/soapbox/api/__mocks__/index.ts similarity index 92% rename from app/soapbox/__mocks__/api.ts rename to app/soapbox/api/__mocks__/index.ts index 060846c94..dd2f1ec93 100644 --- a/app/soapbox/__mocks__/api.ts +++ b/app/soapbox/api/__mocks__/index.ts @@ -4,7 +4,7 @@ import LinkHeader from 'http-link-header'; import type { AxiosInstance, AxiosResponse } from 'axios'; -const api = jest.requireActual('../api') as Record; +const api = jest.requireActual('../index') as Record; let mocks: Array = []; export const __stub = (func: (mock: MockAdapter) => void) => mocks.push(func); diff --git a/app/soapbox/api.ts b/app/soapbox/api/index.ts similarity index 75% rename from app/soapbox/api.ts rename to app/soapbox/api/index.ts index bdcaf53d8..97d7d25d7 100644 --- a/app/soapbox/api.ts +++ b/app/soapbox/api/index.ts @@ -9,18 +9,18 @@ import axios, { AxiosInstance, AxiosResponse } from 'axios'; import LinkHeader from 'http-link-header'; import { createSelector } from 'reselect'; -import * as BuildConfig from 'soapbox/build_config'; +import * as BuildConfig from 'soapbox/build-config'; import { RootState } from 'soapbox/store'; import { getAccessToken, getAppToken, isURL, parseBaseURL } from 'soapbox/utils/auth'; import type MockAdapter from 'axios-mock-adapter'; /** - Parse Link headers, mostly for pagination. - @see {@link https://www.npmjs.com/package/http-link-header} - @param {object} response - Axios response object - @returns {object} Link object - */ + Parse Link headers, mostly for pagination. + @see {@link https://www.npmjs.com/package/http-link-header} + @param {object} response - Axios response object + @returns {object} Link object + */ export const getLinks = (response: AxiosResponse): LinkHeader => { return new LinkHeader(response.headers?.link); }; @@ -50,11 +50,11 @@ const getAuthBaseURL = createSelector([ }); /** - * Base client for HTTP requests. - * @param {string} accessToken - * @param {string} baseURL - * @returns {object} Axios instance - */ + * Base client for HTTP requests. + * @param {string} accessToken + * @param {string} baseURL + * @returns {object} Axios instance + */ export const baseClient = (accessToken?: string | null, baseURL: string = ''): AxiosInstance => { return axios.create({ // When BACKEND_URL is set, always use it. @@ -68,22 +68,22 @@ export const baseClient = (accessToken?: string | null, baseURL: string = ''): A }; /** - * Dumb client for grabbing static files. - * It uses FE_SUBDIRECTORY and parses JSON if possible. - * No authorization is needed. - */ + * Dumb client for grabbing static files. + * It uses FE_SUBDIRECTORY and parses JSON if possible. + * No authorization is needed. + */ export const staticClient = axios.create({ baseURL: BuildConfig.FE_SUBDIRECTORY, transformResponse: [maybeParseJSON], }); /** - * Stateful API client. - * Uses credentials from the Redux store if available. - * @param {function} getState - Must return the Redux state - * @param {string} authType - Either 'user' or 'app' - * @returns {object} Axios instance - */ + * Stateful API client. + * Uses credentials from the Redux store if available. + * @param {function} getState - Must return the Redux state + * @param {string} authType - Either 'user' or 'app' + * @returns {object} Axios instance + */ export default (getState: () => RootState, authType: string = 'user'): AxiosInstance => { const state = getState(); const accessToken = getToken(state, authType); diff --git a/app/soapbox/base_polyfills.ts b/app/soapbox/base-polyfills.ts similarity index 100% rename from app/soapbox/base_polyfills.ts rename to app/soapbox/base-polyfills.ts diff --git a/app/soapbox/build_config.js b/app/soapbox/build-config.js similarity index 96% rename from app/soapbox/build_config.js rename to app/soapbox/build-config.js index 04b48bf78..a11faa0e8 100644 --- a/app/soapbox/build_config.js +++ b/app/soapbox/build-config.js @@ -1,7 +1,7 @@ // @preval /** * Build config: configuration set at build time. - * @module soapbox/build_config + * @module soapbox/build-config */ const trim = require('lodash/trim'); diff --git a/app/soapbox/components/__tests__/autosuggest_emoji.test.tsx b/app/soapbox/components/__tests__/autosuggest-emoji.test.tsx similarity index 94% rename from app/soapbox/components/__tests__/autosuggest_emoji.test.tsx rename to app/soapbox/components/__tests__/autosuggest-emoji.test.tsx index 8fab0ef8b..e2f059ff7 100644 --- a/app/soapbox/components/__tests__/autosuggest_emoji.test.tsx +++ b/app/soapbox/components/__tests__/autosuggest-emoji.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { render, screen } from '../../jest/test-helpers'; -import AutosuggestEmoji from '../autosuggest_emoji'; +import AutosuggestEmoji from '../autosuggest-emoji'; describe('', () => { it('renders native emoji', () => { diff --git a/app/soapbox/components/__tests__/avatar_overlay.test.tsx b/app/soapbox/components/__tests__/avatar-overlay.test.tsx similarity index 94% rename from app/soapbox/components/__tests__/avatar_overlay.test.tsx rename to app/soapbox/components/__tests__/avatar-overlay.test.tsx index 105828556..4e83dd071 100644 --- a/app/soapbox/components/__tests__/avatar_overlay.test.tsx +++ b/app/soapbox/components/__tests__/avatar-overlay.test.tsx @@ -3,7 +3,7 @@ import React from 'react'; import { normalizeAccount } from 'soapbox/normalizers'; import { render, screen } from '../../jest/test-helpers'; -import AvatarOverlay from '../avatar_overlay'; +import AvatarOverlay from '../avatar-overlay'; import type { ReducerAccount } from 'soapbox/reducers/accounts'; diff --git a/app/soapbox/components/__tests__/display_name.test.tsx b/app/soapbox/components/__tests__/display-name.test.tsx similarity index 100% rename from app/soapbox/components/__tests__/display_name.test.tsx rename to app/soapbox/components/__tests__/display-name.test.tsx diff --git a/app/soapbox/components/__tests__/emoji_selector.test.tsx b/app/soapbox/components/__tests__/emoji-selector.test.tsx similarity index 88% rename from app/soapbox/components/__tests__/emoji_selector.test.tsx rename to app/soapbox/components/__tests__/emoji-selector.test.tsx index c680d156e..b382a4b94 100644 --- a/app/soapbox/components/__tests__/emoji_selector.test.tsx +++ b/app/soapbox/components/__tests__/emoji-selector.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { render, screen } from '../../jest/test-helpers'; -import EmojiSelector from '../emoji_selector'; +import EmojiSelector from '../emoji-selector'; describe('', () => { it('renders correctly', () => { diff --git a/app/soapbox/components/account_search.tsx b/app/soapbox/components/account-search.tsx similarity index 99% rename from app/soapbox/components/account_search.tsx rename to app/soapbox/components/account-search.tsx index bf9652b66..883278bcf 100644 --- a/app/soapbox/components/account_search.tsx +++ b/app/soapbox/components/account-search.tsx @@ -2,7 +2,7 @@ import classNames from 'clsx'; import React, { useState } from 'react'; import { defineMessages, useIntl } from 'react-intl'; -import AutosuggestAccountInput from 'soapbox/components/autosuggest_account_input'; +import AutosuggestAccountInput from 'soapbox/components/autosuggest-account-input'; import Icon from 'soapbox/components/icon'; const messages = defineMessages({ diff --git a/app/soapbox/components/account.tsx b/app/soapbox/components/account.tsx index e981e66ae..006584e8d 100644 --- a/app/soapbox/components/account.tsx +++ b/app/soapbox/components/account.tsx @@ -1,8 +1,8 @@ import * as React from 'react'; import { Link, useHistory } from 'react-router-dom'; -import HoverRefWrapper from 'soapbox/components/hover_ref_wrapper'; -import VerificationBadge from 'soapbox/components/verification_badge'; +import HoverRefWrapper from 'soapbox/components/hover-ref-wrapper'; +import VerificationBadge from 'soapbox/components/verification-badge'; import ActionButton from 'soapbox/features/ui/components/action-button'; import { useAppSelector, useOnScreen } from 'soapbox/hooks'; import { getAcct } from 'soapbox/utils/accounts'; diff --git a/app/soapbox/components/announcements/emoji.tsx b/app/soapbox/components/announcements/emoji.tsx index eb9683f08..64266639d 100644 --- a/app/soapbox/components/announcements/emoji.tsx +++ b/app/soapbox/components/announcements/emoji.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import unicodeMapping from 'soapbox/features/emoji/emoji_unicode_mapping_light'; +import unicodeMapping from 'soapbox/features/emoji/emoji-unicode-mapping-light'; import { useSettings } from 'soapbox/hooks'; import { joinPublicPath } from 'soapbox/utils/static'; diff --git a/app/soapbox/components/announcements/reaction.tsx b/app/soapbox/components/announcements/reaction.tsx index 8e2391aec..230613701 100644 --- a/app/soapbox/components/announcements/reaction.tsx +++ b/app/soapbox/components/announcements/reaction.tsx @@ -2,7 +2,7 @@ import classNames from 'clsx'; import React, { useState } from 'react'; import AnimatedNumber from 'soapbox/components/animated-number'; -import unicodeMapping from 'soapbox/features/emoji/emoji_unicode_mapping_light'; +import unicodeMapping from 'soapbox/features/emoji/emoji-unicode-mapping-light'; import Emoji from './emoji'; diff --git a/app/soapbox/components/announcements/reactions-bar.tsx b/app/soapbox/components/announcements/reactions-bar.tsx index 130db2d99..f9569fb90 100644 --- a/app/soapbox/components/announcements/reactions-bar.tsx +++ b/app/soapbox/components/announcements/reactions-bar.tsx @@ -9,7 +9,7 @@ import { useSettings } from 'soapbox/hooks'; import Reaction from './reaction'; import type { List as ImmutableList, Map as ImmutableMap } from 'immutable'; -import type { Emoji } from 'soapbox/components/autosuggest_emoji'; +import type { Emoji } from 'soapbox/components/autosuggest-emoji'; import type { AnnouncementReaction } from 'soapbox/types/entities'; interface IReactionsBar { diff --git a/app/soapbox/components/attachment_list.tsx b/app/soapbox/components/attachment_list.tsx deleted file mode 100644 index 94c496819..000000000 --- a/app/soapbox/components/attachment_list.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import React from 'react'; - -import Icon from 'soapbox/components/icon'; - -import type { Attachment as AttachmentEntity } from 'soapbox/types/entities'; - -const filename = (url: string) => url.split('/').pop()!.split('#')[0].split('?')[0]; - -interface IAttachmentList { - media: AttachmentEntity[], - compact?: boolean, -} - -const AttachmentList: React.FC = ({ media, compact }) => { - if (compact) { - return ( -
-
    - {media.map(attachment => { - const displayUrl = attachment.get('remote_url') || attachment.get('url'); - - return ( -
  • - {filename(displayUrl)} -
  • - ); - })} -
-
- ); - } - - return ( -
-
- -
- -
    - {media.map(attachment => { - const displayUrl = attachment.get('remote_url') || attachment.get('url'); - - return ( -
  • - {filename(displayUrl)} -
  • - ); - })} -
-
- ); -}; - -export default AttachmentList; diff --git a/app/soapbox/components/autosuggest_account_input.tsx b/app/soapbox/components/autosuggest-account-input.tsx similarity index 95% rename from app/soapbox/components/autosuggest_account_input.tsx rename to app/soapbox/components/autosuggest-account-input.tsx index e8cd63830..1be14c3ec 100644 --- a/app/soapbox/components/autosuggest_account_input.tsx +++ b/app/soapbox/components/autosuggest-account-input.tsx @@ -3,13 +3,13 @@ import throttle from 'lodash/throttle'; import React, { useState, useRef, useCallback, useEffect } from 'react'; import { accountSearch } from 'soapbox/actions/accounts'; -import AutosuggestInput, { AutoSuggestion } from 'soapbox/components/autosuggest_input'; +import AutosuggestInput, { AutoSuggestion } from 'soapbox/components/autosuggest-input'; import { useAppDispatch } from 'soapbox/hooks'; -import type { Menu } from 'soapbox/components/dropdown_menu'; +import type { Menu } from 'soapbox/components/dropdown-menu'; import type { InputThemes } from 'soapbox/components/ui/input/input'; -const noOp = () => {}; +const noOp = () => { }; interface IAutosuggestAccountInput { onChange: React.ChangeEventHandler, diff --git a/app/soapbox/components/autosuggest_emoji.tsx b/app/soapbox/components/autosuggest-emoji.tsx similarity index 92% rename from app/soapbox/components/autosuggest_emoji.tsx rename to app/soapbox/components/autosuggest-emoji.tsx index 22979d454..7074605a2 100644 --- a/app/soapbox/components/autosuggest_emoji.tsx +++ b/app/soapbox/components/autosuggest-emoji.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import unicodeMapping from 'soapbox/features/emoji/emoji_unicode_mapping_light'; +import unicodeMapping from 'soapbox/features/emoji/emoji-unicode-mapping-light'; import { joinPublicPath } from 'soapbox/utils/static'; export type Emoji = { diff --git a/app/soapbox/components/autosuggest_input.tsx b/app/soapbox/components/autosuggest-input.tsx similarity index 99% rename from app/soapbox/components/autosuggest_input.tsx rename to app/soapbox/components/autosuggest-input.tsx index 155cd428a..746bee9df 100644 --- a/app/soapbox/components/autosuggest_input.tsx +++ b/app/soapbox/components/autosuggest-input.tsx @@ -1,16 +1,16 @@ -import Portal from '@reach/portal'; +import { Portal } from '@reach/portal'; import classNames from 'clsx'; import { List as ImmutableList } from 'immutable'; import React from 'react'; import ImmutablePureComponent from 'react-immutable-pure-component'; -import AutosuggestEmoji, { Emoji } from 'soapbox/components/autosuggest_emoji'; +import AutosuggestEmoji, { Emoji } from 'soapbox/components/autosuggest-emoji'; import Icon from 'soapbox/components/icon'; import { Input } from 'soapbox/components/ui'; -import AutosuggestAccount from 'soapbox/features/compose/components/autosuggest_account'; +import AutosuggestAccount from 'soapbox/features/compose/components/autosuggest-account'; import { isRtl } from 'soapbox/rtl'; -import type { Menu, MenuItem } from 'soapbox/components/dropdown_menu'; +import type { Menu, MenuItem } from 'soapbox/components/dropdown-menu'; import type { InputThemes } from 'soapbox/components/ui/input/input'; type CursorMatch = [ diff --git a/app/soapbox/components/autosuggest_textarea.tsx b/app/soapbox/components/autosuggest-textarea.tsx similarity index 98% rename from app/soapbox/components/autosuggest_textarea.tsx rename to app/soapbox/components/autosuggest-textarea.tsx index c1c849b07..8e877021f 100644 --- a/app/soapbox/components/autosuggest_textarea.tsx +++ b/app/soapbox/components/autosuggest-textarea.tsx @@ -1,13 +1,13 @@ -import Portal from '@reach/portal'; +import { Portal } from '@reach/portal'; import classNames from 'clsx'; import React from 'react'; import ImmutablePureComponent from 'react-immutable-pure-component'; import Textarea from 'react-textarea-autosize'; -import AutosuggestAccount from '../features/compose/components/autosuggest_account'; +import AutosuggestAccount from '../features/compose/components/autosuggest-account'; import { isRtl } from '../rtl'; -import AutosuggestEmoji, { Emoji } from './autosuggest_emoji'; +import AutosuggestEmoji, { Emoji } from './autosuggest-emoji'; import type { List as ImmutableList } from 'immutable'; diff --git a/app/soapbox/components/avatar_overlay.tsx b/app/soapbox/components/avatar-overlay.tsx similarity index 89% rename from app/soapbox/components/avatar_overlay.tsx rename to app/soapbox/components/avatar-overlay.tsx index ae38b5e4c..a463b35ce 100644 --- a/app/soapbox/components/avatar_overlay.tsx +++ b/app/soapbox/components/avatar-overlay.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import StillImage from 'soapbox/components/still_image'; +import StillImage from 'soapbox/components/still-image'; import type { Account as AccountEntity } from 'soapbox/types/entities'; diff --git a/app/soapbox/components/avatar.tsx b/app/soapbox/components/avatar.tsx index 4f40d46bb..4bc5c0774 100644 --- a/app/soapbox/components/avatar.tsx +++ b/app/soapbox/components/avatar.tsx @@ -1,7 +1,7 @@ import classNames from 'clsx'; import React from 'react'; -import StillImage from 'soapbox/components/still_image'; +import StillImage from 'soapbox/components/still-image'; import type { Account } from 'soapbox/types/entities'; diff --git a/app/soapbox/components/birthday_input.tsx b/app/soapbox/components/birthday-input.tsx similarity index 98% rename from app/soapbox/components/birthday_input.tsx rename to app/soapbox/components/birthday-input.tsx index fc9521ca0..21a10a1e5 100644 --- a/app/soapbox/components/birthday_input.tsx +++ b/app/soapbox/components/birthday-input.tsx @@ -1,8 +1,8 @@ import React, { useMemo } from 'react'; import { defineMessages, useIntl } from 'react-intl'; -import IconButton from 'soapbox/components/icon_button'; -import BundleContainer from 'soapbox/features/ui/containers/bundle_container'; +import IconButton from 'soapbox/components/icon-button'; +import BundleContainer from 'soapbox/features/ui/containers/bundle-container'; import { DatePicker } from 'soapbox/features/ui/util/async-components'; import { useAppSelector, useFeatures } from 'soapbox/hooks'; diff --git a/app/soapbox/components/birthday-panel.tsx b/app/soapbox/components/birthday-panel.tsx index 8381203b9..059b8678b 100644 --- a/app/soapbox/components/birthday-panel.tsx +++ b/app/soapbox/components/birthday-panel.tsx @@ -4,7 +4,7 @@ import { FormattedMessage } from 'react-intl'; import { fetchBirthdayReminders } from 'soapbox/actions/accounts'; import { Widget } from 'soapbox/components/ui'; -import AccountContainer from 'soapbox/containers/account_container'; +import AccountContainer from 'soapbox/containers/account-container'; import { useAppDispatch, useAppSelector } from 'soapbox/hooks'; const timeToMidnight = () => { diff --git a/app/soapbox/components/column_header.js b/app/soapbox/components/column-header.js similarity index 97% rename from app/soapbox/components/column_header.js rename to app/soapbox/components/column-header.js index 83a61b7ea..2d915c9f8 100644 --- a/app/soapbox/components/column_header.js +++ b/app/soapbox/components/column-header.js @@ -7,7 +7,7 @@ import { withRouter } from 'react-router-dom'; // import classNames from 'clsx'; // import { injectIntl, defineMessages } from 'react-intl'; // import Icon from 'soapbox/components/icon'; -import SubNavigation from 'soapbox/components/sub_navigation'; +import SubNavigation from 'soapbox/components/sub-navigation'; // const messages = defineMessages({ // show: { id: 'column_header.show_settings', defaultMessage: 'Show settings' }, diff --git a/app/soapbox/components/display-name.tsx b/app/soapbox/components/display-name.tsx index 63028ccfe..8fd2bfa53 100644 --- a/app/soapbox/components/display-name.tsx +++ b/app/soapbox/components/display-name.tsx @@ -1,13 +1,13 @@ import * as React from 'react'; -import HoverRefWrapper from 'soapbox/components/hover_ref_wrapper'; +import HoverRefWrapper from 'soapbox/components/hover-ref-wrapper'; import { useSoapboxConfig } from 'soapbox/hooks'; import { getAcct } from '../utils/accounts'; import Icon from './icon'; import RelativeTimestamp from './relative-timestamp'; -import VerificationBadge from './verification_badge'; +import VerificationBadge from './verification-badge'; import type { Account } from 'soapbox/types/entities'; diff --git a/app/soapbox/components/domain.tsx b/app/soapbox/components/domain.tsx index 22c8272de..191dc3872 100644 --- a/app/soapbox/components/domain.tsx +++ b/app/soapbox/components/domain.tsx @@ -2,9 +2,9 @@ import React from 'react'; import { defineMessages, useIntl } from 'react-intl'; import { useDispatch } from 'react-redux'; -import { unblockDomain } from 'soapbox/actions/domain_blocks'; +import { unblockDomain } from 'soapbox/actions/domain-blocks'; -import IconButton from './icon_button'; +import { HStack, IconButton, Text } from './ui'; const messages = defineMessages({ blockDomainConfirm: { id: 'confirmations.domain_block.confirm', defaultMessage: 'Hide entire domain' }, @@ -34,17 +34,12 @@ const Domain: React.FC = ({ domain }) => { }; return ( -
-
- - {domain} - - -
- -
-
-
+ + + {domain} + + + ); }; diff --git a/app/soapbox/components/dropdown_menu.tsx b/app/soapbox/components/dropdown-menu.tsx similarity index 99% rename from app/soapbox/components/dropdown_menu.tsx rename to app/soapbox/components/dropdown-menu.tsx index 01d69483d..77be0f18d 100644 --- a/app/soapbox/components/dropdown_menu.tsx +++ b/app/soapbox/components/dropdown-menu.tsx @@ -8,7 +8,7 @@ import { withRouter, RouteComponentProps } from 'react-router-dom'; import { IconButton, Counter } from 'soapbox/components/ui'; import SvgIcon from 'soapbox/components/ui/icon/svg-icon'; -import Motion from 'soapbox/features/ui/util/optional_motion'; +import Motion from 'soapbox/features/ui/util/optional-motion'; import type { Status } from 'soapbox/types/entities'; diff --git a/app/soapbox/components/emoji-button-wrapper.tsx b/app/soapbox/components/emoji-button-wrapper.tsx index d85d22627..23a165fcb 100644 --- a/app/soapbox/components/emoji-button-wrapper.tsx +++ b/app/soapbox/components/emoji-button-wrapper.tsx @@ -3,12 +3,12 @@ import React, { useState, useEffect, useRef } from 'react'; import { usePopper } from 'react-popper'; import { useDispatch } from 'react-redux'; -import { simpleEmojiReact } from 'soapbox/actions/emoji_reacts'; +import { simpleEmojiReact } from 'soapbox/actions/emoji-reacts'; import { openModal } from 'soapbox/actions/modals'; import EmojiSelector from 'soapbox/components/ui/emoji-selector/emoji-selector'; import { useAppSelector, useOwnAccount, useSoapboxConfig } from 'soapbox/hooks'; -import { isUserTouching } from 'soapbox/is_mobile'; -import { getReactForStatus } from 'soapbox/utils/emoji_reacts'; +import { isUserTouching } from 'soapbox/is-mobile'; +import { getReactForStatus } from 'soapbox/utils/emoji-reacts'; interface IEmojiButtonWrapper { statusId: string, diff --git a/app/soapbox/components/emoji_selector.tsx b/app/soapbox/components/emoji-selector.tsx similarity index 100% rename from app/soapbox/components/emoji_selector.tsx rename to app/soapbox/components/emoji-selector.tsx diff --git a/app/soapbox/components/error_boundary.tsx b/app/soapbox/components/error-boundary.tsx similarity index 98% rename from app/soapbox/components/error_boundary.tsx rename to app/soapbox/components/error-boundary.tsx index 76adf9728..830f3e679 100644 --- a/app/soapbox/components/error_boundary.tsx +++ b/app/soapbox/components/error-boundary.tsx @@ -3,10 +3,10 @@ import { FormattedMessage } from 'react-intl'; import { connect } from 'react-redux'; import { getSoapboxConfig } from 'soapbox/actions/soapbox'; -import * as BuildConfig from 'soapbox/build_config'; +import * as BuildConfig from 'soapbox/build-config'; import { Text, Stack } from 'soapbox/components/ui'; import { captureException } from 'soapbox/monitoring'; -import KVStore from 'soapbox/storage/kv_store'; +import KVStore from 'soapbox/storage/kv-store'; import sourceCode from 'soapbox/utils/code'; import { unregisterSw } from 'soapbox/utils/sw'; diff --git a/app/soapbox/components/extended-video-player.tsx b/app/soapbox/components/extended-video-player.tsx new file mode 100644 index 000000000..ec7e7f3f4 --- /dev/null +++ b/app/soapbox/components/extended-video-player.tsx @@ -0,0 +1,64 @@ +import React, { useEffect, useRef } from 'react'; + +import { isIOS } from 'soapbox/is-mobile'; + +interface IExtendedVideoPlayer { + src: string, + alt?: string, + width?: number, + height?: number, + time?: number, + controls?: boolean, + muted?: boolean, + onClick?: () => void, +} + +const ExtendedVideoPlayer: React.FC = ({ src, alt, time, controls, muted, onClick }) => { + const video = useRef(null); + + useEffect(() => { + const handleLoadedData = () => { + if (time) { + video.current!.currentTime = time; + } + }; + + video.current?.addEventListener('loadeddata', handleLoadedData); + + return () => { + video.current?.removeEventListener('loadeddata', handleLoadedData); + }; + }, [video.current]); + + const handleClick: React.MouseEventHandler = e => { + e.stopPropagation(); + const handler = onClick; + if (handler) handler(); + }; + + const conditionalAttributes: React.VideoHTMLAttributes = {}; + if (isIOS()) { + conditionalAttributes.playsInline = true; + } + + return ( +
+
+ ); +}; + +export default ExtendedVideoPlayer; diff --git a/app/soapbox/components/extended_video_player.js b/app/soapbox/components/extended_video_player.js deleted file mode 100644 index 59a6b938e..000000000 --- a/app/soapbox/components/extended_video_player.js +++ /dev/null @@ -1,70 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; - -import { isIOS } from 'soapbox/is_mobile'; - -export default class ExtendedVideoPlayer extends React.PureComponent { - - static propTypes = { - src: PropTypes.string.isRequired, - alt: PropTypes.string, - width: PropTypes.number, - height: PropTypes.number, - time: PropTypes.number, - controls: PropTypes.bool.isRequired, - muted: PropTypes.bool.isRequired, - onClick: PropTypes.func, - }; - - handleLoadedData = () => { - if (this.props.time) { - this.video.currentTime = this.props.time; - } - } - - componentDidMount() { - this.video.addEventListener('loadeddata', this.handleLoadedData); - } - - componentWillUnmount() { - this.video.removeEventListener('loadeddata', this.handleLoadedData); - } - - setRef = (c) => { - this.video = c; - } - - handleClick = e => { - e.stopPropagation(); - const handler = this.props.onClick; - if (handler) handler(); - } - - render() { - const { src, muted, controls, alt } = this.props; - const conditionalAttributes = {}; - if (isIOS()) { - conditionalAttributes.playsInline = '1'; - } - - return ( -
-
- ); - } - -} diff --git a/app/soapbox/components/fork_awesome_icon.tsx b/app/soapbox/components/fork-awesome-icon.tsx similarity index 100% rename from app/soapbox/components/fork_awesome_icon.tsx rename to app/soapbox/components/fork-awesome-icon.tsx diff --git a/app/soapbox/components/hashtag.tsx b/app/soapbox/components/hashtag.tsx index 0b0cc5bae..41267d19c 100644 --- a/app/soapbox/components/hashtag.tsx +++ b/app/soapbox/components/hashtag.tsx @@ -1,10 +1,10 @@ import React from 'react'; import { FormattedMessage } from 'react-intl'; +import { Link } from 'react-router-dom'; import { Sparklines, SparklinesCurve } from 'react-sparklines'; import { shortNumberFormat } from '../utils/numbers'; -import Permalink from './permalink'; import { HStack, Stack, Text } from './ui'; import type { Tag } from 'soapbox/types/entities'; @@ -19,9 +19,9 @@ const Hashtag: React.FC = ({ hashtag }) => { return ( - + #{hashtag.name} - + {hashtag.history && ( diff --git a/app/soapbox/components/helmet.tsx b/app/soapbox/components/helmet.tsx index cd13dd30a..ba4a82fd3 100644 --- a/app/soapbox/components/helmet.tsx +++ b/app/soapbox/components/helmet.tsx @@ -3,7 +3,7 @@ import { Helmet as ReactHelmet } from 'react-helmet'; import { useAppSelector, useSettings } from 'soapbox/hooks'; import { RootState } from 'soapbox/store'; -import FaviconService from 'soapbox/utils/favicon_service'; +import FaviconService from 'soapbox/utils/favicon-service'; FaviconService.initFaviconService(); diff --git a/app/soapbox/components/hover_ref_wrapper.tsx b/app/soapbox/components/hover-ref-wrapper.tsx similarity index 94% rename from app/soapbox/components/hover_ref_wrapper.tsx rename to app/soapbox/components/hover-ref-wrapper.tsx index f509b2efe..bcde02720 100644 --- a/app/soapbox/components/hover_ref_wrapper.tsx +++ b/app/soapbox/components/hover-ref-wrapper.tsx @@ -6,9 +6,9 @@ import { fetchAccount } from 'soapbox/actions/accounts'; import { openProfileHoverCard, closeProfileHoverCard, -} from 'soapbox/actions/profile_hover_card'; +} from 'soapbox/actions/profile-hover-card'; import { useAppDispatch } from 'soapbox/hooks'; -import { isMobile } from 'soapbox/is_mobile'; +import { isMobile } from 'soapbox/is-mobile'; const showProfileHoverCard = debounce((dispatch, ref, accountId) => { dispatch(openProfileHoverCard(ref, accountId)); diff --git a/app/soapbox/components/hover-status-wrapper.tsx b/app/soapbox/components/hover-status-wrapper.tsx index da962e47c..a90969da2 100644 --- a/app/soapbox/components/hover-status-wrapper.tsx +++ b/app/soapbox/components/hover-status-wrapper.tsx @@ -7,7 +7,7 @@ import { openStatusHoverCard, closeStatusHoverCard, } from 'soapbox/actions/status-hover-card'; -import { isMobile } from 'soapbox/is_mobile'; +import { isMobile } from 'soapbox/is-mobile'; const showStatusHoverCard = debounce((dispatch, ref, statusId) => { dispatch(openStatusHoverCard(ref, statusId)); diff --git a/app/soapbox/components/icon_button.js b/app/soapbox/components/icon-button.js similarity index 98% rename from app/soapbox/components/icon_button.js rename to app/soapbox/components/icon-button.js index cb92c2841..bdfe157a6 100644 --- a/app/soapbox/components/icon_button.js +++ b/app/soapbox/components/icon-button.js @@ -6,7 +6,7 @@ import spring from 'react-motion/lib/spring'; import Icon from 'soapbox/components/icon'; import emojify from 'soapbox/features/emoji/emoji'; -import Motion from '../features/ui/util/optional_motion'; +import Motion from '../features/ui/util/optional-motion'; export default class IconButton extends React.PureComponent { diff --git a/app/soapbox/components/icon_with_counter.tsx b/app/soapbox/components/icon-with-counter.tsx similarity index 88% rename from app/soapbox/components/icon_with_counter.tsx rename to app/soapbox/components/icon-with-counter.tsx index 2d95cb9f9..7e6a3a007 100644 --- a/app/soapbox/components/icon_with_counter.tsx +++ b/app/soapbox/components/icon-with-counter.tsx @@ -15,9 +15,9 @@ const IconWithCounter: React.FC = ({ icon, count, ...rest }) = {count > 0 && ( - + - + )} ); diff --git a/app/soapbox/components/icon.tsx b/app/soapbox/components/icon.tsx index cba7b5805..f03f40580 100644 --- a/app/soapbox/components/icon.tsx +++ b/app/soapbox/components/icon.tsx @@ -7,8 +7,8 @@ import React from 'react'; -import ForkAwesomeIcon, { IForkAwesomeIcon } from './fork_awesome_icon'; -import SvgIcon, { ISvgIcon } from './svg_icon'; +import ForkAwesomeIcon, { IForkAwesomeIcon } from './fork-awesome-icon'; +import SvgIcon, { ISvgIcon } from './svg-icon'; export type IIcon = IForkAwesomeIcon | ISvgIcon; diff --git a/app/soapbox/components/load_gap.tsx b/app/soapbox/components/load-gap.tsx similarity index 100% rename from app/soapbox/components/load_gap.tsx rename to app/soapbox/components/load-gap.tsx diff --git a/app/soapbox/components/load_more.tsx b/app/soapbox/components/load-more.tsx similarity index 100% rename from app/soapbox/components/load_more.tsx rename to app/soapbox/components/load-more.tsx diff --git a/app/soapbox/components/media_gallery.tsx b/app/soapbox/components/media-gallery.tsx similarity index 99% rename from app/soapbox/components/media_gallery.tsx rename to app/soapbox/components/media-gallery.tsx index f899d7ba4..42b961dc1 100644 --- a/app/soapbox/components/media_gallery.tsx +++ b/app/soapbox/components/media-gallery.tsx @@ -3,14 +3,14 @@ import React, { useState, useRef, useEffect } from 'react'; import Blurhash from 'soapbox/components/blurhash'; import Icon from 'soapbox/components/icon'; -import StillImage from 'soapbox/components/still_image'; +import StillImage from 'soapbox/components/still-image'; import { MIMETYPE_ICONS } from 'soapbox/features/compose/components/upload'; import { useSettings } from 'soapbox/hooks'; import { Attachment } from 'soapbox/types/entities'; import { truncateFilename } from 'soapbox/utils/media'; -import { isIOS } from '../is_mobile'; -import { isPanoramic, isPortrait, isNonConformingRatio, minimumAspectRatio, maximumAspectRatio } from '../utils/media_aspect_ratio'; +import { isIOS } from '../is-mobile'; +import { isPanoramic, isPortrait, isNonConformingRatio, minimumAspectRatio, maximumAspectRatio } from '../utils/media-aspect-ratio'; import type { Property } from 'csstype'; import type { List as ImmutableList } from 'immutable'; @@ -526,7 +526,6 @@ const MediaGallery: React.FC = (props) => { /> )); - useEffect(() => { if (node.current) { const { offsetWidth } = node.current; diff --git a/app/soapbox/components/missing_indicator.tsx b/app/soapbox/components/missing-indicator.tsx similarity index 100% rename from app/soapbox/components/missing_indicator.tsx rename to app/soapbox/components/missing-indicator.tsx diff --git a/app/soapbox/components/modal_root.tsx b/app/soapbox/components/modal-root.tsx similarity index 98% rename from app/soapbox/components/modal_root.tsx rename to app/soapbox/components/modal-root.tsx index f34597d5b..f3cdac7da 100644 --- a/app/soapbox/components/modal_root.tsx +++ b/app/soapbox/components/modal-root.tsx @@ -9,6 +9,7 @@ import { openModal, closeModal } from 'soapbox/actions/modals'; import { useAppDispatch, useAppSelector, usePrevious } from 'soapbox/hooks'; import type { UnregisterCallback } from 'history'; +import type { ModalType } from 'soapbox/features/ui/components/modal-root'; import type { ReducerCompose } from 'soapbox/reducers/compose'; const messages = defineMessages({ @@ -26,8 +27,8 @@ export const checkComposeContent = (compose?: ReturnType) interface IModalRoot { onCancel?: () => void, - onClose: (type?: string) => void, - type: string, + onClose: (type?: ModalType) => void, + type: ModalType, } const ModalRoot: React.FC = ({ children, onCancel, onClose, type }) => { diff --git a/app/soapbox/components/more_follows.tsx b/app/soapbox/components/more_follows.tsx deleted file mode 100644 index f200cd543..000000000 --- a/app/soapbox/components/more_follows.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import React from 'react'; -import { defineMessages, useIntl } from 'react-intl'; - -import { useAppSelector } from 'soapbox/hooks'; -import { getFeatures } from 'soapbox/utils/features'; - -const messages = defineMessages({ - following: { - id: 'morefollows.following_label', - defaultMessage: '…and {count} more {count, plural, one {follow} other {follows}} on remote sites.', - }, - followers: { - id: 'morefollows.followers_label', - defaultMessage: '…and {count} more {count, plural, one {follower} other {followers}} on remote sites.', - }, -}); - -interface IMoreFollows { - visible?: Boolean, - count?: number, - type: 'following' | 'followers', -} - -const MoreFollows: React.FC = ({ visible = true, count, type }) => { - const intl = useIntl(); - const features = useAppSelector((state) => getFeatures(state.instance)); - - const getMessage = () => { - return intl.formatMessage(messages[type], { count }); - }; - - // If the instance isn't federating, there are no remote followers - if (!features.federating) { - return null; - } - - return ( -
-
-
- {getMessage()} -
-
-
- ); -}; - -export default MoreFollows; diff --git a/app/soapbox/components/permalink.tsx b/app/soapbox/components/permalink.tsx deleted file mode 100644 index db68811e5..000000000 --- a/app/soapbox/components/permalink.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import * as React from 'react'; -import { useHistory } from 'react-router-dom'; - -interface IPermaLink extends Pick, 'dangerouslySetInnerHTML'> { - className?: string, - href: string, - title?: string, - to: string, -} - -const Permalink: React.FC = (props) => { - const history = useHistory(); - - const { className, href, title, to, children, ...filteredProps } = props; - - const handleClick = (event: React.MouseEvent) => { - if (event.button === 0 && !(event.ctrlKey || event.metaKey)) { - event.preventDefault(); - history.push(to); - } - }; - - return ( - - {children} - - ); -}; - -export default Permalink; diff --git a/app/soapbox/components/profile-hover-card.tsx b/app/soapbox/components/profile-hover-card.tsx index 5baabeb86..367c788e0 100644 --- a/app/soapbox/components/profile-hover-card.tsx +++ b/app/soapbox/components/profile-hover-card.tsx @@ -8,16 +8,16 @@ import { fetchRelationships } from 'soapbox/actions/accounts'; import { closeProfileHoverCard, updateProfileHoverCard, -} from 'soapbox/actions/profile_hover_card'; +} from 'soapbox/actions/profile-hover-card'; import Badge from 'soapbox/components/badge'; import ActionButton from 'soapbox/features/ui/components/action-button'; -import BundleContainer from 'soapbox/features/ui/containers/bundle_container'; +import BundleContainer from 'soapbox/features/ui/containers/bundle-container'; import { UserPanel } from 'soapbox/features/ui/util/async-components'; import { useAppSelector, useAppDispatch } from 'soapbox/hooks'; import { makeGetAccount } from 'soapbox/selectors'; import { isLocal } from 'soapbox/utils/accounts'; -import { showProfileHoverCard } from './hover_ref_wrapper'; +import { showProfileHoverCard } from './hover-ref-wrapper'; import { Card, CardBody, HStack, Icon, Stack, Text } from './ui'; import type { AppDispatch } from 'soapbox/store'; diff --git a/app/soapbox/components/progress_circle.tsx b/app/soapbox/components/progress-circle.tsx similarity index 100% rename from app/soapbox/components/progress_circle.tsx rename to app/soapbox/components/progress-circle.tsx diff --git a/app/soapbox/components/quoted-status.tsx b/app/soapbox/components/quoted-status.tsx index 863a5d3af..2c976bf86 100644 --- a/app/soapbox/components/quoted-status.tsx +++ b/app/soapbox/components/quoted-status.tsx @@ -1,17 +1,17 @@ import classNames from 'clsx'; -import React, { MouseEventHandler, useState } from 'react'; +import React, { MouseEventHandler, useEffect, useRef, useState } from 'react'; import { defineMessages, useIntl } from 'react-intl'; import { useHistory } from 'react-router-dom'; import StatusMedia from 'soapbox/components/status-media'; import { Stack } from 'soapbox/components/ui'; -import AccountContainer from 'soapbox/containers/account_container'; +import AccountContainer from 'soapbox/containers/account-container'; import { useSettings } from 'soapbox/hooks'; import { defaultMediaVisibility } from 'soapbox/utils/status'; import OutlineBox from './outline-box'; +import StatusContent from './status-content'; import StatusReplyMentions from './status-reply-mentions'; -import StatusContent from './status_content'; import SensitiveContentOverlay from './statuses/sensitive-content-overlay'; import type { Account as AccountEntity, Status as StatusEntity } from 'soapbox/types/entities'; @@ -37,7 +37,16 @@ const QuotedStatus: React.FC = ({ status, onCancel, compose }) => const settings = useSettings(); const displayMedia = settings.get('displayMedia'); + const overlay = useRef(null); + const [showMedia, setShowMedia] = useState(defaultMediaVisibility(status, displayMedia)); + const [minHeight, setMinHeight] = useState(208); + + useEffect(() => { + if (overlay.current) { + setMinHeight(overlay.current.getBoundingClientRect().height); + } + }, [overlay.current]); const handleExpandClick: MouseEventHandler = (e) => { if (!status) return; @@ -103,15 +112,16 @@ const QuotedStatus: React.FC = ({ status, onCancel, compose }) => - {(status.hidden) && ( )} diff --git a/app/soapbox/components/radio_button.tsx b/app/soapbox/components/radio_button.tsx deleted file mode 100644 index 2d350b953..000000000 --- a/app/soapbox/components/radio_button.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import classNames from 'clsx'; -import React from 'react'; - -interface IRadioButton { - value: string, - checked?: boolean, - name: string, - onChange: React.ChangeEventHandler, - label: React.ReactNode, -} - -const RadioButton: React.FC = ({ name, value, checked, onChange, label }) => ( - -); - -export default RadioButton; diff --git a/app/soapbox/components/scrollable_list.tsx b/app/soapbox/components/scrollable-list.tsx similarity index 99% rename from app/soapbox/components/scrollable_list.tsx rename to app/soapbox/components/scrollable-list.tsx index cdb74e580..86e40570e 100644 --- a/app/soapbox/components/scrollable_list.tsx +++ b/app/soapbox/components/scrollable-list.tsx @@ -5,7 +5,7 @@ import { Virtuoso, Components, VirtuosoProps, VirtuosoHandle, ListRange, IndexLo import { useSettings } from 'soapbox/hooks'; -import LoadMore from './load_more'; +import LoadMore from './load-more'; import { Card, Spinner } from './ui'; /** Custom Viruoso component context. */ diff --git a/app/soapbox/components/sidebar_menu.tsx b/app/soapbox/components/sidebar-menu.tsx similarity index 99% rename from app/soapbox/components/sidebar_menu.tsx rename to app/soapbox/components/sidebar-menu.tsx index 817e1f0d2..0e0ae7f6f 100644 --- a/app/soapbox/components/sidebar_menu.tsx +++ b/app/soapbox/components/sidebar-menu.tsx @@ -9,7 +9,7 @@ import { getSettings } from 'soapbox/actions/settings'; import { closeSidebar } from 'soapbox/actions/sidebar'; import Account from 'soapbox/components/account'; import { Stack } from 'soapbox/components/ui'; -import ProfileStats from 'soapbox/features/ui/components/profile_stats'; +import ProfileStats from 'soapbox/features/ui/components/profile-stats'; import { useAppSelector, useFeatures } from 'soapbox/hooks'; import { makeGetAccount, makeGetOtherAccounts } from 'soapbox/selectors'; @@ -228,7 +228,7 @@ const SidebarMenu: React.FC = (): JSX.Element | null => { {features.federating && ( } onClick={onClose} /> diff --git a/app/soapbox/components/sidebar-navigation.tsx b/app/soapbox/components/sidebar-navigation.tsx index 583006070..18c104b16 100644 --- a/app/soapbox/components/sidebar-navigation.tsx +++ b/app/soapbox/components/sidebar-navigation.tsx @@ -2,14 +2,14 @@ import React from 'react'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; import { getSettings } from 'soapbox/actions/settings'; -import DropdownMenu from 'soapbox/containers/dropdown_menu_container'; +import DropdownMenu from 'soapbox/containers/dropdown-menu-container'; import ComposeButton from 'soapbox/features/ui/components/compose-button'; import { useAppSelector, useOwnAccount } from 'soapbox/hooks'; import { getFeatures } from 'soapbox/utils/features'; import SidebarNavigationLink from './sidebar-navigation-link'; -import type { Menu } from 'soapbox/components/dropdown_menu'; +import type { Menu } from 'soapbox/components/dropdown-menu'; const messages = defineMessages({ follow_requests: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' }, @@ -28,7 +28,7 @@ const SidebarNavigation = () => { const instance = useAppSelector((state) => state.instance); const settings = useAppSelector((state) => getSettings(state)); const account = useOwnAccount(); - const notificationCount = useAppSelector((state) => state.notifications.get('unread')); + const notificationCount = useAppSelector((state) => state.notifications.unread); const chatsCount = useAppSelector((state) => state.chats.items.reduce((acc, curr) => acc + Math.min(curr.unread || 0, 1), 0)); const followRequestsCount = useAppSelector((state) => state.user_lists.follow_requests.items.count()); const dashboardCount = useAppSelector((state) => state.admin.openReports.count() + state.admin.awaitingApproval.count()); @@ -97,7 +97,7 @@ const SidebarNavigation = () => { if (features.publicTimeline && features.federating) { menu.push({ to: '/timeline/fediverse', - icon: require('icons/fediverse.svg'), + icon: require('assets/icons/fediverse.svg'), text: intl.formatMessage(messages.fediverse), }); } diff --git a/app/soapbox/components/site-logo.tsx b/app/soapbox/components/site-logo.tsx index 56add1c19..90552d0bd 100644 --- a/app/soapbox/components/site-logo.tsx +++ b/app/soapbox/components/site-logo.tsx @@ -18,8 +18,8 @@ const SiteLogo: React.FC = ({ className, theme, ...rest }) => { /** Soapbox logo. */ const soapboxLogo = darkMode - ? require('images/soapbox-logo-white.svg') - : require('images/soapbox-logo.svg'); + ? require('assets/images/soapbox-logo-white.svg') + : require('assets/images/soapbox-logo.svg'); // Use the right logo if provided, then use fallbacks. const getSrc = () => { diff --git a/app/soapbox/components/status-action-bar.tsx b/app/soapbox/components/status-action-bar.tsx index 9153cb256..011fc63a8 100644 --- a/app/soapbox/components/status-action-bar.tsx +++ b/app/soapbox/components/status-action-bar.tsx @@ -16,12 +16,12 @@ import { initReport } from 'soapbox/actions/reports'; import { deleteStatus, editStatus, toggleMuteStatus } from 'soapbox/actions/statuses'; import EmojiButtonWrapper from 'soapbox/components/emoji-button-wrapper'; import StatusActionButton from 'soapbox/components/status-action-button'; -import DropdownMenuContainer from 'soapbox/containers/dropdown_menu_container'; +import DropdownMenuContainer from 'soapbox/containers/dropdown-menu-container'; import { useAppDispatch, useAppSelector, useFeatures, useOwnAccount, useSettings, useSoapboxConfig } from 'soapbox/hooks'; import { isLocal } from 'soapbox/utils/accounts'; -import { getReactForStatus, reduceEmoji } from 'soapbox/utils/emoji_reacts'; +import { getReactForStatus, reduceEmoji } from 'soapbox/utils/emoji-reacts'; -import type { Menu } from 'soapbox/components/dropdown_menu'; +import type { Menu } from 'soapbox/components/dropdown-menu'; import type { Account, Status } from 'soapbox/types/entities'; const messages = defineMessages({ diff --git a/app/soapbox/components/status-action-button.tsx b/app/soapbox/components/status-action-button.tsx index aacda516f..2f355211b 100644 --- a/app/soapbox/components/status-action-button.tsx +++ b/app/soapbox/components/status-action-button.tsx @@ -41,7 +41,7 @@ const StatusActionButton = React.forwardRef { if (emoji) { return ( - + ); diff --git a/app/soapbox/components/status_content.tsx b/app/soapbox/components/status-content.tsx similarity index 99% rename from app/soapbox/components/status_content.tsx rename to app/soapbox/components/status-content.tsx index b3592c62d..a495a9f82 100644 --- a/app/soapbox/components/status_content.tsx +++ b/app/soapbox/components/status-content.tsx @@ -6,7 +6,7 @@ import { useHistory } from 'react-router-dom'; import Icon from 'soapbox/components/icon'; import { useSoapboxConfig } from 'soapbox/hooks'; import { addGreentext } from 'soapbox/utils/greentext'; -import { onlyEmoji as isOnlyEmoji } from 'soapbox/utils/rich_content'; +import { onlyEmoji as isOnlyEmoji } from 'soapbox/utils/rich-content'; import { isRtl } from '../rtl'; diff --git a/app/soapbox/components/status-hover-card.tsx b/app/soapbox/components/status-hover-card.tsx index 4ae3f705e..37ca117a0 100644 --- a/app/soapbox/components/status-hover-card.tsx +++ b/app/soapbox/components/status-hover-card.tsx @@ -8,7 +8,7 @@ import { updateStatusHoverCard, } from 'soapbox/actions/status-hover-card'; import { fetchStatus } from 'soapbox/actions/statuses'; -import StatusContainer from 'soapbox/containers/status_container'; +import StatusContainer from 'soapbox/containers/status-container'; import { useAppSelector, useAppDispatch } from 'soapbox/hooks'; import { showStatusHoverCard } from './hover-status-wrapper'; diff --git a/app/soapbox/components/status_list.tsx b/app/soapbox/components/status-list.tsx similarity index 97% rename from app/soapbox/components/status_list.tsx rename to app/soapbox/components/status-list.tsx index 09fbe3275..68dba32c6 100644 --- a/app/soapbox/components/status_list.tsx +++ b/app/soapbox/components/status-list.tsx @@ -5,20 +5,20 @@ import React, { useRef, useCallback } from 'react'; import { FormattedMessage } from 'react-intl'; import { v4 as uuidv4 } from 'uuid'; -import LoadGap from 'soapbox/components/load_gap'; -import ScrollableList from 'soapbox/components/scrollable_list'; -import StatusContainer from 'soapbox/containers/status_container'; +import LoadGap from 'soapbox/components/load-gap'; +import ScrollableList from 'soapbox/components/scrollable-list'; +import StatusContainer from 'soapbox/containers/status-container'; import Ad from 'soapbox/features/ads/components/ad'; import FeedSuggestions from 'soapbox/features/feed-suggestions/feed-suggestions'; -import PlaceholderStatus from 'soapbox/features/placeholder/components/placeholder_status'; +import PlaceholderStatus from 'soapbox/features/placeholder/components/placeholder-status'; import { ALGORITHMS } from 'soapbox/features/timeline-insertion'; -import PendingStatus from 'soapbox/features/ui/components/pending_status'; +import PendingStatus from 'soapbox/features/ui/components/pending-status'; import { useSoapboxConfig } from 'soapbox/hooks'; import useAds from 'soapbox/queries/ads'; import type { OrderedSet as ImmutableOrderedSet } from 'immutable'; import type { VirtuosoHandle } from 'react-virtuoso'; -import type { IScrollableList } from 'soapbox/components/scrollable_list'; +import type { IScrollableList } from 'soapbox/components/scrollable-list'; import type { Ad as AdEntity } from 'soapbox/types/soapbox'; interface IStatusList extends Omit { diff --git a/app/soapbox/components/status-media.tsx b/app/soapbox/components/status-media.tsx index 4445e67b5..71177cb12 100644 --- a/app/soapbox/components/status-media.tsx +++ b/app/soapbox/components/status-media.tsx @@ -2,11 +2,12 @@ import React, { useState } from 'react'; import { openModal } from 'soapbox/actions/modals'; import AttachmentThumbs from 'soapbox/components/attachment-thumbs'; -import PlaceholderCard from 'soapbox/features/placeholder/components/placeholder_card'; +import PlaceholderCard from 'soapbox/features/placeholder/components/placeholder-card'; import Card from 'soapbox/features/status/components/card'; import Bundle from 'soapbox/features/ui/components/bundle'; import { MediaGallery, Video, Audio } from 'soapbox/features/ui/util/async-components'; -import { useAppDispatch } from 'soapbox/hooks'; +import { useAppDispatch, useSettings } from 'soapbox/hooks'; +import { addAutoPlay } from 'soapbox/utils/media'; import type { List as ImmutableList } from 'immutable'; import type { Status, Attachment } from 'soapbox/types/entities'; @@ -33,6 +34,9 @@ const StatusMedia: React.FC = ({ onToggleVisibility = () => { }, }) => { const dispatch = useAppDispatch(); + const settings = useSettings(); + const shouldAutoPlayVideo = settings.get('autoPlayVideo'); + const [mediaWrapperWidth, setMediaWrapperWidth] = useState(undefined); const size = status.media_attachments.size; @@ -93,7 +97,9 @@ const StatusMedia: React.FC = ({ ref={setRef} className='status-card__image status-card-video' style={height ? { height } : undefined} - dangerouslySetInnerHTML={{ __html: status.card.html }} + dangerouslySetInnerHTML={{ + __html: shouldAutoPlayVideo ? addAutoPlay(status.card.html) : status.card.html, + }} /> ); diff --git a/app/soapbox/components/status-reply-mentions.tsx b/app/soapbox/components/status-reply-mentions.tsx index 4d65abd11..0964c84ae 100644 --- a/app/soapbox/components/status-reply-mentions.tsx +++ b/app/soapbox/components/status-reply-mentions.tsx @@ -3,8 +3,8 @@ import { FormattedList, FormattedMessage } from 'react-intl'; import { Link } from 'react-router-dom'; import { openModal } from 'soapbox/actions/modals'; +import HoverRefWrapper from 'soapbox/components/hover-ref-wrapper'; import HoverStatusWrapper from 'soapbox/components/hover-status-wrapper'; -import HoverRefWrapper from 'soapbox/components/hover_ref_wrapper'; import { useAppDispatch } from 'soapbox/hooks'; import type { Account, Status } from 'soapbox/types/entities'; @@ -75,7 +75,7 @@ const StatusReplyMentions: React.FC = ({ status, hoverable return (
, diff --git a/app/soapbox/components/status.tsx b/app/soapbox/components/status.tsx index f01ded300..846735dc3 100644 --- a/app/soapbox/components/status.tsx +++ b/app/soapbox/components/status.tsx @@ -10,15 +10,15 @@ import { openModal } from 'soapbox/actions/modals'; import { toggleStatusHidden } from 'soapbox/actions/statuses'; import Icon from 'soapbox/components/icon'; import TranslateButton from 'soapbox/components/translate-button'; -import AccountContainer from 'soapbox/containers/account_container'; -import QuotedStatus from 'soapbox/features/status/containers/quoted_status_container'; +import AccountContainer from 'soapbox/containers/account-container'; +import QuotedStatus from 'soapbox/features/status/containers/quoted-status-container'; import { useAppDispatch, useSettings } from 'soapbox/hooks'; import { defaultMediaVisibility, textForScreenReader, getActualStatus } from 'soapbox/utils/status'; import StatusActionBar from './status-action-bar'; +import StatusContent from './status-content'; import StatusMedia from './status-media'; import StatusReplyMentions from './status-reply-mentions'; -import StatusContent from './status_content'; import SensitiveContentOverlay from './statuses/sensitive-content-overlay'; import { Card, HStack, Stack, Text } from './ui'; @@ -79,8 +79,10 @@ const Status: React.FC = (props) => { const displayMedia = settings.get('displayMedia') as string; const didShowCard = useRef(false); const node = useRef(null); + const overlay = useRef(null); const [showMedia, setShowMedia] = useState(defaultMediaVisibility(status, displayMedia)); + const [minHeight, setMinHeight] = useState(208); const actualStatus = getActualStatus(status); @@ -95,6 +97,12 @@ const Status: React.FC = (props) => { setShowMedia(defaultMediaVisibility(status, displayMedia)); }, [status.id]); + useEffect(() => { + if (overlay.current) { + setMinHeight(overlay.current.getBoundingClientRect().height); + } + }, [overlay.current]); + const handleToggleMediaVisibility = (): void => { setShowMedia(!showMedia); }; @@ -102,6 +110,11 @@ const Status: React.FC = (props) => { const handleClick = (e?: React.MouseEvent): void => { e?.stopPropagation(); + // If the user is selecting text, don't focus the status. + if (getSelection()?.toString().length) { + return; + } + if (!e || !(e.ctrlKey || e.metaKey)) { if (onClick) { onClick(); @@ -313,7 +326,7 @@ const Status: React.FC = (props) => { data-featured={featured ? 'true' : null} aria-label={textForScreenReader(intl, actualStatus, rebloggedByText)} ref={node} - onClick={handleClick} + onMouseUp={handleClick} role='link' > {featured && ( @@ -358,17 +371,15 @@ const Status: React.FC = (props) => { {(isUnderReview || isSensitive) && ( )} diff --git a/app/soapbox/components/statuses/sensitive-content-overlay.tsx b/app/soapbox/components/statuses/sensitive-content-overlay.tsx index 5239192fc..59faef161 100644 --- a/app/soapbox/components/statuses/sensitive-content-overlay.tsx +++ b/app/soapbox/components/statuses/sensitive-content-overlay.tsx @@ -25,7 +25,7 @@ interface ISensitiveContentOverlay { visible?: boolean } -const SensitiveContentOverlay = (props: ISensitiveContentOverlay) => { +const SensitiveContentOverlay = React.forwardRef((props, ref) => { const { onToggleVisibility, status } = props; const isUnderReview = status.visibility === 'self'; @@ -72,7 +72,7 @@ const SensitiveContentOverlay = (props: ISensitiveContentOverlay) => { size='sm' /> ) : ( -
+
{intl.formatMessage(isUnderReview ? messages.underReviewTitle : messages.sensitiveTitle)} @@ -84,7 +84,7 @@ const SensitiveContentOverlay = (props: ISensitiveContentOverlay) => { {status.spoiler_text && (
- +
@@ -127,6 +127,6 @@ const SensitiveContentOverlay = (props: ISensitiveContentOverlay) => { )}
); -}; +}); -export default SensitiveContentOverlay; \ No newline at end of file +export default SensitiveContentOverlay; diff --git a/app/soapbox/components/still_image.tsx b/app/soapbox/components/still-image.tsx similarity index 100% rename from app/soapbox/components/still_image.tsx rename to app/soapbox/components/still-image.tsx diff --git a/app/soapbox/components/sub_navigation.tsx b/app/soapbox/components/sub-navigation.tsx similarity index 100% rename from app/soapbox/components/sub_navigation.tsx rename to app/soapbox/components/sub-navigation.tsx diff --git a/app/soapbox/components/svg_icon.tsx b/app/soapbox/components/svg-icon.tsx similarity index 100% rename from app/soapbox/components/svg_icon.tsx rename to app/soapbox/components/svg-icon.tsx diff --git a/app/soapbox/components/thumb_navigation-link.tsx b/app/soapbox/components/thumb-navigation-link.tsx similarity index 96% rename from app/soapbox/components/thumb_navigation-link.tsx rename to app/soapbox/components/thumb-navigation-link.tsx index 58a55e7e6..069849507 100644 --- a/app/soapbox/components/thumb_navigation-link.tsx +++ b/app/soapbox/components/thumb-navigation-link.tsx @@ -2,7 +2,7 @@ import classNames from 'clsx'; import React from 'react'; import { NavLink, useLocation } from 'react-router-dom'; -import IconWithCounter from 'soapbox/components/icon_with_counter'; +import IconWithCounter from 'soapbox/components/icon-with-counter'; import { Icon, Text } from 'soapbox/components/ui'; interface IThumbNavigationLink { diff --git a/app/soapbox/components/thumb_navigation.tsx b/app/soapbox/components/thumb-navigation.tsx similarity index 97% rename from app/soapbox/components/thumb_navigation.tsx rename to app/soapbox/components/thumb-navigation.tsx index e46f7c7c3..45a980f86 100644 --- a/app/soapbox/components/thumb_navigation.tsx +++ b/app/soapbox/components/thumb-navigation.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { FormattedMessage } from 'react-intl'; -import ThumbNavigationLink from 'soapbox/components/thumb_navigation-link'; +import ThumbNavigationLink from 'soapbox/components/thumb-navigation-link'; import { useAppSelector, useOwnAccount } from 'soapbox/hooks'; import { getFeatures } from 'soapbox/utils/features'; diff --git a/app/soapbox/components/ui/accordion/accordion.tsx b/app/soapbox/components/ui/accordion/accordion.tsx new file mode 100644 index 000000000..299848d84 --- /dev/null +++ b/app/soapbox/components/ui/accordion/accordion.tsx @@ -0,0 +1,74 @@ +import classNames from 'clsx'; +import React from 'react'; +import { defineMessages, useIntl } from 'react-intl'; + +import { HStack, Icon, Text } from 'soapbox/components/ui'; +import DropdownMenu from 'soapbox/containers/dropdown-menu-container'; + +import type { Menu } from 'soapbox/components/dropdown-menu'; + +const messages = defineMessages({ + collapse: { id: 'accordion.collapse', defaultMessage: 'Collapse' }, + expand: { id: 'accordion.expand', defaultMessage: 'Expand' }, +}); + +interface IAccordion { + headline: React.ReactNode, + children?: React.ReactNode, + menu?: Menu, + expanded?: boolean, + onToggle?: (value: boolean) => void, +} + +/** + * Accordion + * An accordion is a vertically stacked group of collapsible sections. + */ +const Accordion: React.FC = ({ headline, children, menu, expanded = false, onToggle = () => {} }) => { + const intl = useIntl(); + + const handleToggle = (e: React.MouseEvent) => { + onToggle(!expanded); + e.preventDefault(); + }; + + return ( +
+ + +
+ {children} +
+
+ ); +}; + +export default Accordion; diff --git a/app/soapbox/components/ui/avatar/avatar.tsx b/app/soapbox/components/ui/avatar/avatar.tsx index bdd38df9c..ec1980978 100644 --- a/app/soapbox/components/ui/avatar/avatar.tsx +++ b/app/soapbox/components/ui/avatar/avatar.tsx @@ -1,7 +1,7 @@ import classNames from 'clsx'; import * as React from 'react'; -import StillImage from 'soapbox/components/still_image'; +import StillImage from 'soapbox/components/still-image'; const AVATAR_SIZE = 42; diff --git a/app/soapbox/components/ui/index.ts b/app/soapbox/components/ui/index.ts index fd9cb055e..90f5933ed 100644 --- a/app/soapbox/components/ui/index.ts +++ b/app/soapbox/components/ui/index.ts @@ -1,3 +1,4 @@ +export { default as Accordion } from './accordion/accordion'; export { default as Avatar } from './avatar/avatar'; export { default as Banner } from './banner/banner'; export { default as Button } from './button/button'; @@ -30,6 +31,7 @@ export { export { default as Modal } from './modal/modal'; export { default as PhoneInput } from './phone-input/phone-input'; export { default as ProgressBar } from './progress-bar/progress-bar'; +export { default as RadioButton } from './radio-button/radio-button'; export { default as Select } from './select/select'; export { default as Spinner } from './spinner/spinner'; export { default as Stack } from './stack/stack'; diff --git a/app/soapbox/components/ui/radio-button/radio-button.tsx b/app/soapbox/components/ui/radio-button/radio-button.tsx new file mode 100644 index 000000000..322cbd7e7 --- /dev/null +++ b/app/soapbox/components/ui/radio-button/radio-button.tsx @@ -0,0 +1,37 @@ +import React, { useMemo } from 'react'; +import { v4 as uuidv4 } from 'uuid'; + +interface IRadioButton { + value: string + checked?: boolean + name: string + onChange: React.ChangeEventHandler + label: React.ReactNode +} + +/** + * A group for radio input with label. + */ +const RadioButton: React.FC = ({ name, value, checked, onChange, label }) => { + const formFieldId: string = useMemo(() => `radio-${uuidv4()}`, []); + + return ( +
+ + + +
+ ); +}; + +export default RadioButton; diff --git a/app/soapbox/components/ui/tooltip/tooltip.tsx b/app/soapbox/components/ui/tooltip/tooltip.tsx index e04221200..02a811bac 100644 --- a/app/soapbox/components/ui/tooltip/tooltip.tsx +++ b/app/soapbox/components/ui/tooltip/tooltip.tsx @@ -1,4 +1,4 @@ -import Portal from '@reach/portal'; +import { Portal } from '@reach/portal'; import { TooltipPopup, useTooltip } from '@reach/tooltip'; import React from 'react'; diff --git a/app/soapbox/components/upload-progress.tsx b/app/soapbox/components/upload-progress.tsx index a7996e1bf..fe9b84797 100644 --- a/app/soapbox/components/upload-progress.tsx +++ b/app/soapbox/components/upload-progress.tsx @@ -3,7 +3,7 @@ import { FormattedMessage } from 'react-intl'; import { spring } from 'react-motion'; import { HStack, Icon, Stack, Text } from 'soapbox/components/ui'; -import Motion from 'soapbox/features/ui/util/optional_motion'; +import Motion from 'soapbox/features/ui/util/optional-motion'; interface IUploadProgress { /** Number between 0 and 1 to represent the percentage complete. */ diff --git a/app/soapbox/components/verification_badge.tsx b/app/soapbox/components/verification-badge.tsx similarity index 91% rename from app/soapbox/components/verification_badge.tsx rename to app/soapbox/components/verification-badge.tsx index ce1d3792a..766decb88 100644 --- a/app/soapbox/components/verification_badge.tsx +++ b/app/soapbox/components/verification-badge.tsx @@ -18,7 +18,7 @@ const VerificationBadge: React.FC = ({ className }) => { const soapboxConfig = useSoapboxConfig(); // Prefer a custom icon if found - const icon = soapboxConfig.verifiedIcon || require('icons/verified.svg'); + const icon = soapboxConfig.verifiedIcon || require('assets/icons/verified.svg'); // Render component based on file extension const Element = icon.endsWith('.svg') ? Icon : 'img'; diff --git a/app/soapbox/containers/account_container.js b/app/soapbox/containers/account-container.js similarity index 100% rename from app/soapbox/containers/account_container.js rename to app/soapbox/containers/account-container.js diff --git a/app/soapbox/containers/dropdown_menu_container.ts b/app/soapbox/containers/dropdown-menu-container.ts similarity index 89% rename from app/soapbox/containers/dropdown_menu_container.ts rename to app/soapbox/containers/dropdown-menu-container.ts index b047edfff..936e3c5c2 100644 --- a/app/soapbox/containers/dropdown_menu_container.ts +++ b/app/soapbox/containers/dropdown-menu-container.ts @@ -1,12 +1,12 @@ import { connect } from 'react-redux'; -import { openDropdownMenu, closeDropdownMenu } from '../actions/dropdown_menu'; +import { openDropdownMenu, closeDropdownMenu } from '../actions/dropdown-menu'; import { openModal, closeModal } from '../actions/modals'; -import DropdownMenu from '../components/dropdown_menu'; -import { isUserTouching } from '../is_mobile'; +import DropdownMenu from '../components/dropdown-menu'; +import { isUserTouching } from '../is-mobile'; import type { Dispatch } from 'redux'; -import type { DropdownPlacement, IDropdown } from 'soapbox/components/dropdown_menu'; +import type { DropdownPlacement, IDropdown } from 'soapbox/components/dropdown-menu'; import type { RootState } from 'soapbox/store'; const mapStateToProps = (state: RootState) => ({ diff --git a/app/soapbox/containers/soapbox.tsx b/app/soapbox/containers/soapbox.tsx index 2841ec3ca..f1623f585 100644 --- a/app/soapbox/containers/soapbox.tsx +++ b/app/soapbox/containers/soapbox.tsx @@ -13,14 +13,14 @@ import { loadInstance } from 'soapbox/actions/instance'; import { fetchMe } from 'soapbox/actions/me'; import { loadSoapboxConfig, getSoapboxConfig } from 'soapbox/actions/soapbox'; import { fetchVerificationConfig } from 'soapbox/actions/verification'; -import * as BuildConfig from 'soapbox/build_config'; +import * as BuildConfig from 'soapbox/build-config'; import GdprBanner from 'soapbox/components/gdpr-banner'; import Helmet from 'soapbox/components/helmet'; import LoadingScreen from 'soapbox/components/loading-screen'; -import AuthLayout from 'soapbox/features/auth_layout'; +import AuthLayout from 'soapbox/features/auth-layout'; import EmbeddedStatus from 'soapbox/features/embedded-status'; -import PublicLayout from 'soapbox/features/public_layout'; -import BundleContainer from 'soapbox/features/ui/containers/bundle_container'; +import PublicLayout from 'soapbox/features/public-layout'; +import BundleContainer from 'soapbox/features/ui/containers/bundle-container'; import { ModalContainer, NotificationsContainer, @@ -45,7 +45,7 @@ import { generateThemeCss } from 'soapbox/utils/theme'; import { checkOnboardingStatus } from '../actions/onboarding'; import { preload } from '../actions/preload'; -import ErrorBoundary from '../components/error_boundary'; +import ErrorBoundary from '../components/error-boundary'; import UI from '../features/ui'; import { store } from '../store'; diff --git a/app/soapbox/containers/status_container.tsx b/app/soapbox/containers/status-container.tsx similarity index 100% rename from app/soapbox/containers/status_container.tsx rename to app/soapbox/containers/status-container.tsx diff --git a/app/soapbox/custom.ts b/app/soapbox/custom.ts index 4bccb386d..461f64845 100644 --- a/app/soapbox/custom.ts +++ b/app/soapbox/custom.ts @@ -1,7 +1,7 @@ /** * Functions for dealing with custom build configuration. */ -import * as BuildConfig from 'soapbox/build_config'; +import * as BuildConfig from 'soapbox/build-config'; /** Require a custom JSON file if it exists */ export const custom = (filename: string, fallback: any = {}): any => { diff --git a/app/soapbox/extra_polyfills.ts b/app/soapbox/extra-polyfills.ts similarity index 100% rename from app/soapbox/extra_polyfills.ts rename to app/soapbox/extra-polyfills.ts diff --git a/app/soapbox/features/about/index.tsx b/app/soapbox/features/about/index.tsx index 5c184a97a..9cc1e9295 100644 --- a/app/soapbox/features/about/index.tsx +++ b/app/soapbox/features/about/index.tsx @@ -35,11 +35,11 @@ const AboutPage: React.FC = () => { }, [locale, slug]); const alsoAvailable = (defaultLocale) && ( -
+
{' '} -