[BUG] Saving/inserting images from custom ImageDialog
Closed this issue · 8 comments
If you want to ask for support or request features, sponsor the project and contact me over email.
- I have searched for similar issues in both open and closed tickets and cannot find a duplicate.
- I have read the documentation and cannot find an answer.
Describe the bug
I have implemented a custom ImageDialog
component that uses a Dropbox Chooser. The chooser returns some JSON with url, name, etc. When using saveImage$
, insertImage$
, etc nothing happens.
Reproduction
Unfortunately, I can't really make a reproducible example because of Dropbox keys, origins, etc. And I don't think that screenshots will be particularly useful. I can add a video and some code that outlines what is happening. Please see code snippet at bottom.
Video: https://www.loom.com/share/1a92dc6b547546668fa188c373459c28
Expected behavior
I expect the image to be loaded into the editor.
Desktop (please complete the following information):
- OS: Mac
- Browser Chrome
function ImageDialog() {
const saveImage = usePublisher(saveImage$);
const createImage = usePublisher($createImageNode);
const insertImage = usePublisher(insertImage$);
const closeImageDialog = usePublisher(closeImageDialog$);
const [imageDialogState] = useCellValues(imageDialogState$);
const handleDropboxSuccess = async (files) => {
const dropboxItem = files[0];
const file = await urlToObject(dropboxItem.link, dropboxItem.name);
const list = createFileList(file);
// const image = createImage({
// src: file.link,
// altText: file.name,
// title: file.name,
// files: list
// });
// saveImage({
// src: dropboxItem.link,
// altText: dropboxItem.name,
// title: dropboxItem.name,
// file: list
// });
insertImage({
src: dropboxItem.link,
altText: dropboxItem.name,
title: dropboxItem.name,
file: list
});
closeImageDialog();
};
return (
<Modal
isOpen={imageDialogState.type !== 'inactive'}
size="lg"
fullscreen="md"
centered={true}
scrollable={true}
fade={false}
contentClassName="h-100"
backdrop={false}
>
<ModalBody className="p-3">
<div className="mb-4">
<div className="mb-4">
Use Dropbox to securely link your files. Click the button below to
choose files from your Dropbox account.
</div>
<DropboxChooser
appKey={DROPBOX_KEY}
success={handleDropboxSuccess}
linkType="direct"
// cancel={}
// multiselect={true}
>
<Button>
<FaDropbox className="me-2" />
Choose From Dropbox
</Button>
</DropboxChooser>
</div>
{/* <div>
<div className="mb-4">
Use Google Drive to securely link your files. Click the button below
to choose files from your Drive account.
</div>
<Button onClick={openGooglePicker}>
<FaGoogle className="me-2" />
Choose From Google
</Button>
</div> */}
</ModalBody>
<ModalFooter className="p-3">
<Button
type="button"
color="secondary"
className="rounded-pill"
onClick={closeImageDialog}
>
Cancel
</Button>
</ModalFooter>
</Modal>
);
}
const urlToObject = async (url, name) => {
const response = await fetch(url);
const blob = await response.blob();
const file = new File([blob], name, { type: blob.type });
return file;
};
let getDataTransfer = () => new DataTransfer();
const { concat } = Array.prototype;
try {
getDataTransfer();
} catch {
getDataTransfer = () => new ClipboardEvent('').clipboardData;
}
function createFileList() {
// eslint-disable-next-line prefer-rest-params
const files = concat.apply([], arguments);
let index = 0;
const { length } = files;
const dataTransfer = getDataTransfer();
for (; index < length; index++) {
dataTransfer.items.add(files[index]);
}
return dataTransfer.files;
}
export default createFileList;
Confirming that this is actually a bug of insertImage$
. Your code seems correct as far as I can tell, will fix this.
It would also be helpful if the functions took a File
OR FileList
for the file
property. You cannot construct a file list like new FileList()
.
My code is using: https://www.npmjs.com/package/create-file-list
Thanks!
A new version should be built and published soon. Check the examples I did in the commit above.
There is still an error on this line:
editor/src/plugins/image/index.ts
Line 186 in 75a501f
I believe that should be updated to use
if 'file' in values
, similar to how insertImage
was updated.How can I reproduce the error?
Call saveImage({ src: '...' })
without a file
property.
Given that you're using a custom dialog component, you don't have to use the saveImage
signal. It's bound to the data shape of the default dialog form. Instead, use the insertImage
, it should work as expected.
OK. I was thinking saveImage
might "update" the current image data. How would I go about editing the image data? For example, my custom ImageDialog
now has inputs for file name and alt text. When I click the gear icon on an image, it opens the modal with the field values. How do I save those if the user edits them?