8

enter image description here

Drag and Drop images into chat! In any chat window, simply drag and drop an image to anywhere in the window to upload it. Bonus! - the image will not be automatically sent, allowing you to edit your message before sending!

Userscript download

  1. Download the file
  2. Drag and Drop onto your Extensions page in Chrome, or install with Greasemonkey in FF

2 Answers 2

3

Also support pasting an image from the clipboard.

Thank you for this, this is awesome. But if you also add the paste feature that imgur has (it also works on Stack Exchange posts, hit the "insert image" icon and Ctrl+V), I will worship you1.

1: For very specific definitions of "worship." Offer void on weekdays or days that start with "S." Terms and conditions apply.

2
  • So I've spent a little while looking into this, and I don't think it's going to be possible. For the main site image uploader, there's something going on where SE helps marshal the pasted data-blob over to imgur. There's no simple way (given the level of access possible from a userscript) to inject the pasted image into existing upload mechanism, or to otherwise trick it into handling the data. If someone else wants to try (and compete for Doorknob's worship) please do!
    – fredley
    Commented Mar 5, 2015 at 10:36
  • I've implemented this and left an answer with my implementation :)
    – Fastnlight
    Commented Aug 26 at 20:00
1

I've gone ahead and implemented paste functionality, allowing you to simply press paste while having an image copied to your clipboard. Note that it does not open any sort of UI, but the cursor will show a waiting spinner while the image is being uploaded. When the upload finishes, the URL is automatically inserted into the text box.

Here's the new userscript:

// ==UserScript==
// @name Chat Image Upload
// @description Drag and Drop upload images
// @author fredley
// @version 1.0.0
// @match *://chat.meta.stackoverflow.com/rooms/*
// @match *://chat.meta.stackexchange.com/rooms/*
// @match *://chat.stackexchange.com/rooms/*
// @match *://chat.stackoverflow.com/rooms/*
// @match *://chat.askubuntu.com/rooms/*
// @match *://chat.serverfault.com/rooms/*
// @run-at document-end
// ==/UserScript==

function inject() {
    for (var i = 0; i < arguments.length; ++i) {
        if (typeof arguments[i] == "function") {
            var script = document.createElement("script");
            script.type = "text/javascript";
            script.textContent = "(" + arguments[i].toString() + ")(jQuery)";
            document.body.appendChild(script);
        }
    }
}

inject(function ($) {
    async function uploadFile(fkey, image) {
        const formdata = new FormData();
        formdata.append("filename", image), formdata.append("fkey", fkey);
        try {
            const response = await fetch("https://chat.stackexchange.com/upload/image", { method: "post", body: formdata }),
                  responseText = await response.text();

            const responseParsed = responseText.match(/var result = '(.+)'/);
            if (!responseParsed) {
                console.error("Failed to upload image", responseText);
                return "ERROR";
            } else return responseParsed[1];
        } catch (e) {
            console.error(e);
        }
    }

    $(document).ready(function () {
        $("body").append('<div id="dropper"><h1>Upload image!</h1></div>');
        $("body").append(
            "<style>#dropper{display:none;position:fixed;left:0;top:0;width:100%;height:100%;background:rgba(0,0,0,0.7);z-index:9999;}#dropper h1{text-align:center;padding-top:200px;position:absolute;width:100%;color:#FFF;font-size:450%;font-weight:bold;font-family:Helvetica;}body.waiting *{cursor:progress;}</style>"
        );
        $("body").on({
            dragenter: function (e) {
                $("#dropper").show();
                e.preventDefault();
                e.stopPropagation();
            },
            dragover: function (e) {
                $("#dropper").show();
                e.preventDefault();
                e.stopPropagation();
            },
            dragend: function (e) {
                $("#dropper").hide();
                e.preventDefault();
                e.stopPropagation();
            },
            drop: function (e) {
                $("#dropper").hide();
                if (e.originalEvent.dataTransfer && e.originalEvent.dataTransfer.files.length) {
                    console.log("upload!");
                    e.preventDefault();
                    e.stopPropagation();
                    var files = e.originalEvent.dataTransfer.files;
                    initFileUpload().showDialog(function (a) {
                        $("#input").val($("#input").val() + a);
                        $("#input").focus();
                    });
                    setTimeout(function () {
                        $("#filename-input").prop("files", files);
                        setTimeout(function () {
                            $('input[value="upload"]').click();
                        }, 20);
                    }, 20);
                }
            },
            paste: async function (e) {
                // upload the image from clipboard
                try {
                    const clipboardItems = await navigator.clipboard.read();
                    for (const clipboardItem of clipboardItems) {
                        const imageType = clipboardItem.types.find((type) => type.startsWith("image/"));
                        if (!imageType) {
                            return;
                        }
                        const blob = await clipboardItem.getType(imageType);
                        const fkey = $("#fkey").val();
                        document.body.classList.add("waiting");
                        const response = await uploadFile(fkey, blob);
                        document.body.classList.remove("waiting");
                        if (response !== "ERROR") {
                            $("#input").val($("#input").val() + response);
                            $("#input").focus();
                        }
                    }
                } catch (err) {
                    console.error(err.name, err.message);
                }
            },
        });
        $("#dropper").on("click", function (e) {
            $(this).hide();
        });
    });
});

And the download link:

Click to download

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .