From 706e303547b501485f02eed093858593d495ecb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Fri, 16 Sep 2022 21:02:15 +0200 Subject: [PATCH] Show compose form on event discussion page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- app/soapbox/actions/compose.ts | 16 +++++++ .../features/aliases/components/account.tsx | 2 +- .../compose/components/compose-form.tsx | 9 ++-- .../containers/quoted_status_container.tsx | 2 +- .../features/event/event-discussion.tsx | 48 +++++++++---------- .../components/account_authorize.tsx | 2 +- .../reducers/__tests__/compose.test.ts | 6 +++ app/soapbox/reducers/compose.ts | 2 +- 8 files changed, 55 insertions(+), 32 deletions(-) diff --git a/app/soapbox/actions/compose.ts b/app/soapbox/actions/compose.ts index ab4d47b97..df519fe6c 100644 --- a/app/soapbox/actions/compose.ts +++ b/app/soapbox/actions/compose.ts @@ -717,6 +717,21 @@ const removeFromMentions = (composeId: string, accountId: string) => }); }; +const eventDiscussionCompose = (composeId: string, status: Status) => + (dispatch: AppDispatch, getState: () => RootState) => { + const state = getState(); + const instance = state.instance; + const { explicitAddressing } = getFeatures(instance); + + dispatch({ + type: COMPOSE_REPLY, + id: composeId, + status: status, + account: state.accounts.get(state.me), + explicitAddressing, + }); + }; + export { COMPOSE_CHANGE, COMPOSE_SUBMIT_REQUEST, @@ -812,4 +827,5 @@ export { openComposeWithText, addToMentions, removeFromMentions, + eventDiscussionCompose, }; diff --git a/app/soapbox/features/aliases/components/account.tsx b/app/soapbox/features/aliases/components/account.tsx index be9178b8d..802d3e0f6 100644 --- a/app/soapbox/features/aliases/components/account.tsx +++ b/app/soapbox/features/aliases/components/account.tsx @@ -23,7 +23,7 @@ interface IAccount { const Account: React.FC = ({ accountId, aliases }) => { const intl = useIntl(); const dispatch = useAppDispatch(); - + const getAccount = useCallback(makeGetAccount(), []); const account = useAppSelector((state) => getAccount(state, accountId)); diff --git a/app/soapbox/features/compose/components/compose-form.tsx b/app/soapbox/features/compose/components/compose-form.tsx index d4b6a4406..52fff1deb 100644 --- a/app/soapbox/features/compose/components/compose-form.tsx +++ b/app/soapbox/features/compose/components/compose-form.tsx @@ -61,9 +61,10 @@ interface IComposeForm { shouldCondense?: boolean, autoFocus?: boolean, clickableAreaRef?: React.RefObject, + eventDiscussion?: boolean } -const ComposeForm: React.FC = ({ id, shouldCondense, autoFocus, clickableAreaRef }) => { +const ComposeForm: React.FC = ({ id, shouldCondense, autoFocus, clickableAreaRef, eventDiscussion }) => { const history = useHistory(); const intl = useIntl(); const dispatch = useAppDispatch(); @@ -264,7 +265,7 @@ const ComposeForm: React.FC = ({ id, shouldCondense, autoFocus, cl return ( - {scheduledStatusCount > 0 && ( + {scheduledStatusCount > 0 && !eventDiscussion && ( = ({ id, shouldCondense, autoFocus, cl - {!shouldCondense && } + {!shouldCondense && !eventDiscussion && } - {!shouldCondense && } + {!shouldCondense && !eventDiscussion && }
= ({ composeId }) => { const dispatch = useAppDispatch(); const getStatus = useCallback(makeGetStatus(), []); - + const status = useAppSelector(state => getStatus(state, { id: state.compose.get(composeId)?.quote! })); const onCancel = () => { diff --git a/app/soapbox/features/event/event-discussion.tsx b/app/soapbox/features/event/event-discussion.tsx index 62c90ae65..1ee361799 100644 --- a/app/soapbox/features/event/event-discussion.tsx +++ b/app/soapbox/features/event/event-discussion.tsx @@ -3,9 +3,9 @@ import debounce from 'lodash/debounce'; import React, { useCallback, useEffect, useRef, useState } from 'react'; import { createSelector } from 'reselect'; +import { eventDiscussionCompose } from 'soapbox/actions/compose'; import { fetchStatusWithContext, fetchNext } from 'soapbox/actions/statuses'; import MissingIndicator from 'soapbox/components/missing_indicator'; -import PullToRefresh from 'soapbox/components/pull-to-refresh'; import ScrollableList from 'soapbox/components/scrollable_list'; import Tombstone from 'soapbox/components/tombstone'; import { Stack } from 'soapbox/components/ui'; @@ -14,6 +14,7 @@ import PendingStatus from 'soapbox/features/ui/components/pending_status'; import { useAppDispatch, useAppSelector } from 'soapbox/hooks'; import { makeGetStatus } from 'soapbox/selectors'; +import ComposeForm from '../compose/components/compose-form'; import ThreadStatus from '../status/components/thread-status'; import type { VirtuosoHandle } from 'react-virtuoso'; @@ -55,13 +56,13 @@ const getDescendantsIds = createSelector([ type RouteParams = { statusId: string }; -interface IThread { +interface IEventDiscussion { params: RouteParams, onOpenMedia: (media: ImmutableList, index: number) => void, onOpenVideo: (video: AttachmentEntity, time: number) => void, } -const Thread: React.FC = (props) => { +const EventDiscussion: React.FC = (props) => { const dispatch = useAppDispatch(); const status = useAppSelector(state => getStatus(state, { id: props.params.statusId })); @@ -101,6 +102,10 @@ const Thread: React.FC = (props) => { }); }, [props.params.statusId]); + useEffect(() => { + dispatch(eventDiscussionCompose(`reply:${props.params.statusId}`, status!)); + }, [isLoaded]); + const handleMoveUp = (id: string) => { const index = ImmutableList(descendantsIds).indexOf(id); _selectChild(index - 1); @@ -174,10 +179,6 @@ const Thread: React.FC = (props) => { }); }; - const handleRefresh = () => { - return fetchData(); - }; - const handleLoadMore = useCallback(debounce(() => { if (next && status) { dispatch(fetchNext(status.id, next)).then(({ next }) => { @@ -205,23 +206,22 @@ const Thread: React.FC = (props) => { } return ( - - -
- } - initialTopMostItemIndex={0} - > - {children} - -
-
-
+ + +
+ } + initialTopMostItemIndex={0} + > + {children} + +
+
); }; -export default Thread; +export default EventDiscussion; diff --git a/app/soapbox/features/follow_requests/components/account_authorize.tsx b/app/soapbox/features/follow_requests/components/account_authorize.tsx index b820938d6..0d0428d44 100644 --- a/app/soapbox/features/follow_requests/components/account_authorize.tsx +++ b/app/soapbox/features/follow_requests/components/account_authorize.tsx @@ -23,7 +23,7 @@ interface IAccountAuthorize { const AccountAuthorize: React.FC = ({ id }) => { const intl = useIntl(); const dispatch = useDispatch(); - + const getAccount = useCallback(makeGetAccount(), []); const account = useAppSelector((state) => getAccount(state, id)); diff --git a/app/soapbox/reducers/__tests__/compose.test.ts b/app/soapbox/reducers/__tests__/compose.test.ts index c8da1c744..ea79b40ad 100644 --- a/app/soapbox/reducers/__tests__/compose.test.ts +++ b/app/soapbox/reducers/__tests__/compose.test.ts @@ -91,6 +91,7 @@ describe('compose reducer', () => { it('uses \'public\' scope as default', () => { const action = { type: actions.COMPOSE_REPLY, + id: 'compose-modal', status: ImmutableRecord({})(), account: ImmutableRecord({})(), }; @@ -101,6 +102,7 @@ describe('compose reducer', () => { const state = initialState.set('default', ReducerCompose({ privacy: 'public' })); const action = { type: actions.COMPOSE_REPLY, + id: 'compose-modal', status: ImmutableRecord({ visibility: 'direct' })(), account: ImmutableRecord({})(), }; @@ -111,6 +113,7 @@ describe('compose reducer', () => { const state = initialState.set('default', ReducerCompose({ privacy: 'public' })); const action = { type: actions.COMPOSE_REPLY, + id: 'compose-modal', status: ImmutableRecord({ visibility: 'private' })(), account: ImmutableRecord({})(), }; @@ -121,6 +124,7 @@ describe('compose reducer', () => { const state = initialState.set('default', ReducerCompose({ privacy: 'public' })); const action = { type: actions.COMPOSE_REPLY, + id: 'compose-modal', status: ImmutableRecord({ visibility: 'unlisted' })(), account: ImmutableRecord({})(), }; @@ -131,6 +135,7 @@ describe('compose reducer', () => { const state = initialState.set('default', ReducerCompose({ privacy: 'private' })); const action = { type: actions.COMPOSE_REPLY, + id: 'compose-modal', status: ImmutableRecord({ visibility: 'public' })(), account: ImmutableRecord({})(), }; @@ -141,6 +146,7 @@ describe('compose reducer', () => { const state = initialState.set('default', ReducerCompose({ privacy: 'unlisted' })); const action = { type: actions.COMPOSE_REPLY, + id: 'compose-modal', status: ImmutableRecord({ visibility: 'public' })(), account: ImmutableRecord({})(), }; diff --git a/app/soapbox/reducers/compose.ts b/app/soapbox/reducers/compose.ts index 4523edab9..9d4f84556 100644 --- a/app/soapbox/reducers/compose.ts +++ b/app/soapbox/reducers/compose.ts @@ -317,7 +317,7 @@ export default function compose(state = initialState, action: AnyAction) { case COMPOSE_COMPOSING_CHANGE: return updateCompose(state, action.id, compose => compose.set('is_composing', action.value)); case COMPOSE_REPLY: - return updateCompose(state, 'compose-modal', compose => compose.withMutations(map => { + return updateCompose(state, action.id, compose => compose.withMutations(map => { const defaultCompose = state.get('default')!; map.set('in_reply_to', action.status.get('id'));