Merge branch 'upload-ctrl-enter' into 'main'
Composer: fix Ctrl+Enter deleting text when the cursor is inside an upload input Closes #1554 See merge request soapbox-pub/soapbox!2806
This commit is contained in:
commit
7863e6225e
4 changed files with 20 additions and 24 deletions
|
@ -1,3 +1,12 @@
|
||||||
|
import bookIcon from '@tabler/icons/book.svg';
|
||||||
|
import fileCodeIcon from '@tabler/icons/file-code.svg';
|
||||||
|
import fileSpreadsheetIcon from '@tabler/icons/file-spreadsheet.svg';
|
||||||
|
import fileTextIcon from '@tabler/icons/file-text.svg';
|
||||||
|
import fileZipIcon from '@tabler/icons/file-zip.svg';
|
||||||
|
import defaultIcon from '@tabler/icons/paperclip.svg';
|
||||||
|
import presentationIcon from '@tabler/icons/presentation.svg';
|
||||||
|
import xIcon from '@tabler/icons/x.svg';
|
||||||
|
import zoomInIcon from '@tabler/icons/zoom-in.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { List as ImmutableList } from 'immutable';
|
import { List as ImmutableList } from 'immutable';
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
@ -6,20 +15,11 @@ import { spring } from 'react-motion';
|
||||||
|
|
||||||
import { openModal } from 'soapbox/actions/modals';
|
import { openModal } from 'soapbox/actions/modals';
|
||||||
import Blurhash from 'soapbox/components/blurhash';
|
import Blurhash from 'soapbox/components/blurhash';
|
||||||
import Icon from 'soapbox/components/icon';
|
import { HStack, Icon, IconButton } from 'soapbox/components/ui';
|
||||||
import { HStack, IconButton } from 'soapbox/components/ui';
|
|
||||||
import Motion from 'soapbox/features/ui/util/optional-motion';
|
import Motion from 'soapbox/features/ui/util/optional-motion';
|
||||||
import { useAppDispatch } from 'soapbox/hooks';
|
import { useAppDispatch } from 'soapbox/hooks';
|
||||||
import { Attachment } from 'soapbox/types/entities';
|
import { Attachment } from 'soapbox/types/entities';
|
||||||
|
|
||||||
const bookIcon = require('@tabler/icons/book.svg');
|
|
||||||
const fileCodeIcon = require('@tabler/icons/file-code.svg');
|
|
||||||
const fileSpreadsheetIcon = require('@tabler/icons/file-spreadsheet.svg');
|
|
||||||
const fileTextIcon = require('@tabler/icons/file-text.svg');
|
|
||||||
const fileZipIcon = require('@tabler/icons/file-zip.svg');
|
|
||||||
const defaultIcon = require('@tabler/icons/paperclip.svg');
|
|
||||||
const presentationIcon = require('@tabler/icons/presentation.svg');
|
|
||||||
|
|
||||||
export const MIMETYPE_ICONS: Record<string, string> = {
|
export const MIMETYPE_ICONS: Record<string, string> = {
|
||||||
'application/x-freearc': fileZipIcon,
|
'application/x-freearc': fileZipIcon,
|
||||||
'application/x-bzip': fileZipIcon,
|
'application/x-bzip': fileZipIcon,
|
||||||
|
@ -163,7 +163,7 @@ const Upload: React.FC<IUpload> = ({
|
||||||
{(withPreview && mediaType !== 'unknown' && Boolean(media.url)) && (
|
{(withPreview && mediaType !== 'unknown' && Boolean(media.url)) && (
|
||||||
<IconButton
|
<IconButton
|
||||||
onClick={handleOpenModal}
|
onClick={handleOpenModal}
|
||||||
src={require('@tabler/icons/zoom-in.svg')}
|
src={zoomInIcon}
|
||||||
theme='dark'
|
theme='dark'
|
||||||
className='hover:scale-105 hover:bg-gray-900'
|
className='hover:scale-105 hover:bg-gray-900'
|
||||||
iconClassName='h-5 w-5'
|
iconClassName='h-5 w-5'
|
||||||
|
@ -173,7 +173,7 @@ const Upload: React.FC<IUpload> = ({
|
||||||
{onDelete && (
|
{onDelete && (
|
||||||
<IconButton
|
<IconButton
|
||||||
onClick={handleUndoClick}
|
onClick={handleUndoClick}
|
||||||
src={require('@tabler/icons/x.svg')}
|
src={xIcon}
|
||||||
theme='dark'
|
theme='dark'
|
||||||
className='hover:scale-105 hover:bg-gray-900'
|
className='hover:scale-105 hover:bg-gray-900'
|
||||||
iconClassName='h-5 w-5'
|
iconClassName='h-5 w-5'
|
||||||
|
|
|
@ -223,7 +223,7 @@ const ComposeForm = <ID extends string>({ id, shouldCondense, autoFocus, clickab
|
||||||
|
|
||||||
const composeModifiers = !condensed && (
|
const composeModifiers = !condensed && (
|
||||||
<Stack space={4} className='compose-form__modifiers'>
|
<Stack space={4} className='compose-form__modifiers'>
|
||||||
<UploadForm composeId={id} />
|
<UploadForm composeId={id} onSubmit={handleSubmit} />
|
||||||
<PollForm composeId={id} />
|
<PollForm composeId={id} />
|
||||||
|
|
||||||
<SpoilerInput
|
<SpoilerInput
|
||||||
|
|
|
@ -11,9 +11,10 @@ import type { Attachment as AttachmentEntity } from 'soapbox/types/entities';
|
||||||
|
|
||||||
interface IUploadForm {
|
interface IUploadForm {
|
||||||
composeId: string;
|
composeId: string;
|
||||||
|
onSubmit(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const UploadForm: React.FC<IUploadForm> = ({ composeId }) => {
|
const UploadForm: React.FC<IUploadForm> = ({ composeId, onSubmit }) => {
|
||||||
const mediaIds = useCompose(composeId).media_attachments.map((item: AttachmentEntity) => item.id);
|
const mediaIds = useCompose(composeId).media_attachments.map((item: AttachmentEntity) => item.id);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -22,7 +23,7 @@ const UploadForm: React.FC<IUploadForm> = ({ composeId }) => {
|
||||||
|
|
||||||
<HStack wrap className={clsx('overflow-hidden', mediaIds.size !== 0 && 'p-1')}>
|
<HStack wrap className={clsx('overflow-hidden', mediaIds.size !== 0 && 'p-1')}>
|
||||||
{mediaIds.map((id: string) => (
|
{mediaIds.map((id: string) => (
|
||||||
<Upload id={id} key={id} composeId={composeId} />
|
<Upload id={id} key={id} composeId={composeId} onSubmit={onSubmit} />
|
||||||
))}
|
))}
|
||||||
</HStack>
|
</HStack>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,26 +1,21 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useHistory } from 'react-router-dom';
|
|
||||||
|
|
||||||
import { undoUploadCompose, changeUploadCompose, submitCompose } from 'soapbox/actions/compose';
|
import { undoUploadCompose, changeUploadCompose } from 'soapbox/actions/compose';
|
||||||
import Upload from 'soapbox/components/upload';
|
import Upload from 'soapbox/components/upload';
|
||||||
import { useAppDispatch, useCompose, useInstance } from 'soapbox/hooks';
|
import { useAppDispatch, useCompose, useInstance } from 'soapbox/hooks';
|
||||||
|
|
||||||
interface IUploadCompose {
|
interface IUploadCompose {
|
||||||
id: string;
|
id: string;
|
||||||
composeId: string;
|
composeId: string;
|
||||||
|
onSubmit?(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const UploadCompose: React.FC<IUploadCompose> = ({ composeId, id }) => {
|
const UploadCompose: React.FC<IUploadCompose> = ({ composeId, id, onSubmit }) => {
|
||||||
const history = useHistory();
|
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { description_limit: descriptionLimit } = useInstance();
|
const { description_limit: descriptionLimit } = useInstance();
|
||||||
|
|
||||||
const media = useCompose(composeId).media_attachments.find(item => item.id === id)!;
|
const media = useCompose(composeId).media_attachments.find(item => item.id === id)!;
|
||||||
|
|
||||||
const handleSubmit = () => {
|
|
||||||
dispatch(submitCompose(composeId, history));
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleDescriptionChange = (description: string) => {
|
const handleDescriptionChange = (description: string) => {
|
||||||
dispatch(changeUploadCompose(composeId, media.id, { description }));
|
dispatch(changeUploadCompose(composeId, media.id, { description }));
|
||||||
};
|
};
|
||||||
|
@ -34,7 +29,7 @@ const UploadCompose: React.FC<IUploadCompose> = ({ composeId, id }) => {
|
||||||
media={media}
|
media={media}
|
||||||
onDelete={handleDelete}
|
onDelete={handleDelete}
|
||||||
onDescriptionChange={handleDescriptionChange}
|
onDescriptionChange={handleDescriptionChange}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={onSubmit}
|
||||||
descriptionLimit={descriptionLimit}
|
descriptionLimit={descriptionLimit}
|
||||||
withPreview
|
withPreview
|
||||||
/>
|
/>
|
||||||
|
|
Loading…
Reference in a new issue