WebContextMenus: fix copying images
This commit is contained in:
parent
8a168bd185
commit
3d64f3da41
1 changed files with 44 additions and 23 deletions
|
@ -46,6 +46,21 @@ const settings = definePluginSettings({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const MEDIA_PROXY_URL = "https://media.discordapp.net";
|
||||||
|
const CDN_URL = "https://cdn.discordapp.com";
|
||||||
|
|
||||||
|
function fixImageUrl(urlString: string) {
|
||||||
|
const url = new URL(urlString);
|
||||||
|
if (url.origin === CDN_URL) return urlString;
|
||||||
|
if (url.origin === MEDIA_PROXY_URL) return CDN_URL + url.pathname;
|
||||||
|
|
||||||
|
url.searchParams.delete("width");
|
||||||
|
url.searchParams.delete("height");
|
||||||
|
url.searchParams.set("quality", "lossless");
|
||||||
|
if (url.searchParams.get("format") === "webp") url.searchParams.set("format", "png");
|
||||||
|
return url.toString();
|
||||||
|
}
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "WebContextMenus",
|
name: "WebContextMenus",
|
||||||
description: "Re-adds context menus missing in the web version of Discord: Links & Images (Copy/Open Link/Image), Text Area (Copy, Cut, Paste, SpellCheck)",
|
description: "Re-adds context menus missing in the web version of Discord: Links & Images (Copy/Open Link/Image), Text Area (Copy, Cut, Paste, SpellCheck)",
|
||||||
|
@ -182,34 +197,40 @@ export default definePlugin({
|
||||||
],
|
],
|
||||||
|
|
||||||
async copyImage(url: string) {
|
async copyImage(url: string) {
|
||||||
if (IS_VESKTOP && VesktopNative.clipboard) {
|
url = fixImageUrl(url);
|
||||||
const data = await fetch(url).then(r => r.arrayBuffer());
|
|
||||||
VesktopNative.clipboard.copyImage(data, url);
|
let imageData = await fetch(url).then(r => r.blob());
|
||||||
return;
|
if (imageData.type !== "image/png") {
|
||||||
|
const bitmap = await createImageBitmap(imageData);
|
||||||
|
|
||||||
|
const canvas = document.createElement("canvas");
|
||||||
|
canvas.width = bitmap.width;
|
||||||
|
canvas.height = bitmap.height;
|
||||||
|
canvas.getContext("2d")!.drawImage(bitmap, 0, 0);
|
||||||
|
|
||||||
|
await new Promise<void>(done => {
|
||||||
|
canvas.toBlob(data => {
|
||||||
|
imageData = data!;
|
||||||
|
done();
|
||||||
|
}, "image/png");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clipboard only supports image/png, jpeg and similar won't work. Thus, we need to convert it to png
|
if (IS_VESKTOP && VesktopNative.clipboard) {
|
||||||
// via canvas first
|
VesktopNative.clipboard.copyImage(await imageData.arrayBuffer(), url);
|
||||||
const img = new Image();
|
return;
|
||||||
img.onload = () => {
|
} else {
|
||||||
const canvas = document.createElement("canvas");
|
navigator.clipboard.write([
|
||||||
canvas.width = img.naturalWidth;
|
new ClipboardItem({
|
||||||
canvas.height = img.naturalHeight;
|
"image/png": imageData
|
||||||
canvas.getContext("2d")!.drawImage(img, 0, 0);
|
})
|
||||||
|
]);
|
||||||
canvas.toBlob(data => {
|
}
|
||||||
navigator.clipboard.write([
|
|
||||||
new ClipboardItem({
|
|
||||||
"image/png": data!
|
|
||||||
})
|
|
||||||
]);
|
|
||||||
}, "image/png");
|
|
||||||
};
|
|
||||||
img.crossOrigin = "anonymous";
|
|
||||||
img.src = url;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
async saveImage(url: string) {
|
async saveImage(url: string) {
|
||||||
|
url = fixImageUrl(url);
|
||||||
|
|
||||||
const data = await fetchImage(url);
|
const data = await fetchImage(url);
|
||||||
if (!data) return;
|
if (!data) return;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue