Merge branch 'compose-form-suspense' into 'main'

ComposeForm: wrap ComposeEditor with Suspense

See merge request soapbox-pub/soapbox!2785
This commit is contained in:
Alex Gleason 2023-10-10 03:34:53 +00:00
commit 3f21fe5e57
3 changed files with 36 additions and 32 deletions

View File

@ -1,6 +1,6 @@
import clsx from 'clsx'; import clsx from 'clsx';
import { CLEAR_EDITOR_COMMAND, TextNode, type LexicalEditor } from 'lexical'; import { CLEAR_EDITOR_COMMAND, TextNode, type LexicalEditor } from 'lexical';
import React, { useCallback, useEffect, useRef, useState } from 'react'; import React, { Suspense, useCallback, useEffect, useRef, useState } from 'react';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import { Link, useHistory } from 'react-router-dom'; import { Link, useHistory } from 'react-router-dom';
import { length } from 'stringz'; import { length } from 'stringz';
@ -17,7 +17,7 @@ import AutosuggestInput, { AutoSuggestion } from 'soapbox/components/autosuggest
import AutosuggestTextarea from 'soapbox/components/autosuggest-textarea'; import AutosuggestTextarea from 'soapbox/components/autosuggest-textarea';
import { Button, HStack, Stack } from 'soapbox/components/ui'; import { Button, HStack, Stack } from 'soapbox/components/ui';
import EmojiPickerDropdown from 'soapbox/features/emoji/containers/emoji-picker-dropdown-container'; import EmojiPickerDropdown from 'soapbox/features/emoji/containers/emoji-picker-dropdown-container';
import { ComposeEditor, ScheduleForm } from 'soapbox/features/ui/util/async-components'; import { ComposeEditor } from 'soapbox/features/ui/util/async-components';
import { useAppDispatch, useAppSelector, useCompose, useDraggedFiles, useFeatures, useInstance, usePrevious } from 'soapbox/hooks'; import { useAppDispatch, useAppSelector, useCompose, useDraggedFiles, useFeatures, useInstance, usePrevious } from 'soapbox/hooks';
import { isMobile } from 'soapbox/is-mobile'; import { isMobile } from 'soapbox/is-mobile';
@ -35,6 +35,7 @@ import PrivacyDropdown from './privacy-dropdown';
import ReplyGroupIndicator from './reply-group-indicator'; import ReplyGroupIndicator from './reply-group-indicator';
import ReplyMentions from './reply-mentions'; import ReplyMentions from './reply-mentions';
import ScheduleButton from './schedule-button'; import ScheduleButton from './schedule-button';
import ScheduleForm from './schedule-form';
import SpoilerButton from './spoiler-button'; import SpoilerButton from './spoiler-button';
import SpoilerInput from './spoiler-input'; import SpoilerInput from './spoiler-input';
import TextCharacterCounter from './text-character-counter'; import TextCharacterCounter from './text-character-counter';
@ -311,19 +312,21 @@ const ComposeForm = <ID extends string>({ id, shouldCondense, autoFocus, clickab
{!shouldCondense && !event && !group && <ReplyMentions composeId={id} />} {!shouldCondense && !event && !group && <ReplyMentions composeId={id} />}
<div> <div>
<ComposeEditor <Suspense>
ref={editorRef} <ComposeEditor
className='mt-2' ref={editorRef}
composeId={id} className='mt-2'
condensed={condensed} composeId={id}
eventDiscussion={!!event} condensed={condensed}
autoFocus={shouldAutoFocus} eventDiscussion={!!event}
hasPoll={hasPoll} autoFocus={shouldAutoFocus}
handleSubmit={handleSubmit} hasPoll={hasPoll}
onChange={setText} handleSubmit={handleSubmit}
onFocus={handleComposeFocus} onChange={setText}
onPaste={onPaste} onFocus={handleComposeFocus}
/> onPaste={onPaste}
/>
</Suspense>
{composeModifiers} {composeModifiers}
</div> </div>

View File

@ -1,10 +1,10 @@
import clsx from 'clsx'; import clsx from 'clsx';
import React from 'react'; import React, { Suspense } from 'react';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import { setSchedule, removeSchedule } from 'soapbox/actions/compose'; import { setSchedule, removeSchedule } from 'soapbox/actions/compose';
import IconButton from 'soapbox/components/icon-button'; import IconButton from 'soapbox/components/icon-button';
import { HStack, Stack, Text } from 'soapbox/components/ui'; import { HStack, Input, Stack, Text } from 'soapbox/components/ui';
import { DatePicker } from 'soapbox/features/ui/util/async-components'; import { DatePicker } from 'soapbox/features/ui/util/async-components';
import { useAppDispatch, useCompose } from 'soapbox/hooks'; import { useAppDispatch, useCompose } from 'soapbox/hooks';
@ -54,20 +54,22 @@ const ScheduleForm: React.FC<IScheduleForm> = ({ composeId }) => {
<FormattedMessage id='datepicker.hint' defaultMessage='Scheduled to post at…' /> <FormattedMessage id='datepicker.hint' defaultMessage='Scheduled to post at…' />
</Text> </Text>
<HStack space={2} alignItems='center'> <HStack space={2} alignItems='center'>
<DatePicker <Suspense fallback={<Input type='text' disabled />}>
selected={scheduledAt} <DatePicker
showTimeSelect selected={scheduledAt}
dateFormat='MMMM d, yyyy h:mm aa' showTimeSelect
timeIntervals={15} dateFormat='MMMM d, yyyy h:mm aa'
wrapperClassName='react-datepicker-wrapper' timeIntervals={15}
onChange={onSchedule} wrapperClassName='react-datepicker-wrapper'
placeholderText={intl.formatMessage(messages.schedule)} onChange={onSchedule}
filterDate={isCurrentOrFutureDate} placeholderText={intl.formatMessage(messages.schedule)}
filterTime={isFiveMinutesFromNow} filterDate={isCurrentOrFutureDate}
className={clsx({ filterTime={isFiveMinutesFromNow}
'has-error': !isFiveMinutesFromNow(scheduledAt), className={clsx({
})} 'has-error': !isFiveMinutesFromNow(scheduledAt),
/> })}
/>
</Suspense>
<IconButton <IconButton
iconClassName='h-4 w-4' iconClassName='h-4 w-4'
className='bg-transparent text-gray-400 hover:text-gray-600' className='bg-transparent text-gray-400 hover:text-gray-600'

View File

@ -107,7 +107,6 @@ export const UserIndex = lazy(() => import('soapbox/features/admin/user-index'))
export const FederationRestrictions = lazy(() => import('soapbox/features/federation-restrictions')); export const FederationRestrictions = lazy(() => import('soapbox/features/federation-restrictions'));
export const Aliases = lazy(() => import('soapbox/features/aliases')); export const Aliases = lazy(() => import('soapbox/features/aliases'));
export const Migration = lazy(() => import('soapbox/features/migration')); export const Migration = lazy(() => import('soapbox/features/migration'));
export const ScheduleForm = lazy(() => import('soapbox/features/compose/components/schedule-form'));
export const WhoToFollowPanel = lazy(() => import('soapbox/features/ui/components/who-to-follow-panel')); export const WhoToFollowPanel = lazy(() => import('soapbox/features/ui/components/who-to-follow-panel'));
export const FollowRecommendations = lazy(() => import('soapbox/features/follow-recommendations')); export const FollowRecommendations = lazy(() => import('soapbox/features/follow-recommendations'));
export const Directory = lazy(() => import('soapbox/features/directory')); export const Directory = lazy(() => import('soapbox/features/directory'));