Limit number of photos to paste in web composer
This commit is contained in:
@@ -35,6 +35,7 @@ import QuoteEmbed from '../util/post-embeds/QuoteEmbed'
|
||||
import {useExternalLinkFetch} from './useExternalLinkFetch'
|
||||
import {isDesktopWeb} from 'platform/detection'
|
||||
|
||||
const MAX_IMAGES = 4
|
||||
const MAX_GRAPHEME_LENGTH = 300
|
||||
|
||||
export const ComposePost = observer(function ComposePost({
|
||||
@@ -127,12 +128,12 @@ export const ComposePost = observer(function ComposePost({
|
||||
|
||||
const onPhotoPasted = React.useCallback(
|
||||
async (uri: string) => {
|
||||
if (selectedPhotos.length >= 4) {
|
||||
if (selectedPhotos.length >= MAX_IMAGES) {
|
||||
return
|
||||
}
|
||||
|
||||
setSelectedPhotos(sp => {
|
||||
if (sp.length >= 4) {
|
||||
if (sp.length >= MAX_IMAGES) {
|
||||
return sp
|
||||
}
|
||||
|
||||
@@ -290,6 +291,7 @@ export const ComposePost = observer(function ComposePost({
|
||||
placeholder={selectTextInputPlaceholder}
|
||||
suggestedLinks={suggestedLinks}
|
||||
autocompleteView={autocompleteView}
|
||||
numPasteableImages={MAX_IMAGES - selectedPhotos.length}
|
||||
setRichText={setRichText}
|
||||
onPhotoPasted={onPhotoPasted}
|
||||
onSuggestedLinksChanged={setSuggestedLinks}
|
||||
@@ -332,12 +334,12 @@ export const ComposePost = observer(function ComposePost({
|
||||
) : null}
|
||||
<View style={[pal.border, styles.bottomBar]}>
|
||||
<SelectPhotoBtn
|
||||
enabled={selectedPhotos.length < 4}
|
||||
enabled={selectedPhotos.length < MAX_IMAGES}
|
||||
selectedPhotos={selectedPhotos}
|
||||
onSelectPhotos={setSelectedPhotos}
|
||||
/>
|
||||
<OpenCameraBtn
|
||||
enabled={selectedPhotos.length < 4}
|
||||
enabled={selectedPhotos.length < MAX_IMAGES}
|
||||
selectedPhotos={selectedPhotos}
|
||||
onSelectPhotos={setSelectedPhotos}
|
||||
/>
|
||||
|
||||
@@ -37,6 +37,7 @@ interface TextInputProps {
|
||||
placeholder: string
|
||||
suggestedLinks: Set<string>
|
||||
autocompleteView: UserAutocompleteViewModel
|
||||
numPasteableImages: number
|
||||
setRichText: (v: RichText) => void
|
||||
onPhotoPasted: (uri: string) => void
|
||||
onSuggestedLinksChanged: (uris: Set<string>) => void
|
||||
@@ -55,6 +56,7 @@ export const TextInput = React.forwardRef(
|
||||
placeholder,
|
||||
suggestedLinks,
|
||||
autocompleteView,
|
||||
numPasteableImages,
|
||||
setRichText,
|
||||
onPhotoPasted,
|
||||
onSuggestedLinksChanged,
|
||||
@@ -129,6 +131,9 @@ export const TextInput = React.forwardRef(
|
||||
if (err) {
|
||||
return onError(cleanError(err))
|
||||
}
|
||||
if (numPasteableImages <= 0) {
|
||||
return
|
||||
}
|
||||
const uris = files.map(f => f.uri)
|
||||
const imgUri = uris.find(uri => /\.(jpe?g|png)$/.test(uri))
|
||||
if (imgUri) {
|
||||
@@ -148,7 +153,7 @@ export const TextInput = React.forwardRef(
|
||||
onPhotoPasted(finalImgPath)
|
||||
}
|
||||
},
|
||||
[store, onError, onPhotoPasted],
|
||||
[store, onError, onPhotoPasted, numPasteableImages],
|
||||
)
|
||||
|
||||
const onSelectionChange = React.useCallback(
|
||||
|
||||
@@ -11,7 +11,6 @@ import {Text} from '@tiptap/extension-text'
|
||||
import isEqual from 'lodash.isequal'
|
||||
import {UserAutocompleteViewModel} from 'state/models/user-autocomplete-view'
|
||||
import {createSuggestion} from './web/Autocomplete'
|
||||
import {Transaction} from '@tiptap/pm/state'
|
||||
import {cropAndCompressFlow} from 'lib/media/picker'
|
||||
import {useStores} from 'state/index'
|
||||
import {
|
||||
@@ -31,6 +30,7 @@ interface TextInputProps {
|
||||
placeholder: string
|
||||
suggestedLinks: Set<string>
|
||||
autocompleteView: UserAutocompleteViewModel
|
||||
numPasteableImages: number
|
||||
setRichText: (v: RichText) => void
|
||||
onPhotoPasted: (uri: string) => void
|
||||
onSuggestedLinksChanged: (uris: Set<string>) => void
|
||||
@@ -44,6 +44,7 @@ export const TextInput = React.forwardRef(
|
||||
placeholder,
|
||||
suggestedLinks,
|
||||
autocompleteView,
|
||||
numPasteableImages,
|
||||
setRichText,
|
||||
onPhotoPasted,
|
||||
onSuggestedLinksChanged,
|
||||
@@ -52,8 +53,13 @@ export const TextInput = React.forwardRef(
|
||||
ref,
|
||||
) => {
|
||||
const store = useStores()
|
||||
const processClipboardItemAsPhoto = async (item: DataTransferItem) => {
|
||||
const editorContent = React.useRef({}) // track the editor content in a ref to avoid triggering renders
|
||||
const processClipboardItemAsPhoto = React.useCallback(
|
||||
async (item: DataTransferItem) => {
|
||||
const file = item.getAsFile()
|
||||
if (numPasteableImages <= 0) {
|
||||
return
|
||||
}
|
||||
|
||||
if (file && file.type && file.type.startsWith('image/')) {
|
||||
const {uri, width, height} = await getImageInfoFromFile(file)
|
||||
@@ -66,8 +72,11 @@ export const TextInput = React.forwardRef(
|
||||
)
|
||||
onPhotoPasted(croppedUri)
|
||||
}
|
||||
}
|
||||
const editor = useEditor({
|
||||
},
|
||||
[store, onPhotoPasted, numPasteableImages],
|
||||
)
|
||||
const editor = useEditor(
|
||||
{
|
||||
extensions: [
|
||||
Document,
|
||||
Link.configure({
|
||||
@@ -86,7 +95,8 @@ export const TextInput = React.forwardRef(
|
||||
}),
|
||||
Text,
|
||||
],
|
||||
content: richtext.text.toString(),
|
||||
// use editorContent when possible to preserve state across re-renders (see useEditor deps below)
|
||||
content: editorContent.current || richtext.text.toString(),
|
||||
autofocus: true,
|
||||
editable: true,
|
||||
injectCSS: true,
|
||||
@@ -105,7 +115,7 @@ export const TextInput = React.forwardRef(
|
||||
}
|
||||
|
||||
// For any pasted images, bring them through the crop and compress flow
|
||||
for (const item of Array.from(items)) {
|
||||
for (const item of Array.from(items).slice(0, numPasteableImages)) {
|
||||
processClipboardItemAsPhoto(item)
|
||||
}
|
||||
|
||||
@@ -115,6 +125,7 @@ export const TextInput = React.forwardRef(
|
||||
},
|
||||
onUpdate({editor: editorProp}) {
|
||||
const json = editorProp.getJSON()
|
||||
editorContent.current = json
|
||||
|
||||
const newRt = new RichText({text: editorJsonToText(json).trim()})
|
||||
setRichText(newRt)
|
||||
@@ -124,7 +135,9 @@ export const TextInput = React.forwardRef(
|
||||
onSuggestedLinksChanged(newSuggestedLinks)
|
||||
}
|
||||
},
|
||||
})
|
||||
},
|
||||
[numPasteableImages],
|
||||
)
|
||||
|
||||
React.useImperativeHandle(ref, () => ({
|
||||
focus: () => {}, // TODO
|
||||
|
||||
Reference in New Issue
Block a user