Improve compose page styles, propagate compose toast to other tabs

Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
marcin mikołajczak 2023-07-26 00:53:22 +02:00
parent b820781eff
commit 4c9201e8b4
6 changed files with 35 additions and 20 deletions

View file

@ -274,15 +274,18 @@ const directComposeById = (accountId: string) =>
dispatch(openModal('COMPOSE'));
};
const handleComposeSubmit = (dispatch: AppDispatch, getState: () => RootState, composeId: string, data: APIEntity, status: string, edit?: boolean) => {
const handleComposeSubmit = (dispatch: AppDispatch, getState: () => RootState, composeId: string, data: APIEntity, status: string, edit?: boolean, propagate?: boolean) => {
if (!dispatch || !getState) return;
dispatch(insertIntoTagHistory(composeId, data.tags || [], status));
dispatch(submitComposeSuccess(composeId, { ...data }));
toast.success(edit ? messages.editSuccess : messages.success, {
const toastMessage = edit ? messages.editSuccess : messages.success;
const toastOpts = {
actionLabel: messages.view,
actionLink: `/@${data.account.acct}/posts/${data.id}`,
});
};
if (propagate) toast.propagate('success', toastMessage, toastOpts);
else toast.success(toastMessage, toastOpts);
};
const needsDescriptions = (state: RootState, composeId: string) => {
@ -303,7 +306,7 @@ const validateSchedule = (state: RootState, composeId: string) => {
return schedule.getTime() > fiveMinutesFromNow.getTime();
};
const submitCompose = (composeId: string, routerHistory?: History, force = false, onSubmit?: () => void) =>
const submitCompose = (composeId: string, routerHistory?: History, force = false, onSubmit?: () => void, propagate?: boolean) =>
(dispatch: AppDispatch, getState: () => RootState) => {
if (!isLoggedIn(getState)) return;
const state = getState();
@ -368,7 +371,7 @@ const submitCompose = (composeId: string, routerHistory?: History, force = false
if (!statusId && data.visibility === 'direct' && getState().conversations.mounted <= 0 && routerHistory) {
routerHistory.push('/messages');
}
handleComposeSubmit(dispatch, getState, composeId, data, status, !!statusId);
handleComposeSubmit(dispatch, getState, composeId, data, status, !!statusId, propagate);
if (onSubmit) onSubmit();
}).catch(function(error) {
dispatch(submitComposeFail(composeId, error));

View file

@ -30,6 +30,7 @@ interface IAutosuggesteTextarea {
onFocus: () => void
onBlur?: () => void
condensed?: boolean
fullScreen?: boolean
children: React.ReactNode
}
@ -227,7 +228,7 @@ class AutosuggestTextarea extends ImmutablePureComponent<IAutosuggesteTextarea>
}
render() {
const { value, suggestions, disabled, placeholder, onKeyUp, autoFocus, children, condensed, id } = this.props;
const { value, suggestions, disabled, placeholder, onKeyUp, autoFocus, children, condensed, id, fullScreen } = this.props;
const { suggestionsHidden } = this.state;
const style = { direction: 'ltr', minRows: 10 };
@ -237,7 +238,7 @@ class AutosuggestTextarea extends ImmutablePureComponent<IAutosuggesteTextarea>
}
return [
<div key='textarea'>
<div key='textarea' className={clsx(fullScreen && 'grow')}>
<div className='relative'>
<label>
<span style={{ display: 'none' }}>{placeholder}</span>
@ -247,6 +248,7 @@ class AutosuggestTextarea extends ImmutablePureComponent<IAutosuggesteTextarea>
className={clsx('w-full resize-none border-0 px-0 text-gray-800 transition-[min-height] placeholder:text-gray-600 focus:border-0 focus:shadow-none focus:ring-0 motion-reduce:transition-none dark:bg-transparent dark:text-white dark:placeholder:text-gray-600', {
'min-h-[40px]': condensed,
'min-h-[100px]': !condensed,
'h-full': fullScreen,
})}
id={id}
disabled={disabled}

View file

@ -195,11 +195,7 @@ const SoapboxMount = () => {
<GdprBanner />
<div id='toaster'>
<Toaster
position='top-right'
containerClassName='top-10'
containerStyle={{ top: 75 }}
/>
<Toaster position='top-right' />
</div>
</Route>
</Switch>

View file

@ -66,9 +66,10 @@ interface IComposeForm<ID extends string> {
group?: string
extra?: React.ReactNode
onSubmit?: () => void
fullScreen?: boolean
}
const ComposeForm = <ID extends string>({ id, shouldCondense, autoFocus, clickableAreaRef, event, group, extra, onSubmit }: IComposeForm<ID>) => {
const ComposeForm = <ID extends string>({ id, shouldCondense, autoFocus, clickableAreaRef, event, group, extra, onSubmit, fullScreen }: IComposeForm<ID>) => {
const history = useHistory();
const intl = useIntl();
const dispatch = useAppDispatch();
@ -158,7 +159,7 @@ const ComposeForm = <ID extends string>({ id, shouldCondense, autoFocus, clickab
return;
}
dispatch(submitCompose(id, history, false, onSubmit));
dispatch(submitCompose(id, history, false, onSubmit, fullScreen));
};
const onSuggestionsClearRequested = () => {
@ -275,7 +276,7 @@ const ComposeForm = <ID extends string>({ id, shouldCondense, autoFocus, clickab
}
return (
<Stack className='w-full' space={4} ref={formRef} onClick={handleClick} element='form' onSubmit={handleSubmit}>
<Stack className='w-full' grow={fullScreen} space={4} ref={formRef} onClick={handleClick} element='form' onSubmit={handleSubmit}>
{scheduledStatusCount > 0 && !event && !group && (
<Warning
message={(
@ -319,6 +320,7 @@ const ComposeForm = <ID extends string>({ id, shouldCondense, autoFocus, clickab
autoFocus={shouldAutoFocus}
condensed={condensed}
id='compose-textarea'
fullScreen
>
{
!condensed &&

View file

@ -8,7 +8,7 @@ import { fetchStatus } from 'soapbox/actions/statuses';
import { Stack } from 'soapbox/components/ui';
import ComposeForm from 'soapbox/features/compose/components/compose-form';
import { useAppDispatch, useCompose } from 'soapbox/hooks';
import { makeGetStatus } from 'soapbox/selectors';
import { makeGetStatus, selectOwnAccount } from 'soapbox/selectors';
import { getFeatures } from 'soapbox/utils/features';
const getStatus = makeGetStatus();
@ -56,7 +56,7 @@ const ComposePage = () => {
type: COMPOSE_REPLY,
id: 'compose-modal',
status: status,
account: state.accounts.get(state.me)!,
account: selectOwnAccount(state),
explicitAddressing,
});
}));
@ -72,7 +72,7 @@ const ComposePage = () => {
type: COMPOSE_QUOTE,
id: 'compose-modal',
status: status,
account: state.accounts.get(state.me)!,
account: selectOwnAccount(state),
explicitAddressing,
});
}));
@ -83,7 +83,7 @@ const ComposePage = () => {
<h3 className='grow-0 truncate text-lg font-bold leading-6 text-gray-900 dark:text-white'>
{heading}
</h3>
<ComposeForm id='compose-modal' onSubmit={() => window.close()} />
<ComposeForm id='compose-modal' onSubmit={() => window.close()} fullScreen />
</Stack>
);
};

View file

@ -17,6 +17,13 @@ interface IToastOptions {
summary?: string
}
let bc: BroadcastChannel;
if (BroadcastChannel) {
bc = new BroadcastChannel('toast');
bc.onmessage = ({ data }) => createToast(data.type, data.message, data.opts);
(window as any).bc = bc;
}
const DEFAULT_DURATION = 4000;
const createToast = (type: ToastType, message: ToastText, opts?: IToastOptions) => {
@ -39,6 +46,10 @@ function error(message: ToastText, opts?: IToastOptions) {
createToast('error', message, opts);
}
const propagate = (type: ToastType, message: ToastText, opts?: IToastOptions) => {
bc?.postMessage({ type, message, opts });
};
const messages = defineMessages({
unexpectedMessage: { id: 'alert.unexpected.message', defaultMessage: 'An unexpected error occurred.' },
});
@ -79,5 +90,6 @@ export default {
info,
success,
error,
propagate,
showAlertForError,
};
};