diff --git a/.madgerc b/.madgerc new file mode 100644 index 000000000..7d1dcdca0 --- /dev/null +++ b/.madgerc @@ -0,0 +1,3 @@ +{ + "fileExtensions": ["ts", "tsx"] +} \ No newline at end of file diff --git a/src/actions/compose-status.ts b/src/actions/compose-status.ts new file mode 100644 index 000000000..9a0fbf9c6 --- /dev/null +++ b/src/actions/compose-status.ts @@ -0,0 +1,38 @@ +import { AppDispatch, RootState } from 'soapbox/store'; +import { getFeatures, parseVersion } from 'soapbox/utils/features'; + +import type { Status } from 'soapbox/types/entities'; + +export const COMPOSE_SET_STATUS = 'COMPOSE_SET_STATUS' as const; + +export interface ComposeSetStatusAction { + type: typeof COMPOSE_SET_STATUS; + id: string; + status: Status; + rawText: string; + explicitAddressing: boolean; + spoilerText?: string; + contentType?: string | false; + v: ReturnType; + withRedraft?: boolean; +} + +export const setComposeToStatus = (status: Status, rawText: string, spoilerText?: string, contentType?: string | false, withRedraft?: boolean) => + (dispatch: AppDispatch, getState: () => RootState) => { + const { instance } = getState(); + const { explicitAddressing } = getFeatures(instance); + + const action: ComposeSetStatusAction = { + type: COMPOSE_SET_STATUS, + id: 'compose-modal', + status, + rawText, + explicitAddressing, + spoilerText, + contentType, + v: parseVersion(instance.version), + withRedraft, + }; + + dispatch(action); + }; \ No newline at end of file diff --git a/src/actions/compose.ts b/src/actions/compose.ts index 9e087f293..bdf02fe0a 100644 --- a/src/actions/compose.ts +++ b/src/actions/compose.ts @@ -11,8 +11,9 @@ import { selectAccount, selectOwnAccount } from 'soapbox/selectors'; import { tagHistory } from 'soapbox/settings'; import toast from 'soapbox/toast'; import { isLoggedIn } from 'soapbox/utils/auth'; -import { getFeatures, parseVersion } from 'soapbox/utils/features'; +import { getFeatures } from 'soapbox/utils/features'; +import { ComposeSetStatusAction } from './compose-status'; import { chooseEmoji } from './emojis'; import { importFetchedAccounts } from './importer'; import { uploadFile, updateMedia } from './media'; @@ -85,8 +86,6 @@ const COMPOSE_SCHEDULE_REMOVE = 'COMPOSE_SCHEDULE_REMOVE' as const; const COMPOSE_ADD_TO_MENTIONS = 'COMPOSE_ADD_TO_MENTIONS' as const; const COMPOSE_REMOVE_FROM_MENTIONS = 'COMPOSE_REMOVE_FROM_MENTIONS' as const; -const COMPOSE_SET_STATUS = 'COMPOSE_SET_STATUS' as const; - const COMPOSE_EDITOR_STATE_SET = 'COMPOSE_EDITOR_STATE_SET' as const; const COMPOSE_CHANGE_MEDIA_ORDER = 'COMPOSE_CHANGE_MEDIA_ORDER' as const; @@ -102,38 +101,6 @@ const messages = defineMessages({ replyMessage: { id: 'confirmations.reply.message', defaultMessage: 'Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?' }, }); -interface ComposeSetStatusAction { - type: typeof COMPOSE_SET_STATUS; - id: string; - status: Status; - rawText: string; - explicitAddressing: boolean; - spoilerText?: string; - contentType?: string | false; - v: ReturnType; - withRedraft?: boolean; -} - -const setComposeToStatus = (status: Status, rawText: string, spoilerText?: string, contentType?: string | false, withRedraft?: boolean) => - (dispatch: AppDispatch, getState: () => RootState) => { - const { instance } = getState(); - const { explicitAddressing } = getFeatures(instance); - - const action: ComposeSetStatusAction = { - type: COMPOSE_SET_STATUS, - id: 'compose-modal', - status, - rawText, - explicitAddressing, - spoilerText, - contentType, - v: parseVersion(instance.version), - withRedraft, - }; - - dispatch(action); - }; - const changeCompose = (composeId: string, text: string) => ({ type: COMPOSE_CHANGE, id: composeId, @@ -952,11 +919,9 @@ export { COMPOSE_SCHEDULE_REMOVE, COMPOSE_ADD_TO_MENTIONS, COMPOSE_REMOVE_FROM_MENTIONS, - COMPOSE_SET_STATUS, COMPOSE_EDITOR_STATE_SET, COMPOSE_SET_GROUP_TIMELINE_VISIBLE, COMPOSE_CHANGE_MEDIA_ORDER, - setComposeToStatus, changeCompose, replyCompose, cancelReplyCompose, diff --git a/src/actions/statuses.ts b/src/actions/statuses.ts index 78b4a8390..db1bfdb47 100644 --- a/src/actions/statuses.ts +++ b/src/actions/statuses.ts @@ -4,7 +4,7 @@ import { shouldHaveCard } from 'soapbox/utils/status'; import api, { getNextLink } from '../api'; -import { setComposeToStatus } from './compose'; +import { setComposeToStatus } from './compose-status'; import { fetchGroupRelationships } from './groups'; import { importFetchedStatus, importFetchedStatuses } from './importer'; import { openModal } from './modals'; diff --git a/src/components/polls/poll-footer.tsx b/src/components/polls/poll-footer.tsx index 402216a71..9fc40b073 100644 --- a/src/components/polls/poll-footer.tsx +++ b/src/components/polls/poll-footer.tsx @@ -7,7 +7,6 @@ import { useAppDispatch } from 'soapbox/hooks'; import RelativeTimestamp from '../relative-timestamp'; import { Button, HStack, Stack, Text, Tooltip } from '../ui'; -import type { Selected } from './poll'; import type { Poll as PollEntity } from 'soapbox/types/entities'; const messages = defineMessages({ @@ -18,7 +17,7 @@ const messages = defineMessages({ interface IPollFooter { poll: PollEntity; showResults: boolean; - selected: Selected; + selected: Record; } const PollFooter: React.FC = ({ poll, showResults, selected }): JSX.Element => { diff --git a/src/components/polls/poll.tsx b/src/components/polls/poll.tsx index 45336a05c..b7f75424a 100644 --- a/src/components/polls/poll.tsx +++ b/src/components/polls/poll.tsx @@ -10,8 +10,6 @@ import { Stack, Text } from '../ui'; import PollFooter from './poll-footer'; import PollOption from './poll-option'; -export type Selected = Record; - interface IPoll { id: string; status?: string; @@ -28,7 +26,7 @@ const Poll: React.FC = ({ id, status }): JSX.Element | null => { const isLoggedIn = useAppSelector((state) => state.me); const poll = useAppSelector((state) => state.polls.get(id)); - const [selected, setSelected] = useState({} as Selected); + const [selected, setSelected] = useState>({}); const openUnauthorizedModal = () => dispatch(openModal('UNAUTHORIZED', { @@ -49,7 +47,7 @@ const Poll: React.FC = ({ id, status }): JSX.Element | null => { } setSelected(tmp); } else { - const tmp: Selected = {}; + const tmp: Record = {}; tmp[value] = true; setSelected(tmp); handleVote(value); diff --git a/src/features/group/components/group-member-list-item.tsx b/src/features/group/components/group-member-list-item.tsx index eea6514f8..f1102965c 100644 --- a/src/features/group/components/group-member-list-item.tsx +++ b/src/features/group/components/group-member-list-item.tsx @@ -14,8 +14,7 @@ import PlaceholderAccount from 'soapbox/features/placeholder/components/placehol import { useAppDispatch, useFeatures } from 'soapbox/hooks'; import { GroupRoles } from 'soapbox/schemas/group-member'; import toast from 'soapbox/toast'; - -import { MAX_ADMIN_COUNT } from '../group-members'; +import { MAX_ADMIN_COUNT } from 'soapbox/utils/groups'; import type { Menu as IMenu } from 'soapbox/components/dropdown-menu'; import type { Group, GroupMember } from 'soapbox/types/entities'; diff --git a/src/features/group/group-members.tsx b/src/features/group/group-members.tsx index 360f2c599..0d08d82e8 100644 --- a/src/features/group/group-members.tsx +++ b/src/features/group/group-members.tsx @@ -6,6 +6,7 @@ import { PendingItemsRow } from 'soapbox/components/pending-items-row'; import ScrollableList from 'soapbox/components/scrollable-list'; import { useFeatures } from 'soapbox/hooks'; import { GroupRoles } from 'soapbox/schemas/group-member'; +import { MAX_ADMIN_COUNT } from 'soapbox/utils/groups'; import PlaceholderAccount from '../placeholder/components/placeholder-account'; @@ -18,8 +19,6 @@ interface IGroupMembers { params: { groupId: string }; } -export const MAX_ADMIN_COUNT = 5; - const GroupMembers: React.FC = (props) => { const { groupId } = props.params; diff --git a/src/features/ui/components/modals/nostr-signup-modal/nostr-signup-modal.tsx b/src/features/ui/components/modals/nostr-signup-modal/nostr-signup-modal.tsx index dcbd516f7..ab4b5d5a7 100644 --- a/src/features/ui/components/modals/nostr-signup-modal/nostr-signup-modal.tsx +++ b/src/features/ui/components/modals/nostr-signup-modal/nostr-signup-modal.tsx @@ -29,5 +29,3 @@ const NostrSignUpModal: React.FC = ({ onClose }) => { }; export default NostrSignUpModal; - -export type { Step }; diff --git a/src/features/ui/components/modals/nostr-signup-modal/steps/key-step.tsx b/src/features/ui/components/modals/nostr-signup-modal/steps/key-step.tsx index 272992fc9..f3fd6d0b9 100644 --- a/src/features/ui/components/modals/nostr-signup-modal/steps/key-step.tsx +++ b/src/features/ui/components/modals/nostr-signup-modal/steps/key-step.tsx @@ -7,10 +7,9 @@ import { Button, Stack, Modal, Text, Divider } from 'soapbox/components/ui'; import { useAppDispatch } from 'soapbox/hooks'; import NostrExtensionIndicator from '../../nostr-login-modal/components/nostr-extension-indicator'; -import { Step } from '../nostr-signup-modal'; interface IKeyStep { - setStep(step: Step): void; + setStep(step: 'extension' | 'key' | 'keygen'): void; onClose(): void; } diff --git a/src/reducers/compose.test.ts b/src/reducers/compose.test.ts index 181e3b335..cee5e7170 100644 --- a/src/reducers/compose.test.ts +++ b/src/reducers/compose.test.ts @@ -1,6 +1,7 @@ import { List as ImmutableList, Record as ImmutableRecord, fromJS } from 'immutable'; import * as actions from 'soapbox/actions/compose'; +import { COMPOSE_SET_STATUS } from 'soapbox/actions/compose-status'; import { ME_FETCH_SUCCESS, ME_PATCH_SUCCESS } from 'soapbox/actions/me'; import { SETTING_CHANGE } from 'soapbox/actions/settings'; import { TIMELINE_DELETE } from 'soapbox/actions/timelines'; @@ -43,7 +44,7 @@ describe('compose reducer', () => { const status = await import('soapbox/__fixtures__/pleroma-status-deleted.json'); const action = { - type: actions.COMPOSE_SET_STATUS, + type: COMPOSE_SET_STATUS, id: 'compose-modal', status: normalizeStatus(fromJS(status)), v: { software: 'Pleroma' }, @@ -58,7 +59,7 @@ describe('compose reducer', () => { const status = await import('soapbox/__fixtures__/pleroma-status-deleted.json'); const action = { - type: actions.COMPOSE_SET_STATUS, + type: COMPOSE_SET_STATUS, id: 'compose-modal', status: normalizeStatus(fromJS(status)), }; @@ -73,7 +74,7 @@ describe('compose reducer', () => { const action = { id: 'compose-modal', withRedraft: false, - type: actions.COMPOSE_SET_STATUS, + type: COMPOSE_SET_STATUS, status: normalizeStatus(fromJS(status)), }; @@ -87,7 +88,7 @@ describe('compose reducer', () => { const action = { id: 'compose-modal', withRedraft: true, - type: actions.COMPOSE_SET_STATUS, + type: COMPOSE_SET_STATUS, status: normalizeStatus(fromJS(status)), }; diff --git a/src/reducers/compose.ts b/src/reducers/compose.ts index 69ecc5b2b..bf9ac0d83 100644 --- a/src/reducers/compose.ts +++ b/src/reducers/compose.ts @@ -48,13 +48,13 @@ import { COMPOSE_POLL_SETTINGS_CHANGE, COMPOSE_ADD_TO_MENTIONS, COMPOSE_REMOVE_FROM_MENTIONS, - COMPOSE_SET_STATUS, COMPOSE_EVENT_REPLY, COMPOSE_EDITOR_STATE_SET, COMPOSE_SET_GROUP_TIMELINE_VISIBLE, ComposeAction, COMPOSE_CHANGE_MEDIA_ORDER, } from '../actions/compose'; +import { COMPOSE_SET_STATUS } from '../actions/compose-status'; import { EVENT_COMPOSE_CANCEL, EVENT_FORM_SET, type EventsAction } from '../actions/events'; import { ME_FETCH_SUCCESS, ME_PATCH_SUCCESS, MeAction } from '../actions/me'; import { SETTING_CHANGE, FE_NAME, SettingsAction } from '../actions/settings'; diff --git a/src/utils/groups.ts b/src/utils/groups.ts index 28264e090..5430d636c 100644 --- a/src/utils/groups.ts +++ b/src/utils/groups.ts @@ -1,5 +1,7 @@ import { groupSearchHistory } from 'soapbox/settings'; +export const MAX_ADMIN_COUNT = 5; + const RECENT_SEARCHES_KEY = 'soapbox:recent-group-searches'; const clearRecentGroupSearches = (currentUserId: string) => groupSearchHistory.remove(currentUserId);