Show compose form on event discussion page

Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
environments/review-events-5jp5it/deployments/1372
marcin mikołajczak 2 years ago
parent 640000c18e
commit 706e303547

@ -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 { export {
COMPOSE_CHANGE, COMPOSE_CHANGE,
COMPOSE_SUBMIT_REQUEST, COMPOSE_SUBMIT_REQUEST,
@ -812,4 +827,5 @@ export {
openComposeWithText, openComposeWithText,
addToMentions, addToMentions,
removeFromMentions, removeFromMentions,
eventDiscussionCompose,
}; };

@ -61,9 +61,10 @@ interface IComposeForm {
shouldCondense?: boolean, shouldCondense?: boolean,
autoFocus?: boolean, autoFocus?: boolean,
clickableAreaRef?: React.RefObject<HTMLDivElement>, clickableAreaRef?: React.RefObject<HTMLDivElement>,
eventDiscussion?: boolean
} }
const ComposeForm: React.FC<IComposeForm> = ({ id, shouldCondense, autoFocus, clickableAreaRef }) => { const ComposeForm: React.FC<IComposeForm> = ({ id, shouldCondense, autoFocus, clickableAreaRef, eventDiscussion }) => {
const history = useHistory(); const history = useHistory();
const intl = useIntl(); const intl = useIntl();
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
@ -264,7 +265,7 @@ const ComposeForm: React.FC<IComposeForm> = ({ id, shouldCondense, autoFocus, cl
return ( return (
<Stack className='w-full' space={1} ref={formRef} onClick={handleClick}> <Stack className='w-full' space={1} ref={formRef} onClick={handleClick}>
{scheduledStatusCount > 0 && ( {scheduledStatusCount > 0 && !eventDiscussion && (
<Warning <Warning
message={( message={(
<FormattedMessage <FormattedMessage
@ -285,9 +286,9 @@ const ComposeForm: React.FC<IComposeForm> = ({ id, shouldCondense, autoFocus, cl
<WarningContainer composeId={id} /> <WarningContainer composeId={id} />
{!shouldCondense && <ReplyIndicatorContainer composeId={id} />} {!shouldCondense && !eventDiscussion && <ReplyIndicatorContainer composeId={id} />}
{!shouldCondense && <ReplyMentions composeId={id} />} {!shouldCondense && !eventDiscussion && <ReplyMentions composeId={id} />}
<div <div
className={classNames({ className={classNames({

@ -3,9 +3,9 @@ import debounce from 'lodash/debounce';
import React, { useCallback, useEffect, useRef, useState } from 'react'; import React, { useCallback, useEffect, useRef, useState } from 'react';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import { eventDiscussionCompose } from 'soapbox/actions/compose';
import { fetchStatusWithContext, fetchNext } from 'soapbox/actions/statuses'; import { fetchStatusWithContext, fetchNext } from 'soapbox/actions/statuses';
import MissingIndicator from 'soapbox/components/missing_indicator'; import MissingIndicator from 'soapbox/components/missing_indicator';
import PullToRefresh from 'soapbox/components/pull-to-refresh';
import ScrollableList from 'soapbox/components/scrollable_list'; import ScrollableList from 'soapbox/components/scrollable_list';
import Tombstone from 'soapbox/components/tombstone'; import Tombstone from 'soapbox/components/tombstone';
import { Stack } from 'soapbox/components/ui'; 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 { useAppDispatch, useAppSelector } from 'soapbox/hooks';
import { makeGetStatus } from 'soapbox/selectors'; import { makeGetStatus } from 'soapbox/selectors';
import ComposeForm from '../compose/components/compose-form';
import ThreadStatus from '../status/components/thread-status'; import ThreadStatus from '../status/components/thread-status';
import type { VirtuosoHandle } from 'react-virtuoso'; import type { VirtuosoHandle } from 'react-virtuoso';
@ -55,13 +56,13 @@ const getDescendantsIds = createSelector([
type RouteParams = { statusId: string }; type RouteParams = { statusId: string };
interface IThread { interface IEventDiscussion {
params: RouteParams, params: RouteParams,
onOpenMedia: (media: ImmutableList<AttachmentEntity>, index: number) => void, onOpenMedia: (media: ImmutableList<AttachmentEntity>, index: number) => void,
onOpenVideo: (video: AttachmentEntity, time: number) => void, onOpenVideo: (video: AttachmentEntity, time: number) => void,
} }
const Thread: React.FC<IThread> = (props) => { const EventDiscussion: React.FC<IEventDiscussion> = (props) => {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const status = useAppSelector(state => getStatus(state, { id: props.params.statusId })); const status = useAppSelector(state => getStatus(state, { id: props.params.statusId }));
@ -101,6 +102,10 @@ const Thread: React.FC<IThread> = (props) => {
}); });
}, [props.params.statusId]); }, [props.params.statusId]);
useEffect(() => {
dispatch(eventDiscussionCompose(`reply:${props.params.statusId}`, status!));
}, [isLoaded]);
const handleMoveUp = (id: string) => { const handleMoveUp = (id: string) => {
const index = ImmutableList(descendantsIds).indexOf(id); const index = ImmutableList(descendantsIds).indexOf(id);
_selectChild(index - 1); _selectChild(index - 1);
@ -174,10 +179,6 @@ const Thread: React.FC<IThread> = (props) => {
}); });
}; };
const handleRefresh = () => {
return fetchData();
};
const handleLoadMore = useCallback(debounce(() => { const handleLoadMore = useCallback(debounce(() => {
if (next && status) { if (next && status) {
dispatch(fetchNext(status.id, next)).then(({ next }) => { dispatch(fetchNext(status.id, next)).then(({ next }) => {
@ -205,8 +206,8 @@ const Thread: React.FC<IThread> = (props) => {
} }
return ( return (
<PullToRefresh onRefresh={handleRefresh}>
<Stack space={2}> <Stack space={2}>
<ComposeForm id={`reply:${status.id}`} autoFocus={false} eventDiscussion />
<div ref={node} className='thread p-0 sm:p-2 shadow-none'> <div ref={node} className='thread p-0 sm:p-2 shadow-none'>
<ScrollableList <ScrollableList
id='thread' id='thread'
@ -220,8 +221,7 @@ const Thread: React.FC<IThread> = (props) => {
</ScrollableList> </ScrollableList>
</div> </div>
</Stack> </Stack>
</PullToRefresh>
); );
}; };
export default Thread; export default EventDiscussion;

@ -91,6 +91,7 @@ describe('compose reducer', () => {
it('uses \'public\' scope as default', () => { it('uses \'public\' scope as default', () => {
const action = { const action = {
type: actions.COMPOSE_REPLY, type: actions.COMPOSE_REPLY,
id: 'compose-modal',
status: ImmutableRecord({})(), status: ImmutableRecord({})(),
account: ImmutableRecord({})(), account: ImmutableRecord({})(),
}; };
@ -101,6 +102,7 @@ describe('compose reducer', () => {
const state = initialState.set('default', ReducerCompose({ privacy: 'public' })); const state = initialState.set('default', ReducerCompose({ privacy: 'public' }));
const action = { const action = {
type: actions.COMPOSE_REPLY, type: actions.COMPOSE_REPLY,
id: 'compose-modal',
status: ImmutableRecord({ visibility: 'direct' })(), status: ImmutableRecord({ visibility: 'direct' })(),
account: ImmutableRecord({})(), account: ImmutableRecord({})(),
}; };
@ -111,6 +113,7 @@ describe('compose reducer', () => {
const state = initialState.set('default', ReducerCompose({ privacy: 'public' })); const state = initialState.set('default', ReducerCompose({ privacy: 'public' }));
const action = { const action = {
type: actions.COMPOSE_REPLY, type: actions.COMPOSE_REPLY,
id: 'compose-modal',
status: ImmutableRecord({ visibility: 'private' })(), status: ImmutableRecord({ visibility: 'private' })(),
account: ImmutableRecord({})(), account: ImmutableRecord({})(),
}; };
@ -121,6 +124,7 @@ describe('compose reducer', () => {
const state = initialState.set('default', ReducerCompose({ privacy: 'public' })); const state = initialState.set('default', ReducerCompose({ privacy: 'public' }));
const action = { const action = {
type: actions.COMPOSE_REPLY, type: actions.COMPOSE_REPLY,
id: 'compose-modal',
status: ImmutableRecord({ visibility: 'unlisted' })(), status: ImmutableRecord({ visibility: 'unlisted' })(),
account: ImmutableRecord({})(), account: ImmutableRecord({})(),
}; };
@ -131,6 +135,7 @@ describe('compose reducer', () => {
const state = initialState.set('default', ReducerCompose({ privacy: 'private' })); const state = initialState.set('default', ReducerCompose({ privacy: 'private' }));
const action = { const action = {
type: actions.COMPOSE_REPLY, type: actions.COMPOSE_REPLY,
id: 'compose-modal',
status: ImmutableRecord({ visibility: 'public' })(), status: ImmutableRecord({ visibility: 'public' })(),
account: ImmutableRecord({})(), account: ImmutableRecord({})(),
}; };
@ -141,6 +146,7 @@ describe('compose reducer', () => {
const state = initialState.set('default', ReducerCompose({ privacy: 'unlisted' })); const state = initialState.set('default', ReducerCompose({ privacy: 'unlisted' }));
const action = { const action = {
type: actions.COMPOSE_REPLY, type: actions.COMPOSE_REPLY,
id: 'compose-modal',
status: ImmutableRecord({ visibility: 'public' })(), status: ImmutableRecord({ visibility: 'public' })(),
account: ImmutableRecord({})(), account: ImmutableRecord({})(),
}; };

@ -317,7 +317,7 @@ export default function compose(state = initialState, action: AnyAction) {
case COMPOSE_COMPOSING_CHANGE: case COMPOSE_COMPOSING_CHANGE:
return updateCompose(state, action.id, compose => compose.set('is_composing', action.value)); return updateCompose(state, action.id, compose => compose.set('is_composing', action.value));
case COMPOSE_REPLY: 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')!; const defaultCompose = state.get('default')!;
map.set('in_reply_to', action.status.get('id')); map.set('in_reply_to', action.status.get('id'));

Loading…
Cancel
Save