This commit is contained in:
poslop
2023-03-24 15:23:01 -05:00
parent a3e93cd5a2
commit adfa36a4fd
13 changed files with 493 additions and 376 deletions

View File

@@ -2,7 +2,7 @@
* @name ImageUtilities
* @author DevilBro
* @authorId 278543574059057154
* @version 5.1.4
* @version 5.1.9
* @description Adds several Utilities for Images/Videos (Gallery, Download, Reverse Search, Zoom, Copy, etc.)
* @invite Jx3TjNS
* @donate https://www.paypal.me/MircoWittrien
@@ -74,22 +74,22 @@ module.exports = (_ => {
};
const fileTypes = {
"3gp": {copyable: false, searchable: false, video: true, signs: [[0x66, 0x74, 0x79, 0x70, 0x33, 0x67]]},
"avi": {copyable: false, searchable: false, video: true, signs: [[0x41, 0x56, 0x49, 0x20]]},
"flv": {copyable: false, searchable: false, video: true, signs: [[0x46, 0x4C, 0x56]]},
"jpeg": {copyable: true, searchable: true, video: false, signs: [[0xFF, 0xD8, 0xFF, 0xEE]]},
"jpg": {copyable: true, searchable: true, video: false, signs: [[0xFF, 0xD8, 0xFF, 0xDB], [0xFF, 0xD8, 0xFF, 0xE0], [0xFF, 0xD8, 0xFF, 0xE1]]},
"gif": {copyable: false, searchable: true, video: false, signs: [[0x47, 0x49, 0x46, 0x38, 0x37, 0x61], [0x47, 0x49, 0x46, 0x38, 0x39, 0x61]]},
"mov": {copyable: false, searchable: false, video: true, signs: [[null, null, null, null, 0x6D, 0x6F, 0x6F, 0x76], [null, null, null, null, 0x66, 0x74, 0x79, 0x70, 0x71, 0x74, 0x20, 0x20]]},
"mp4": {copyable: false, searchable: false, video: true, signs: [[null, null, null, null, 0x66, 0x74, 0x79, 0x70]]},
"mpeg-1": {copyable: false, searchable: false, video: true, signs: [[0x00, 0x00, 0x01, 0xBA]]},
"mpeg-2": {copyable: false, searchable: false, video: true, signs: [[0x00, 0x00, 0x01, 0xB3]]},
"ogg": {copyable: false, searchable: false, video: true, signs: [[0x4F, 0x67, 0x67, 0x53]]},
"png": {copyable: true, searchable: true, video: false, signs: [[0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]]},
"svg": {copyable: false, searchable: false, video: false, signs: [[0x3C]]},
"webm": {copyable: false, searchable: false, video: true, signs: [[0x1A, 0x45, 0xDF, 0xA3]]},
"webp": {copyable: false, searchable: true, video: false, signs: [[0x52, 0x49, 0x46, 0x46, null, null, null, null, 0x57, 0x45, 0x42, 0x50]]},
"wmv": {copyable: false, searchable: false, video: true, signs: [[0x30, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11], [0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C]]}
"3gp": {copyable: false, searchable: false, gif: false, video: true, signs: [[0x66, 0x74, 0x79, 0x70, 0x33, 0x67]]},
"avi": {copyable: false, searchable: false, gif: false, video: true, signs: [[0x41, 0x56, 0x49, 0x20]]},
"flv": {copyable: false, searchable: false, gif: false, video: true, signs: [[0x46, 0x4C, 0x56]]},
"jpeg": {copyable: true, searchable: true, gif: false, video: false, signs: [[0xFF, 0xD8, 0xFF, 0xEE]]},
"jpg": {copyable: true, searchable: true, gif: false, video: false, signs: [[0xFF, 0xD8, 0xFF, 0xDB], [0xFF, 0xD8, 0xFF, 0xE0], [0xFF, 0xD8, 0xFF, 0xE1]]},
"gif": {copyable: false, searchable: true, gif: true, video: false, signs: [[0x47, 0x49, 0x46, 0x38, 0x37, 0x61], [0x47, 0x49, 0x46, 0x38, 0x39, 0x61]]},
"mov": {copyable: false, searchable: false, gif: false, video: true, signs: [[null, null, null, null, 0x6D, 0x6F, 0x6F, 0x76], [null, null, null, null, 0x66, 0x74, 0x79, 0x70, 0x71, 0x74, 0x20, 0x20]]},
"mp4": {copyable: false, searchable: false, gif: false, video: true, signs: [[null, null, null, null, 0x66, 0x74, 0x79, 0x70]]},
"mpeg-1": {copyable: false, searchable: false, gif: false, video: true, signs: [[0x00, 0x00, 0x01, 0xBA]]},
"mpeg-2": {copyable: false, searchable: false, gif: false, video: true, signs: [[0x00, 0x00, 0x01, 0xB3]]},
"ogg": {copyable: false, searchable: false, gif: false, video: true, signs: [[0x4F, 0x67, 0x67, 0x53]]},
"png": {copyable: true, searchable: true, gif: false, video: false, signs: [[0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]]},
"svg": {copyable: false, searchable: false, gif: false, video: false, signs: [[0x3C]]},
"webm": {copyable: false, searchable: false, gif: false, video: true, signs: [[0x1A, 0x45, 0xDF, 0xA3]]},
"webp": {copyable: false, searchable: true, gif: false, video: false, signs: [[0x52, 0x49, 0x46, 0x46, null, null, null, null, 0x57, 0x45, 0x42, 0x50]]},
"wmv": {copyable: false, searchable: false, gif: false, video: true, signs: [[0x30, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11], [0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C]]}
};
const LazyImageSiblingComponent = class LazyImageSibling extends BdApi.React.Component {
@@ -116,11 +116,11 @@ module.exports = (_ => {
className: BDFDB.DOMUtils.formatClassName(BDFDB.disCN._imageutilitiessibling, this.props.className),
onClick: event => {
BDFDB.ListenerUtils.stopEvent(event);
_this.switchImages(this.props.offset);
_this.switchImages(this.props.offset, _this.isValid(this.props.url, "video"));
},
children: [
this.props.loadedImage || BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SpinnerComponents.Spinner, {
type: BDFDB.LibraryComponents.SpinnerComponents.Types.SPINNING_CIRCLE
type: BDFDB.LibraryComponents.SpinnerComponents.Types.WANDERING_CUBES
}),
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SvgIcon, {
className: BDFDB.disCNS._imageutilitiesswitchicon + BDFDB.disCN.svgicon,
@@ -133,12 +133,12 @@ module.exports = (_ => {
const ImageDetailsComponent = class ImageDetails extends BdApi.React.Component {
componentDidMount() {
BDFDB.DOMUtils.addClass(BDFDB.DOMUtils.getParent(BDFDB.dotCN.imagemosaiconebyonegridsingle, BDFDB.ReactUtils.findDOMNode(this)), BDFDB.disCN._imageutilitiesimagedetailsadded);
this.props.attachment = BDFDB.ReactUtils.findValue(BDFDB.ObjectUtils.get(this, `${BDFDB.ReactUtils.instanceKey}.return`), "attachment", {up: true});
BDFDB.ReactUtils.forceUpdate(this);
}
componentDidUpdate() {
if ((!this.props.attachment || !this.props.attachment.size) && !this.props.loaded) {
BDFDB.DOMUtils.addClass(BDFDB.DOMUtils.getParent(BDFDB.dotCN.imagemosaiconebyonegridsingle, BDFDB.ReactUtils.findDOMNode(this)), BDFDB.disCN._imageutilitiesimagedetailsadded);
this.props.loaded = true;
this.props.attachment = BDFDB.ReactUtils.findValue(BDFDB.ObjectUtils.get(this, `${BDFDB.ReactUtils.instanceKey}.return`), "attachment", {up: true});
BDFDB.ReactUtils.forceUpdate(this);
@@ -214,8 +214,9 @@ module.exports = (_ => {
galleryFilter: {},
zoomSettings: {
pixelMode: {value: false, label: "Uses Pixel Lens instead of a Blur Lens"},
lensSize: {value: 200, digits: 0, minValue: 50, maxValue: 5000, unit: "px", label: "context_lenssize"},
zoomLevel: {value: 2, digits: 1, minValue: 1, maxValue: 20, unit: "x", label: "ACCESSIBILITY_ZOOM_LEVEL_LABEL"},
lensSize: {value: 200, digits: 0, minValue: 50, maxValue: 5000, unit: "px", label: "context_lenssize"}
zoomSpeed: {value: 0.1, digits: 2, minValue: 0.01, maxValue: 1, unit: "", label: "context_zoomspeed"}
},
rescaleSettings: {
messages: {value: "NONE", description: "Messages"},
@@ -234,18 +235,18 @@ module.exports = (_ => {
},
engines: {
_all: {value: true, name: BDFDB.LanguageUtils.LanguageStrings.FORM_LABEL_ALL, url: null},
Baidu: {value: true, name: "Baidu", url: "http://image.baidu.com/pcdutu?queryImageUrl=" + imgUrlReplaceString},
Bing: {value: true, name: "Bing", url: "https://www.bing.com/images/search?q=imgurl:" + imgUrlReplaceString + "&view=detailv2&iss=sbi&FORM=IRSBIQ"},
Google: {value: true, name: "Google", url: "https://www.google.com/searchbyimage?sbisrc=1&image_url=" + imgUrlReplaceString},
GoogleLens: {value: true, name: "Google Lens", url: "https://lens.google.com/uploadbyurl?url=" + imgUrlReplaceString},
ImgOps: {value: true, name: "ImgOps", raw: true, url: "https://imgops.com/specialized+reverse/" + imgUrlReplaceString},
IQDB: {value: true, name: "IQDB", url: "https://iqdb.org/?url=" + imgUrlReplaceString},
Reddit: {value: true, name: "Reddit", url: "http://karmadecay.com/search?q=" + imgUrlReplaceString},
SauceNAO: {value: true, name: "SauceNAO", url: "https://saucenao.com/search.php?db=999&url=" + imgUrlReplaceString},
Sogou: {value: true, name: "Sogou", url: "http://pic.sogou.com/ris?flag=1&drag=0&query=" + imgUrlReplaceString + "&flag=1"},
TinEye: {value: true, name: "TinEye", url: "https://tineye.com/search?url=" + imgUrlReplaceString},
WhatAnime: {value: true, name: "WhatAnime", url: "https://trace.moe/?url=" + imgUrlReplaceString},
Yandex: {value: true, name: "Yandex", url: "https://yandex.com/images/search?url=" + imgUrlReplaceString + "&rpt=imageview"}
Baidu: {value: true, name: "Baidu", url: "http://image.baidu.com/pcdutu?queryImageUrl=" + imgUrlReplaceString},
Bing: {value: true, name: "Bing", url: "https://www.bing.com/images/search?q=imgurl:" + imgUrlReplaceString + "&view=detailv2&iss=sbi&FORM=IRSBIQ"},
Google: {value: true, name: "Google", url: "https://www.google.com/searchbyimage?sbisrc=1&image_url=" + imgUrlReplaceString},
GoogleLens: {value: true, name: "Google Lens", url: "https://lens.google.com/uploadbyurl?url=" + imgUrlReplaceString},
ImgOps: {value: true, name: "ImgOps", raw: true, url: "https://imgops.com/specialized+reverse/" + imgUrlReplaceString},
IQDB: {value: true, name: "IQDB", url: "https://iqdb.org/?url=" + imgUrlReplaceString},
Reddit: {value: true, name: "Reddit", url: "http://karmadecay.com/search?q=" + imgUrlReplaceString},
SauceNAO: {value: true, name: "SauceNAO", url: "https://saucenao.com/search.php?db=999&url=" + imgUrlReplaceString},
Sogou: {value: true, name: "Sogou", url: "http://pic.sogou.com/ris?flag=1&drag=0&query=" + imgUrlReplaceString + "&flag=1"},
TinEye: {value: true, name: "TinEye", url: "https://tineye.com/search?url=" + imgUrlReplaceString},
WhatAnime: {value: true, name: "WhatAnime", url: "https://trace.moe/?url=" + imgUrlReplaceString},
Yandex: {value: true, name: "Yandex", url: "https://yandex.com/images/search?url=" + imgUrlReplaceString + "&rpt=imageview"}
}
};
@@ -254,11 +255,13 @@ module.exports = (_ => {
this.modulePatches = {
before: [
"ImageModal",
"ImageVideoModal",
"MessageAccessories",
"Spoiler"
],
after: [
"ImageModal",
"ImageVideoModal",
"LazyImage",
"LazyImageZoomable",
"ModalCarousel",
@@ -278,7 +281,7 @@ module.exports = (_ => {
this.css = `
${BDFDB.dotCNS._imageutilitiesimagedetailsadded + BDFDB.dotCN.imagewrapper} {
border-radius: 8px; !important;
border-radius: 8px !important;
height: calc(100% - 1rem - 16px) !important;
max-height: unset !important;
}
@@ -315,12 +318,24 @@ module.exports = (_ => {
${BDFDB.dotCN._imageutilitiesimagedetails} > span {
max-width: 100px;
}
${BDFDB.dotCN._imageutilitiesgallery},
${BDFDB.dotCN._imageutilitiesdetailsadded} {
${BDFDB.dotCNS._imageutilitiesgallery + BDFDB.dotCN.modal},
${BDFDB.dotCNS._imageutilitiesdetailsadded + BDFDB.dotCN.modal} {
transform: unset !important;
filter: unset !important;
backdrop-filter: unset !important;
}
${BDFDB.dotCN._imageutilitiesgallery} ~ ${BDFDB.dotCN.imagemodalnavbutton} {
display: none;
}
${BDFDB.dotCNS.imagemodal + BDFDB.dotCNS.attachment + BDFDB.dotCN.attachmentvideocontrols},
${BDFDB.dotCNS.imagemodal + BDFDB.dotCN.attachment + BDFDB.dotCNS.attachmentcontrolshidden + BDFDB.dotCN.attachmentvideocontrols}:hover {
bottom: -10px;
transform: unset !important;
transition: bottom 0.3s ease;
}
${BDFDB.dotCNS.imagemodal + BDFDB.dotCN.attachment + BDFDB.dotCNS.attachmentcontrolshidden + BDFDB.dotCN.attachmentvideocontrols} {
bottom: -42px;
}
${BDFDB.dotCNS.imagemodal + BDFDB.notCN._imageutilitiessibling} > ${BDFDB.dotCN.imagewrapper} {
display: flex;
justify-content: center;
@@ -369,6 +384,7 @@ module.exports = (_ => {
}
${BDFDB.dotCNS._imageutilitiessibling + BDFDB.dotCN.spinner} {
position: absolute;
width: 32px;
}
${BDFDB.dotCNS._imageutilitiesprevious + BDFDB.dotCN.spinner} {
right: 21px;
@@ -418,7 +434,7 @@ module.exports = (_ => {
}
onStart () {
BDFDB.ListenerUtils.add(this, document.body, "click", BDFDB.dotCNS.message + BDFDB.dotCNS.imagewrapper + BDFDB.dotCNC.imageoriginallink + BDFDB.dotCNS.message + BDFDB.dotCNS.imagewrapper + "img", e => this.cacheClickedImage(e.target));
BDFDB.ListenerUtils.add(this, document.body, "click", [BDFDB.dotCN.imageoriginallink, "img", BDFDB.dotCN.attachmentcover, BDFDB.dotCN.attachmentcovericon, "video"].map(n => BDFDB.dotCNS.message + BDFDB.dotCNS.imagewrapper + n).join(", "), e => this.cacheClickedImage(e.target));
this.forceUpdateAll();
}
@@ -677,9 +693,9 @@ module.exports = (_ => {
onGuildContextMenu (e) {
if (!this.settings.places.guildIcons || !e.instance.props.guild) return;
if (BDFDB.DOMUtils.getParent(BDFDB.dotCN.guildheader, e.instance.props.target) || BDFDB.DOMUtils.getParent(BDFDB.dotCN.guildchannels, e.instance.props.target) && !e.instance.props.target.className && e.instance.props.target.parentElement.firstElementChild == e.instance.props.target) {
if (BDFDB.DOMUtils.getParent(BDFDB.dotCNC.guildheader + BDFDB.dotCN.guildchannels, e.instance.props.target) && (!e.instance.props.target.className && e.instance.props.target.parentElement.firstElementChild == e.instance.props.target) || (e.instance.props.target.className && e.instance.props.target.className.indexOf(BDFDB.disCN.guildheaderbanneranimatedhoverlayer) > -1)) {
let banner = BDFDB.GuildUtils.getBanner(e.instance.props.guild.id);
if (banner) this.injectItem(e, [banner.replace(/\.webp|\.gif/, ".png"), e.instance.props.guild.banner && BDFDB.LibraryModules.IconUtils.isAnimatedIconHash(e.instance.props.guild.banner), banner], BDFDB.LanguageUtils.LibraryStrings.guildbanner);
if (banner) this.injectItem(e, [banner.replace(/\.webp|\.gif/, ".png"), e.instance.props.guild.banner && BDFDB.LibraryModules.IconUtils.isAnimatedIconHash(e.instance.props.guild.banner) && banner.replace(/\.webp|\.png/, ".gif")], BDFDB.LanguageUtils.LibraryStrings.guildbanner);
}
else if (!BDFDB.DOMUtils.getParent(BDFDB.dotCN.channels, e.instance.props.target)) this.injectItem(e, [(e.instance.props.guild.getIconURL(4096) || "").replace(/\.webp|\.gif/, ".png"), e.instance.props.guild.icon && BDFDB.LibraryModules.IconUtils.isAnimatedIconHash(e.instance.props.guild.icon) && e.instance.props.guild.getIconURL(4096, true)], BDFDB.LanguageUtils.LibraryStrings.guildicon);
}
@@ -703,24 +719,21 @@ module.exports = (_ => {
onMessageContextMenu (e) {
if (!e.instance.props.message || !e.instance.props.channel || !e.instance.props.target) return;
if (e.instance.props.attachment) this.injectItem(e, [{original: e.instance.props.attachment.url, file: e.instance.props.attachment.proxy_url}], null, true);
const target = e.instance.props.target.tagName == "A" && BDFDB.DOMUtils.containsClass(e.instance.props.target, BDFDB.disCN.imageoriginallink) && e.instance.props.target.parentElement.querySelector("img") || (BDFDB.DOMUtils.getParent(BDFDB.dotCN.messageattachment, e.instance.props.target) || e.instance.props.target).querySelector("img, video") || e.instance.props.target;
if (target.tagName == "A" && e.instance.props.message.embeds && e.instance.props.message.embeds[0] && (e.instance.props.message.embeds[0].type == "image" || e.instance.props.message.embeds[0].type == "video" || e.instance.props.message.embeds[0].type == "gifv")) this.injectItem(e, [target.href], null, true);
else if (target.tagName == "IMG" && target.complete && target.naturalHeight) {
if (BDFDB.DOMUtils.getParent(BDFDB.dotCN.imagewrapper, target) || BDFDB.DOMUtils.containsClass(target, BDFDB.disCN.imagesticker)) this.injectItem(e, [{file: target.src, original: this.getTargetLink(e.instance.props.target) || this.getTargetLink(target)}], null, true);
else if (BDFDB.DOMUtils.containsClass(target, BDFDB.disCN.embedauthoricon) && this.settings.places.userAvatars) this.injectItem(e, [target.src], null, true);
else if (BDFDB.DOMUtils.containsClass(target, BDFDB.disCN.emojiold, "emote", false) && this.settings.places.emojis) this.injectItem(e, [{file: target.src, alternativeName: target.getAttribute("data-name")}], null, true);
}
else if (target.tagName == "VIDEO") {
if (BDFDB.DOMUtils.containsClass(target, BDFDB.disCN.embedvideo) || BDFDB.DOMUtils.getParent(BDFDB.dotCN.attachmentvideo, target)) this.injectItem(e, [{file: target.src, original: this.getTargetLink(e.instance.props.target) || this.getTargetLink(target)}], null, true);
}
else {
const target = e.instance.props.target.tagName == "A" && BDFDB.DOMUtils.containsClass(e.instance.props.target, BDFDB.disCN.imageoriginallink) && e.instance.props.target.parentElement.querySelector("img, video") || e.instance.props.target;
if (target.tagName == "A" && e.instance.props.message.embeds && e.instance.props.message.embeds[0] && (e.instance.props.message.embeds[0].type == "image" || e.instance.props.message.embeds[0].type == "video" || e.instance.props.message.embeds[0].type == "gifv")) this.injectItem(e, [target.href], null, true);
else if (target.tagName == "IMG" && target.complete && target.naturalHeight) {
if (BDFDB.DOMUtils.getParent(BDFDB.dotCN.imagewrapper, target) || BDFDB.DOMUtils.containsClass(target, BDFDB.disCN.imagesticker)) this.injectItem(e, [{file: target.src, original: this.getTargetLink(e.instance.props.target) || this.getTargetLink(target)}], null, true);
else if (BDFDB.DOMUtils.containsClass(target, BDFDB.disCN.embedauthoricon) && this.settings.places.userAvatars) this.injectItem(e, [target.src], null, true);
else if (BDFDB.DOMUtils.containsClass(target, BDFDB.disCN.emojiold, "emote", false) && this.settings.places.emojis) this.injectItem(e, [{file: target.src, alternativeName: target.getAttribute("data-name")}], null, true);
}
else if (target.tagName == "VIDEO") {
if (BDFDB.DOMUtils.containsClass(target, BDFDB.disCN.embedvideo) || BDFDB.DOMUtils.getParent(BDFDB.dotCN.attachmentvideo, target)) this.injectItem(e, [{file: target.src, original: this.getTargetLink(e.instance.props.target) || this.getTargetLink(target)}], null, true);
}
else {
const reaction = BDFDB.DOMUtils.getParent(BDFDB.dotCN.messagereaction, target);
if (reaction && this.settings.places.emojis) {
const emoji = reaction.querySelector(BDFDB.dotCN.emojiold);
if (emoji) this.injectItem(e, [{file: emoji.src, alternativeName: emoji.getAttribute("data-name")}], null, true);
}
const reaction = BDFDB.DOMUtils.getParent(BDFDB.dotCN.messagereaction, target);
if (reaction && this.settings.places.emojis) {
const emoji = reaction.querySelector(BDFDB.dotCN.emojiold);
if (emoji) this.injectItem(e, [{file: emoji.src, alternativeName: emoji.getAttribute("data-name")}], null, true);
}
}
}
@@ -766,10 +779,8 @@ module.exports = (_ => {
filterUrls (...urls) {
let addedUrls = [];
return urls.filter(n => this.isValid(n && n.file || n)).map(n => {
let srcUrl = (n.file || n).replace(/^url\(|\)$|"|'/g, "").replace(/\?size\=\d+$/, "?size=4096").replace(/\?size\=\d+&/, "?size=4096&").replace(/[\?\&](height|width)=\d+/g, "").split("%3A")[0];
if (srcUrl.startsWith("https://cdn.discordapp.com/") && !srcUrl.endsWith("?size=4096") && srcUrl.indexOf("?size=4096&") == -1) srcUrl += "?size=4096";
let originalUrl = (n.original || n.file || n).replace(/^url\(|\)$|"|'/g, "").replace(/\?size\=\d+$/, "?size=4096").replace(/\?size\=\d+&/, "?size=4096&").replace(/[\?\&](height|width)=\d+/g, "").split("%3A")[0];
if (originalUrl.startsWith("https://cdn.discordapp.com/") && !originalUrl.endsWith("?size=4096") && originalUrl.indexOf("?size=4096&") == -1) originalUrl += "?size=4096";
let srcUrl = (n.file || n).replace(/^url\(|\)$|"|'/g, "");
let originalUrl = (n.original || n.file || n).replace(/^url\(|\)$|"|'/g, "");
let fileUrl = srcUrl;
if (fileUrl.indexOf("https://images-ext-1.discordapp.net/external/") > -1 || fileUrl.indexOf("https://images-ext-2.discordapp.net/external/") > -1) {
if (fileUrl.split("/https/").length > 1) fileUrl = "https://" + fileUrl.split("/https/").pop();
@@ -803,16 +814,21 @@ module.exports = (_ => {
let enabledEngines = BDFDB.ObjectUtils.filter(this.settings.engines, n => n);
let enginesWithoutAll = BDFDB.ObjectUtils.filter(enabledEngines, n => n != "_all", true);
let engineKeys = Object.keys(enginesWithoutAll);
let locations = Object.keys(ownLocations).filter(n => ownLocations[n].enabled);
let isVideo = this.isValid(urlData.file, "video");
let type = isVideo ? BDFDB.LanguageUtils.LanguageStrings.VIDEO : BDFDB.LanguageUtils.LanguageStrings.IMAGE;
return BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuGroup, {
children: [
BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuItem, {
label: BDFDB.LanguageUtils.LanguageStrings.COPY_LINK,
id: BDFDB.ContextMenuUtils.createItemId(this.name, "copy-link"),
action: _ => {
BDFDB.LibraryModules.WindowUtils.copy(urlData.original.split("?size")[0]);
let url = urlData.original.split("?width")[0].split("?height")[0].split("?size")[0];
url = url.indexOf("discordapp.com/avatars/") > 0 || url.indexOf("discordapp.com/icons/") > 0 ? `${url}?size=4096` : url;
BDFDB.LibraryModules.WindowUtils.copy(url);
BDFDB.NotificationUtils.toast(BDFDB.LanguageUtils.LanguageStrings.LINK_COPIED, {type: "success"});
}
}),
@@ -820,7 +836,9 @@ module.exports = (_ => {
label: BDFDB.LanguageUtils.LanguageStrings.COPY_MEDIA_LINK,
id: BDFDB.ContextMenuUtils.createItemId(this.name, "copy-media-link"),
action: _ => {
BDFDB.LibraryModules.WindowUtils.copy(urlData.file.split("?size")[0]);
let url = urlData.file.split("?width")[0].split("?height")[0].split("?size")[0];
url = url.indexOf("discordapp.com/avatars/") > 0 || url.indexOf("discordapp.com/icons/") > 0 ? `${url}?size=4096` : url;
BDFDB.LibraryModules.WindowUtils.copy(url);
BDFDB.NotificationUtils.toast(BDFDB.LanguageUtils.LanguageStrings.LINK_COPIED, {type: "success"});
}
}),
@@ -832,7 +850,7 @@ module.exports = (_ => {
!this.isValid(urlData.file, "copyable") ? null : BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuItem, {
label: this.labels.context_copy.replace("{{var0}}", type),
id: BDFDB.ContextMenuUtils.createItemId(this.name, "copy-file"),
action: _ => this.copyFile(urlData.src)
action: _ => this.copyFile({url: urlData.src, fallbackUrl: urlData.file || urlData.original})
}),
!document.querySelector(BDFDB.dotCN.imagemodal) && BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuItem, {
label: this.labels.context_view.replace("{{var0}}", type),
@@ -840,33 +858,28 @@ module.exports = (_ => {
action: _ => {
const imageThrowaway = document.createElement(isVideo ? "video" : "img");
imageThrowaway.addEventListener(isVideo ? "loadedmetadata" : "load", function() {
_this.cacheClickedImage(target);
BDFDB.LibraryModules.ModalUtils.openModal(modalData => {
_this.cacheClickedImage(target);
return BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.ModalComponents.ModalRoot, Object.assign({
className: BDFDB.disCN.imagemodal
}, modalData, {
size: BDFDB.LibraryComponents.ModalComponents.ModalSize.DYNAMIC,
"aria-label": BDFDB.LanguageUtils.LanguageStrings.IMAGE,
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.ImageModal, {
animated: !!isVideo,
children: isVideo ? BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.ImageVideoModal, {
src: imageThrowaway.src,
poster: this.getPosterUrl(imageThrowaway.src),
width: this.videoWidth,
naturalWidth: this.videoWidth,
height: this.videoHeight,
naturalHeight: this.videoHeight,
renderLinkComponent: props => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Anchor, props)
}) : BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.ImageModal, {
src: imageThrowaway.src,
original: urlData.original,
width: isVideo ? this.videoWidth : this.width,
height: isVideo ? this.videoHeight : this.height,
width: this.width,
height: this.height,
className: BDFDB.disCN.imagemodalimage,
shouldAnimate: true,
renderLinkComponent: props => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Anchor, props),
children: !isVideo ? null : (videoData => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Video, {
ignoreMaxSize: true,
poster: _this.getPosterUrl(urlData.src || urlData.file),
src: urlData.src || urlData.file,
width: videoData.size.width,
height: videoData.size.height,
naturalWidth: this.videoWidth,
naturalHeight: this.videoHeight,
play: true,
playOnHover: !!BDFDB.LibraryStores.AccessibilityStore.useReducedMotion
}))
renderLinkComponent: props => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Anchor, props)
})
}), true);
});
@@ -922,7 +935,22 @@ module.exports = (_ => {
});
}
processImageModal (e) {
processModalCarousel (e) {
if (!this.settings.viewerSettings.galleryMode || !BDFDB.ReactUtils.findParent(e.returnvalue, {name: ["ImageVideoModal", "ImageModal"]})) return;
e.returnvalue.props.className = "";
e.returnvalue.props.children[0] = null;
e.returnvalue.props.children[2] = null;
if (e.returnvalue.props.children[1] && switchedImageProps) {
e.returnvalue.props.children[1].props = Object.assign(e.returnvalue.props.children[1].props, switchedImageProps);
switchedImageProps = null;
}
}
processImageVideoModal (e) {
this.processImageModal(e, true);
}
processImageModal (e, filterForVideos) {
if (!e.returnvalue) {
if (switchedImageProps) {
e.instance.props = Object.assign(e.instance.props, switchedImageProps);
@@ -931,11 +959,10 @@ module.exports = (_ => {
}
else {
let url = this.getImageSrc(viewedImage && viewedImage.proxy_url || typeof e.instance.props.children == "function" && e.instance.props.children(Object.assign({}, e.instance.props, {size: e.instance.props})).props.src || e.instance.props.src);
let isVideo = this.isValid(url, "video");
let [children, index] = BDFDB.ReactUtils.findParent(e.returnvalue, {props: [["className", BDFDB.disCN.downloadlink]]});
if (index > -1) {
let type = isVideo ? BDFDB.LanguageUtils.LanguageStrings.VIDEO : BDFDB.LanguageUtils.LanguageStrings.IMAGE;
let type = filterForVideos ? BDFDB.LanguageUtils.LanguageStrings.VIDEO : BDFDB.LanguageUtils.LanguageStrings.IMAGE;
let openContext = event => BDFDB.ContextMenuUtils.open(this, event, BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuGroup, {
children: Object.keys(this.defaults.zoomSettings).map(type => {
let isBoolean = typeof this.defaults.zoomSettings[type].value == "boolean";
@@ -1018,7 +1045,7 @@ module.exports = (_ => {
children: this.labels.context_copy.replace("{{var0}}", type),
onClick: event => {
BDFDB.ListenerUtils.stopEvent(event);
this.copyFile(url);
this.copyFile({url: url});
}
})
],
@@ -1040,7 +1067,7 @@ module.exports = (_ => {
}
})
],
this.settings.viewerSettings.zoomMode && !isVideo && [
this.settings.viewerSettings.zoomMode && !filterForVideos && !this.isValid(e.instance.props.src, "gif") && [
BDFDB.ReactUtils.createElement("span", {
className: BDFDB.disCN.downloadlink,
children: "|",
@@ -1061,9 +1088,9 @@ module.exports = (_ => {
className: BDFDB.disCN._imageutilitiesdetailswrapper,
children: [
e.instance.props.alt && {label: "Alt", text: e.instance.props.alt},
{label: "Source", text: url},
{label: "Source", text: url.split("?width")[0].split("?height")[0].split("?size")[0]},
{label: "Size", text: `${e.instance.props.width}x${e.instance.props.height}px`},
cachedImages && cachedImages.amount && cachedImages.amount > 1 && {label: "Image", text: `${cachedImages.index + 1 || 1} of ${cachedImages.amount}`}
cachedImages && cachedImages.amount && cachedImages.amount > 1 && {label: filterForVideos ? "Video" : "Image", text: `${cachedImages.index + 1 || 1} of ${cachedImages.amount}`}
].filter(n => n).map(data => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TextElement, {
className: BDFDB.disCN._imageutilitiesdetails,
children: [
@@ -1107,7 +1134,7 @@ module.exports = (_ => {
let messages = [], index = -1;
if (result) {
messages = result.body.flat(10).reverse();
cachedImages = {all: this.filterMessagesForImages(messages, viewedImage)};
cachedImages = {all: this.filterMessagesForImages(messages, viewedImage, filterForVideos)};
index = this.getImageIndex(cachedImages.all, viewedImage);
}
if (index > -1) cachedImages = Object.assign(cachedImages, {
@@ -1149,8 +1176,8 @@ module.exports = (_ => {
this.addListener("keydown", "Gallery", event => {
if (!firedEvents.includes("Gallery")) {
firedEvents.push("Gallery");
if (event.keyCode == 37) this.switchImages(-1);
else if (event.keyCode == 39) this.switchImages(1);
if (event.keyCode == 37) this.switchImages(-1, filterForVideos);
else if (event.keyCode == 39) this.switchImages(1, filterForVideos);
}
});
this.addListener("keyup", "Gallery", _ => BDFDB.ArrayUtils.remove(firedEvents, "Gallery", true));
@@ -1160,13 +1187,6 @@ module.exports = (_ => {
}
}
processModalCarousel (e) {
if (!this.settings.viewerSettings.galleryMode || !BDFDB.ReactUtils.findParent(e.returnvalue, {name: "ImageModal"})) return;
e.returnvalue.props.className = "";
e.returnvalue.props.children[0] = null;
e.returnvalue.props.children[2] = null;
}
processLazyImage (e) {
if (e.node) {
if (e.instance.props.resized) {
@@ -1199,25 +1219,24 @@ module.exports = (_ => {
BDFDB.TimeUtils.clear(viewedImageTimeout);
let modal = BDFDB.DOMUtils.getParent(BDFDB.dotCN.modal, e.node);
if (modal) {
modal.className = BDFDB.DOMUtils.formatClassName(modal.className, this.settings.viewerSettings.galleryMode && BDFDB.disCN._imageutilitiesgallery, this.settings.viewerSettings.details && BDFDB.disCN._imageutilitiesdetailsadded);
modal.parentElement.className = BDFDB.DOMUtils.formatClassName(modal.parentElement.className, this.settings.viewerSettings.galleryMode && BDFDB.disCN._imageutilitiesgallery, this.settings.viewerSettings.details && BDFDB.disCN._imageutilitiesdetailsadded);
if (this.settings.viewerSettings.galleryMode) {
BDFDB.DOMUtils.addClass(modal, BDFDB.disCN.imagemodal);
BDFDB.DOMUtils.removeClass(modal, BDFDB.disCN.modalcarouselmodal, BDFDB.disCN.modalcarouselmodalzoomed);
}
}
let isVideo = typeof e.instance.props.children == "function";
if (isVideo && !BDFDB.LibraryStores.AccessibilityStore.useReducedMotion) e.node.style.setProperty("pointer-events", "none");
if (this.settings.viewerSettings.zoomMode && !isVideo && !BDFDB.DOMUtils.containsClass(e.node.parentElement, BDFDB.disCN._imageutilitiessibling)) {
if (this.isValid(e.instance.props.src, "gif")) e.node.style.setProperty("pointer-events", "none");
if (this.settings.viewerSettings.zoomMode && typeof e.instance.props.children != "function" && !BDFDB.DOMUtils.containsClass(e.node.parentElement, BDFDB.disCN._imageutilitiessibling)) {
e.node.style.setProperty("cursor", "zoom-in");
e.node.addEventListener("mousedown", event => {
if (event.which != 1 || e.node.querySelector("video")) return;
BDFDB.ListenerUtils.stopEvent(event);
let vanishObserver;
let zoomLevel = this.settings.zoomSettings.zoomLevel;
let imgRects = BDFDB.DOMUtils.getRects(e.node.firstElementChild);
let lens = BDFDB.DOMUtils.create(`<div class="${BDFDB.disCN._imageutilitieslense}" style="border-radius: 50% !important; pointer-events: none !important; z-index: 10000 !important; width: ${this.settings.zoomSettings.lensSize}px !important; height: ${this.settings.zoomSettings.lensSize}px !important; position: fixed !important;"><div style="position: absolute !important; top: 0 !important; right: 0 !important; bottom: 0 !important; left: 0 !important;"><${e.node.firstElementChild.tagName} src="${!this.isValid(e.instance.props.src, "video") ? e.instance.props.src : this.getPosterUrl(e.instance.props.src)}" style="width: ${imgRects.width * this.settings.zoomSettings.zoomLevel}px; height: ${imgRects.height * this.settings.zoomSettings.zoomLevel}px; position: fixed !important;${this.settings.zoomSettings.pixelMode ? " image-rendering: pixelated !important;" : ""}"${e.node.firstElementChild.tagName == "VIDEO" ? " loop autoplay" : ""}></${e.node.firstElementChild.tagName}></div></div>`);
let lens = BDFDB.DOMUtils.create(`<div class="${BDFDB.disCN._imageutilitieslense}" style="border-radius: 50% !important; pointer-events: none !important; z-index: 10000 !important; width: ${this.settings.zoomSettings.lensSize}px !important; height: ${this.settings.zoomSettings.lensSize}px !important; position: fixed !important;"><div style="position: absolute !important; top: 0 !important; right: 0 !important; bottom: 0 !important; left: 0 !important;"><${e.node.firstElementChild.tagName} src="${!this.isValid(e.instance.props.src, "video") ? e.instance.props.src : this.getPosterUrl(e.instance.props.src)}" style="width: ${imgRects.width * zoomLevel}px; height: ${imgRects.height * zoomLevel}px; position: fixed !important;${this.settings.zoomSettings.pixelMode ? " image-rendering: pixelated !important;" : ""}"${e.node.firstElementChild.tagName == "VIDEO" ? " loop autoplay" : ""}></${e.node.firstElementChild.tagName}></div></div>`);
let pane = lens.firstElementChild.firstElementChild;
let backdrop = BDFDB.DOMUtils.create(`<div class="${BDFDB.disCN._imageutilitieslensebackdrop}" style="background: rgba(0, 0, 0, 0.3) !important; position: absolute !important; top: 0 !important; right: 0 !important; bottom: 0 !important; left: 0 !important; pointer-events: none !important; z-index: 8000 !important;"></div>`);
let appMount = document.querySelector(BDFDB.dotCN.appmount);
@@ -1239,14 +1258,14 @@ module.exports = (_ => {
lens.style.setProperty("height", this.settings.zoomSettings.lensSize + "px", "important");
lens.style.setProperty("clip-path", `circle(${(this.settings.zoomSettings.lensSize/2) + 2}px at center)`, "important");
lens.firstElementChild.style.setProperty("clip-path", `circle(${this.settings.zoomSettings.lensSize/2}px at center)`, "important");
pane.style.setProperty("left", imgRects.left + ((this.settings.zoomSettings.zoomLevel - 1) * (imgRects.left - x - halfW)) + "px", "important");
pane.style.setProperty("top", imgRects.top + ((this.settings.zoomSettings.zoomLevel - 1) * (imgRects.top - y - halfH)) + "px", "important");
pane.style.setProperty("width", imgRects.width * this.settings.zoomSettings.zoomLevel + "px", "important");
pane.style.setProperty("height", imgRects.height * this.settings.zoomSettings.zoomLevel + "px", "important");
pane.style.setProperty("left", imgRects.left + ((zoomLevel - 1) * (imgRects.left - x - halfW)) + "px", "important");
pane.style.setProperty("top", imgRects.top + ((zoomLevel - 1) * (imgRects.top - y - halfH)) + "px", "important");
pane.style.setProperty("width", imgRects.width * zoomLevel + "px", "important");
pane.style.setProperty("height", imgRects.height * zoomLevel + "px", "important");
};
lens.update();
for (let ele of [e.node, document.querySelector(BDFDB.dotCN.modalcarouselwrapper)]) if (ele) ele.style.setProperty("pointer-events", "none", "important");
for (let ele of [e.node, document.querySelector(BDFDB.dotCN.imagemodal)]) if (ele) ele.style.setProperty("pointer-events", "none", "important");
let dragging = event2 => {
event = event2;
@@ -1254,7 +1273,7 @@ module.exports = (_ => {
};
let releasing = event2 => {
BDFDB.ListenerUtils.stopEvent(event2);
for (let ele of [e.node, document.querySelector(BDFDB.dotCN.modalcarouselwrapper)]) if (ele) ele.style.removeProperty("pointer-events");
for (let ele of [e.node, document.querySelector(BDFDB.dotCN.imagemodal)]) if (ele) ele.style.removeProperty("pointer-events");
this.cleanupListeners("Zoom");
document.removeEventListener("mousemove", dragging);
document.removeEventListener("mouseup", releasing);
@@ -1269,12 +1288,12 @@ module.exports = (_ => {
this.addListener("wheel", "Zoom", event2 => {
if (!document.contains(e.node)) this.cleanupListeners("Zoom");
else {
if (event2.deltaY < 0 && (this.settings.zoomSettings.zoomLevel + 0.1) <= this.defaults.zoomSettings.zoomLevel.maxValue) {
this.settings.zoomSettings.zoomLevel += 0.1;
if (event2.deltaY < 0 && (zoomLevel + this.settings.zoomSettings.zoomSpeed * zoomLevel) <= this.defaults.zoomSettings.zoomLevel.maxValue) {
zoomLevel += this.settings.zoomSettings.zoomSpeed * zoomLevel;
lens.update();
}
else if (event2.deltaY > 0 && (this.settings.zoomSettings.zoomLevel - 0.1) >= this.defaults.zoomSettings.zoomLevel.minValue) {
this.settings.zoomSettings.zoomLevel -= 0.1;
else if (event2.deltaY > 0 && (zoomLevel - this.settings.zoomSettings.zoomSpeed * zoomLevel) >= this.defaults.zoomSettings.zoomLevel.minValue) {
zoomLevel -= this.settings.zoomSettings.zoomSpeed * zoomLevel;
lens.update();
}
}
@@ -1283,12 +1302,12 @@ module.exports = (_ => {
if (!document.contains(e.node)) this.cleanupListeners("Zoom");
else if (!firedEvents.includes("Zoom")) {
firedEvents.push("Zoom");
if (event2.keyCode == 187 && (this.settings.zoomSettings.zoomLevel + 0.5) <= this.defaults.zoomSettings.zoomLevel.maxValue) {
this.settings.zoomSettings.zoomLevel += 0.5;
if (event2.keyCode == 187 && (zoomLevel + zoomLevel * 0.5) <= this.defaults.zoomSettings.zoomLevel.maxValue) {
zoomLevel += zoomLevel * 0.5;
lens.update();
}
else if (event2.keyCode == 189 && (this.settings.zoomSettings.zoomLevel - 0.5) >= this.defaults.zoomSettings.zoomLevel.minValue) {
this.settings.zoomSettings.zoomLevel -= 0.5;
else if (event2.keyCode == 189 && (zoomLevel - zoomLevel * 0.5) >= this.defaults.zoomSettings.zoomLevel.minValue) {
zoomLevel -= zoomLevel * 0.5;
lens.update();
}
}
@@ -1443,10 +1462,11 @@ module.exports = (_ => {
cacheClickedImage (target) {
if (!target) return;
const image = (BDFDB.DOMUtils.getParent(BDFDB.dotCN.imagewrapper, target) || target).querySelector("img") || target;
const image = (BDFDB.DOMUtils.getParent(BDFDB.dotCN.imagewrapper, target) || target).querySelector("img, video") || target;
if (!image) return;
const message = BDFDB.ReactUtils.findValue(image, "message", {up: true});
if (!message) return;
BDFDB.DOMUtils.hide(document.querySelectorAll(BDFDB.dotCN.tooltip));
firstViewedImage = {messageId: message.id, channelId: message.channel_id, proxy_url: image.src};
viewedImage = firstViewedImage;
if (cachedImages) cachedImages.index = this.getImageIndex(cachedImages.all, viewedImage);
@@ -1456,65 +1476,60 @@ module.exports = (_ => {
}, 1000);
}
downloadFile (urls, path, alternativeName, fallbackToRequest) {
if (!urls) return BDFDB.NotificationUtils.toast(this.labels.toast_save_failed.replace("{{var0}}", BDFDB.LanguageUtils.LanguageStrings.IMAGE).replace("{{var1}}", path || "PC"), {type: "danger"});
requestFile (urls, onLoad, onError, config = {}) {
if (!urls || typeof onLoad != "function") return typeof onError == "function" && onError();
let url = urls.url.startsWith("/assets") ? (window.location.origin + urls.url) : urls.url;
if (!fallbackToRequest) BDFDB.DiscordUtils.requestFileData(url, {timeout: 3000}, (error, buffer) => {
let isResized = !config.orignalSizeChecked && (url.indexOf("?width=") > -1 || url.indexOf("?height=") > -1 || url.indexOf("?size=") > -1);
if (!config.fallbackToRequest) BDFDB.DiscordUtils.requestFileData(isResized ? url.split("?width")[0].split("?height")[0].split("?size")[0] : url, {timeout: 3000}, (error, buffer) => {
if (error || !buffer) {
if (urls.fallbackUrl && urls.url != urls.fallbackUrl) this.downloadFile({url: urls.fallbackUrl, oldUrl: urls.url}, path, alternativeName);
else this.downloadFile({url: urls.oldUrl || urls.url, fallbackUrl: urls.oldUrl ? urls.url : undefined}, path, alternativeName, true);
}
else {
let extension = this.getFileExtension(new Uint8Array(buffer));
if (!extension) BDFDB.NotificationUtils.toast(this.labels.toast_save_failed.replace("{{var0}}", BDFDB.LanguageUtils.LanguageStrings.IMAGE).replace("{{var1}}", path || "PC"), {type: "danger"});
else {
let type = fileTypes[extension].video ? BDFDB.LanguageUtils.LanguageStrings.VIDEO : BDFDB.LanguageUtils.LanguageStrings.IMAGE;
if (path) BDFDB.LibraryRequires.fs.writeFile(this.getFileName(path, (alternativeName || url.split("/").pop().split(".").slice(0, -1).join(".") || "unknown").slice(0, 35), extension, 0), Buffer.from(buffer), error => {
if (error) BDFDB.NotificationUtils.toast(this.labels.toast_save_failed.replace("{{var0}}", type).replace("{{var1}}", path), {type: "danger"});
else BDFDB.NotificationUtils.toast(this.labels.toast_save_success.replace("{{var0}}", type).replace("{{var1}}", path), {type: "success"});
});
else {
let hrefURL = window.URL.createObjectURL(new Blob([buffer], {type: this.getMimeType(extension)}));
let tempLink = document.createElement("a");
tempLink.href = hrefURL;
tempLink.download = `${(alternativeName || url.split("/").pop().split(".").slice(0, -1).join(".") || "unknown").slice(0, 35)}.${extension}`;
tempLink.click();
window.URL.revokeObjectURL(hrefURL);
}
}
if (isResized) this.requestFile(urls, onLoad, onError, {orignalSizeChecked: true});
else if (urls.fallbackUrl && urls.url != urls.fallbackUrl) this.requestFile({url: urls.fallbackUrl, oldUrl: urls.url}, onLoad, onError);
else this.requestFile({url: urls.oldUrl || urls.url, fallbackUrl: urls.oldUrl ? urls.url : undefined}, onLoad, onError, {fallbackToRequest: true});
}
else onLoad(url, buffer);
});
else BDFDB.LibraryRequires.request(url, {agentOptions: {rejectUnauthorized: false}, headers: {"Content-Type": "application/json"}}, (error, response, buffer) => {
else BDFDB.LibraryRequires.request(isResized ? url.split("?width")[0].split("?height")[0].split("?size")[0] : url, {agentOptions: {rejectUnauthorized: false}, headers: {"Content-Type": "application/json"}}, (error, response, buffer) => {
if (error || response.statusCode != 200 || response.headers["content-type"].indexOf("text/html") > -1) {
if (urls.fallbackUrl && urls.url != urls.fallbackUrl) this.downloadFile({url: urls.fallbackUrl}, path, alternativeName, true);
else BDFDB.NotificationUtils.toast(this.labels.toast_save_failed.replace("{{var0}}", BDFDB.LanguageUtils.LanguageStrings.IMAGE).replace("{{var1}}", path || "PC"), {type: "danger"});
}
else {
let extension = this.getFileExtension(new Uint8Array(buffer));
if (!extension) BDFDB.NotificationUtils.toast(this.labels.toast_save_failed.replace("{{var0}}", BDFDB.LanguageUtils.LanguageStrings.IMAGE).replace("{{var1}}", path || "PC"), {type: "danger"});
else {
let type = fileTypes[extension].video ? BDFDB.LanguageUtils.LanguageStrings.VIDEO : BDFDB.LanguageUtils.LanguageStrings.IMAGE;
if (path) BDFDB.LibraryRequires.fs.writeFile(this.getFileName(path, (alternativeName || url.split("/").pop().split(".").slice(0, -1).join(".") || "unknown").slice(0, 35), extension, 0), Buffer.from(buffer), error => {
if (error) BDFDB.NotificationUtils.toast(this.labels.toast_save_failed.replace("{{var0}}", type).replace("{{var1}}", path), {type: "danger"});
else BDFDB.NotificationUtils.toast(this.labels.toast_save_success.replace("{{var0}}", type).replace("{{var1}}", path), {type: "success"});
});
else {
let hrefURL = window.URL.createObjectURL(new Blob([buffer], {type: this.getMimeType(extension)}));
let tempLink = document.createElement("a");
tempLink.href = hrefURL;
tempLink.download = `${(alternativeName || url.split("/").pop().split(".").slice(0, -1).join(".") || "unknown").slice(0, 35)}.${extension}`;
tempLink.click();
window.URL.revokeObjectURL(hrefURL);
}
}
if (isResized) this.requestFile(urls, onLoad, onError, {orignalSizeChecked: true, fallbackToRequest: true});
else if (urls.fallbackUrl && urls.url != urls.fallbackUrl) this.requestFile({url: urls.fallbackUrl}, onLoad, onError, {fallbackToRequest: true});
else if (typeof onError == "function") onError();
}
else onLoad(url, buffer);
});
}
copyFile (url) {
let type = this.isValid(url, "video") ? BDFDB.LanguageUtils.LanguageStrings.VIDEO : BDFDB.LanguageUtils.LanguageStrings.IMAGE;
BDFDB.LibraryModules.WindowUtils.copyImage(url);
BDFDB.NotificationUtils.toast(this.labels.toast_copy_success.replace("{{var0}}", type), {type: "success"});
downloadFile (urls, path, alternativeName) {
this.requestFile(urls, (url, buffer) => {
let extension = this.getFileExtension(new Uint8Array(buffer));
if (!extension) BDFDB.NotificationUtils.toast(this.labels.toast_save_failed.replace("{{var0}}", BDFDB.LanguageUtils.LanguageStrings.IMAGE).replace("{{var1}}", path || "PC"), {type: "danger"});
else {
let type = fileTypes[extension].video ? BDFDB.LanguageUtils.LanguageStrings.VIDEO : BDFDB.LanguageUtils.LanguageStrings.IMAGE;
if (path) BDFDB.LibraryRequires.fs.writeFile(this.getFileName(path, (alternativeName || url.split("/").pop().split(".").slice(0, -1).join(".") || "unknown").slice(0, 35), extension, 0), Buffer.from(buffer), error => {
if (error) BDFDB.NotificationUtils.toast(this.labels.toast_save_failed.replace("{{var0}}", type).replace("{{var1}}", path), {type: "danger"});
else BDFDB.NotificationUtils.toast(this.labels.toast_save_success.replace("{{var0}}", type).replace("{{var1}}", path), {type: "success"});
});
else {
let hrefURL = window.URL.createObjectURL(new Blob([buffer], {type: this.getMimeType(extension)}));
let tempLink = document.createElement("a");
tempLink.href = hrefURL;
tempLink.download = `${(alternativeName || url.split("/").pop().split(".").slice(0, -1).join(".") || "unknown").slice(0, 35)}.${extension}`;
tempLink.click();
window.URL.revokeObjectURL(hrefURL);
}
}
}, _ => {
BDFDB.NotificationUtils.toast(this.labels.toast_save_failed.replace("{{var0}}", BDFDB.LanguageUtils.LanguageStrings.IMAGE).replace("{{var1}}", path || "PC"), {type: "danger"});
});
}
copyFile (urls) {
this.requestFile(urls, (url, buffer) => {
let type = this.isValid(url, "video") ? BDFDB.LanguageUtils.LanguageStrings.VIDEO : BDFDB.LanguageUtils.LanguageStrings.IMAGE;
BDFDB.LibraryModules.WindowUtils.copyImage(url);
BDFDB.NotificationUtils.toast(this.labels.toast_copy_success.replace("{{var0}}", type), {type: "success"});
}, _ => {
BDFDB.NotificationUtils.toast(this.labels.toast_copy_failed.replace("{{var0}}", BDFDB.LanguageUtils.LanguageStrings.IMAGE), {type: "danger"});
});
}
getDownloadLocation () {
@@ -1548,24 +1563,26 @@ module.exports = (_ => {
getImageSrc (img) {
if (!img) return null;
return (typeof img == "string" ? img : (img.proxy_url || img.src || (typeof img.querySelector == "function" && img.querySelector("canvas") ? img.querySelector("canvas").src : ""))).split("?width=")[0];
return (typeof img == "string" ? img : (img.proxy_url || img.src || (typeof img.querySelector == "function" && img.querySelector("canvas") ? img.querySelector("canvas").src : "")));
}
getImageIndex (messages, img) {
return messages.findIndex(i => i.messageId == img.messageId && (messages.filter(n => n.messageId == i.messageId).length < 2 || i.url && img.proxy_url.indexOf(i.url) > -1 || i.proxy_url && img.proxy_url.indexOf(i.proxy_url) > -1));
return messages.findIndex(i => i.messageId == img.messageId && (messages.filter(n => n.messageId == i.messageId).length < 2 || i.url && img.proxy_url && img.proxy_url.indexOf(i.url) > -1 || i.proxy_url && img.proxy_url && img.proxy_url.indexOf(i.proxy_url) > -1));
}
filterMessagesForImages (messages, img) {
filterMessagesForImages (messages, img, filterForVideos) {
return messages.filter(m => m && m.channel_id == img.channelId && !BDFDB.LibraryStores.RelationshipStore.isBlocked(m.author.id) && (firstViewedImage && m.id == firstViewedImage.messageId || m.id == img.messageId || m.embeds.filter(e => e.image || e.thumbnail || e.video).length || m.attachments.filter(a => !a.filename.startsWith("SPOILER_")).length)).map(m => [m.attachments, m.embeds].flat(10).filter(n => n).map(i => Object.assign({messageId: m.id, channelId: img.channelId}, i, i.image, i.thumbnail, i.video))).flat(10).filter(n => {
if (!n) return false;
let type = (n.type || n.content_type || "").split("/")[0];
if (type && (filterForVideos && type != "video" || !filterForVideos && type == "video")) return false;
if (!n.content_type || img.proxy_url == n.proxy_url || img.proxy_url == n.url || img.proxy_url == n.href) return true;
let extension = (n.content_type.split("/")[1] || "").split("+")[0] || "";
if (extension && this.settings.galleryFilter[extension] === false) return false;
if (extension && (!fileTypes[extension] || this.settings.galleryFilter[extension] === false)) return false;
return true;
});
}
switchImages (offset) {
switchImages (offset, filterForVideos) {
const newIndex = parseInt(cachedImages.index) + parseInt(offset);
if (newIndex < 0 || newIndex > (cachedImages.amount - 1)) return;
@@ -1587,7 +1604,7 @@ module.exports = (_ => {
}).then(result => {
if (result && viewedImage) {
const messages = result.body.flat(10).reverse();
Object.assign(cachedImages, {all: this.filterForCopies([].concat(cachedImages.all, this.filterMessagesForImages(messages, viewedImage)))});
Object.assign(cachedImages, {all: this.filterForCopies([].concat(cachedImages.all, this.filterMessagesForImages(messages, viewedImage, filterForVideos)))});
const index = this.getImageIndex(cachedImages.all, viewedImage);
cachedImages = Object.assign(cachedImages, {
channelId: viewedImage.channelId,
@@ -1614,7 +1631,7 @@ module.exports = (_ => {
}).then(result => {
if (result && viewedImage) {
const messages = result.body.flat(10).reverse();
Object.assign(cachedImages, {all: this.filterForCopies([].concat(this.filterMessagesForImages(messages, viewedImage), cachedImages.all))});
Object.assign(cachedImages, {all: this.filterForCopies([].concat(this.filterMessagesForImages(messages, viewedImage, filterForVideos), cachedImages.all))});
const index = this.getImageIndex(cachedImages.all, viewedImage);
cachedImages = Object.assign(cachedImages, {
channelId: viewedImage.channelId,
@@ -1638,7 +1655,7 @@ module.exports = (_ => {
height: thisViewedImage.height,
children: !isVideo ? null : (videoData => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Video, {
ignoreMaxSize: true,
poster: thisViewedImage.proxy_url.replace("https://cdn.discordapp.com", "https://media.discordapp.net").split("?size=")[0] + "?format=jpeg",
poster: this.getPosterUrl(thisViewedImage.proxy_url),
src: thisViewedImage.proxy_url,
width: videoData.size.width,
height: videoData.size.height,
@@ -1657,7 +1674,7 @@ module.exports = (_ => {
filterForCopies (messages) {
let filtered = [];
for (let message of messages) if (!filtered.find(n => n.messageId == message.messageId)) filtered.push(message);
for (let message of messages) if (!filtered.find(n => n.messageId == message.messageId && n.id == message.id)) filtered.push(message);
return filtered;
}
@@ -1686,6 +1703,7 @@ module.exports = (_ => {
context_copy: "Копирайте {{var0}}",
context_imageactions: "Действия с изображения",
context_lenssize: "Размер на обектива",
context_zoomspeed: "Скорост на мащабиране",
context_saveas: "Запазете {{var0}} като ...",
context_searchwith: "Търсете {{var0}} с ...",
context_videoactions: "Видео действия",
@@ -1701,6 +1719,7 @@ module.exports = (_ => {
context_copy: "Zkopírovat {{var0}}",
context_imageactions: "Akce s obrázky",
context_lenssize: "Velikost lupy",
context_zoomspeed: "Rychlost zoomu",
context_saveas: "Uložit {{var0}} jako...",
context_searchwith: "Hledat {{var0}} pomocí...",
context_videoactions: "Video akce",
@@ -1716,6 +1735,7 @@ module.exports = (_ => {
context_copy: "Kopiér {{var0}}",
context_imageactions: "Billedhandlinger",
context_lenssize: "Objektivstørrelse",
context_zoomspeed: "Zoomhastighed",
context_saveas: "Gem {{var0}} som ...",
context_searchwith: "Søg i {{var0}} med ...",
context_videoactions: "Videohandlinger",
@@ -1731,6 +1751,7 @@ module.exports = (_ => {
context_copy: "{{var0}} kopieren",
context_imageactions: "Bildaktionen",
context_lenssize: "Linsengröße",
context_zoomspeed: "Zoomgeschwindigkeit",
context_saveas: "{{var0}} speichern als ...",
context_searchwith: "{{var0}} suchen mit ...",
context_videoactions: "Videoaktionen",
@@ -1746,6 +1767,7 @@ module.exports = (_ => {
context_copy: "Αντιγραφή {{var0}}",
context_imageactions: "Ενέργειες εικόνας",
context_lenssize: "Μέγεθος φακού",
context_zoomspeed: "Ταχύτητα ζουμ",
context_saveas: "Αποθήκευση {{var0}} ως ...",
context_searchwith: "Αναζήτηση {{var0}} με ...",
context_videoactions: "Ενέργειες βίντεο",
@@ -1761,6 +1783,7 @@ module.exports = (_ => {
context_copy: "Copiar {{var0}}",
context_imageactions: "Acciones de imagen",
context_lenssize: "Tamaño de la lente",
context_zoomspeed: "Velocidad de zoom",
context_saveas: "Guardar {{var0}} como ...",
context_searchwith: "Buscar {{var0}} con ...",
context_videoactions: "Acciones de vídeo",
@@ -1776,6 +1799,7 @@ module.exports = (_ => {
context_copy: "Kopioi {{var0}}",
context_imageactions: "Kuvatoiminnot",
context_lenssize: "Linssin koko",
context_zoomspeed: "Zoomausnopeus",
context_saveas: "Tallenna {{var0}} nimellä ...",
context_searchwith: "Tee haku {{var0}} ...",
context_videoactions: "Videotoiminnot",
@@ -1791,6 +1815,7 @@ module.exports = (_ => {
context_copy: "Copier {{var0}}",
context_imageactions: "Actions sur les images",
context_lenssize: "Taille de l'objectif",
context_zoomspeed: "Vitesse de zoom",
context_saveas: "Enregistrer {{var0}} sous ...",
context_searchwith: "Rechercher {{var0}} avec ...",
context_videoactions: "Actions vidéo",
@@ -1806,6 +1831,7 @@ module.exports = (_ => {
context_copy: "कॉपी {{var0}}",
context_imageactions: "छवि क्रियाएँ",
context_lenssize: "लेंस का आकार",
context_zoomspeed: "ज़ूम गति",
context_saveas: "{{var0}} को इस रूप में सेव करें...",
context_searchwith: "इसके साथ {{var0}} खोजें ...",
context_videoactions: "वीडियो क्रिया",
@@ -1821,6 +1847,7 @@ module.exports = (_ => {
context_copy: "Kopiraj {{var0}}",
context_imageactions: "Radnje slike",
context_lenssize: "Veličina leće",
context_zoomspeed: "Brzina zumiranja",
context_saveas: "Spremi {{var0}} kao ...",
context_searchwith: "Traži {{var0}} sa ...",
context_videoactions: "Video radnje",
@@ -1836,6 +1863,7 @@ module.exports = (_ => {
context_copy: "{{var0}} másolása",
context_imageactions: "Képműveletek",
context_lenssize: "Lencse mérete",
context_zoomspeed: "Zoom sebesség",
context_saveas: "{{var0}} mentése másként ...",
context_searchwith: "Keresés a következőben: {{var0}} a következővel:",
context_videoactions: "Videóműveletek",
@@ -1851,6 +1879,7 @@ module.exports = (_ => {
context_copy: "Copia {{var0}}",
context_imageactions: "Azioni immagine",
context_lenssize: "Dimensione della lente",
context_zoomspeed: "Velocità dello zoom",
context_saveas: "Salva {{var0}} come ...",
context_searchwith: "Cerca {{var0}} con ...",
context_videoactions: "Azioni video",
@@ -1866,6 +1895,7 @@ module.exports = (_ => {
context_copy: "{{var0}} をコピーします",
context_imageactions: "画像アクション",
context_lenssize: "レンズサイズ",
context_zoomspeed: "ズーム速度",
context_saveas: "{{var0}} を...として保存します",
context_searchwith: "{{var0}} を...で検索",
context_videoactions: "ビデオ アクション",
@@ -1881,6 +1911,7 @@ module.exports = (_ => {
context_copy: "{{var0}} 복사",
context_imageactions: "이미지 작업",
context_lenssize: "렌즈 크기",
context_zoomspeed: "줌 속도",
context_saveas: "{{var0}} 을 다른 이름으로 저장 ...",
context_searchwith: "{{var0}} 검색 ...",
context_videoactions: "비디오 작업",
@@ -1896,6 +1927,7 @@ module.exports = (_ => {
context_copy: "Kopijuoti {{var0}}",
context_imageactions: "Vaizdo veiksmai",
context_lenssize: "Objektyvo dydis",
context_zoomspeed: "Priartinimo greitis",
context_saveas: "Išsaugoti '{{var0}}' kaip ...",
context_searchwith: "Ieškoti {{var0}} naudojant ...",
context_videoactions: "Vaizdo įrašų veiksmai",
@@ -1911,6 +1943,7 @@ module.exports = (_ => {
context_copy: "Kopieer {{var0}}",
context_imageactions: "Afbeeldingsacties",
context_lenssize: "Lens Maat",
context_zoomspeed: "Zoom snelheid",
context_saveas: "Bewaar {{var0}} als ...",
context_searchwith: "Zoek {{var0}} met ...",
context_videoactions: "Video-acties",
@@ -1926,6 +1959,7 @@ module.exports = (_ => {
context_copy: "Kopier {{var0}}",
context_imageactions: "Bildehandlinger",
context_lenssize: "Linsestørrelse",
context_zoomspeed: "Zoomhastighet",
context_saveas: "Lagre {{var0}} som ...",
context_searchwith: "Søk på {{var0}} med ...",
context_videoactions: "Videohandlinger",
@@ -1941,6 +1975,7 @@ module.exports = (_ => {
context_copy: "Kopiuj {{var0}}",
context_imageactions: "Działania związane z obrazem",
context_lenssize: "Rozmiar soczewki",
context_zoomspeed: "Szybkość zoomu",
context_saveas: "Zapisz {{var0}} jako ...",
context_searchwith: "Wyszukaj {{var0}} za pomocą ...",
context_videoactions: "Akcje wideo",
@@ -1956,6 +1991,7 @@ module.exports = (_ => {
context_copy: "Copiar {{var0}}",
context_imageactions: "Ações de imagem",
context_lenssize: "Tamanho da lente",
context_zoomspeed: "Velocidade do zoom",
context_saveas: "Salvar {{var0}} como ...",
context_searchwith: "Pesquisar {{var0}} com ...",
context_videoactions: "Ações de vídeo",
@@ -1971,6 +2007,7 @@ module.exports = (_ => {
context_copy: "Copiați {{var0}}",
context_imageactions: "Acțiuni de imagine",
context_lenssize: "Dimensiunea obiectivului",
context_zoomspeed: "Viteza de zoom",
context_saveas: "Salvați {{var0}} ca ...",
context_searchwith: "Căutați {{var0}} cu ...",
context_videoactions: "Acțiuni video",
@@ -1986,6 +2023,7 @@ module.exports = (_ => {
context_copy: "Скопируйте {{var0}}",
context_imageactions: "Действия с изображением",
context_lenssize: "Размер линзы",
context_zoomspeed: "Скорость масштабирования",
context_saveas: "Сохранить {{var0}} как ...",
context_searchwith: "Искать {{var0}} с помощью ...",
context_videoactions: "Действия с видео",
@@ -2001,6 +2039,7 @@ module.exports = (_ => {
context_copy: "Kopiera {{var0}}",
context_imageactions: "Bildåtgärder",
context_lenssize: "Linsstorlek",
context_zoomspeed: "Zoomhastighet",
context_saveas: "Spara {{var0}} som ...",
context_searchwith: "Sök {{var0}} med ...",
context_videoactions: "Videoåtgärder",
@@ -2016,6 +2055,7 @@ module.exports = (_ => {
context_copy: "คัดลอก{{var0}}",
context_imageactions: "การทำงานของรูปภาพ",
context_lenssize: "ขนาดเลนส์",
context_zoomspeed: "ความเร็วในการซูม",
context_saveas: "บันทึก{{var0}}เป็น ...",
context_searchwith: "ค้นหา{{var0}} ้วย ...",
context_videoactions: "การกระทำของวิดีโอ",
@@ -2031,6 +2071,7 @@ module.exports = (_ => {
context_copy: "{{var0}} kopyala",
context_imageactions: "Görüntü Eylemleri",
context_lenssize: "Lens Boyutu",
context_zoomspeed: "yakınlaştırma hızı",
context_saveas: "{{var0}} farklı kaydet ...",
context_searchwith: "{{var0}} şununla ara ...",
context_videoactions: "Video Eylemleri",
@@ -2046,6 +2087,7 @@ module.exports = (_ => {
context_copy: "Копіювати {{var0}}",
context_imageactions: "Дії із зображеннями",
context_lenssize: "Розмір лінзи",
context_zoomspeed: "Швидкість масштабування",
context_saveas: "Збережіть {{var0}} як ...",
context_searchwith: "Шукати {{var0}} за допомогою ...",
context_videoactions: "Відео дії",
@@ -2061,6 +2103,7 @@ module.exports = (_ => {
context_copy: "Sao chép {{var0}}",
context_imageactions: "Hành động hình ảnh",
context_lenssize: "Kích thước ống kính",
context_zoomspeed: "tốc độ thu phóng",
context_saveas: "Lưu {{var0}} dưới dạng ...",
context_searchwith: "Tìm kiếm {{var0}} bằng ...",
context_videoactions: "Hành động video",
@@ -2076,6 +2119,7 @@ module.exports = (_ => {
context_copy: "复制 {{var0}}",
context_imageactions: "图像动作",
context_lenssize: "缩放尺寸",
context_zoomspeed: "变焦速度",
context_saveas: "将 {{var0}} 另存到...",
context_searchwith: "搜索 {{var0}} 使用...",
context_videoactions: "视频动作",
@@ -2091,6 +2135,7 @@ module.exports = (_ => {
context_copy: "複製 {{var0}}",
context_imageactions: "圖像動作",
context_lenssize: "縮放尺寸",
context_zoomspeed: "变焦速度",
context_saveas: "將 {{var0}} 另存到...",
context_searchwith: "搜尋 {{var0}} 使用...",
context_videoactions: "視頻動作",
@@ -2106,6 +2151,7 @@ module.exports = (_ => {
context_copy: "Copy {{var0}}",
context_imageactions: "Image Actions",
context_lenssize: "Lens Size",
context_zoomspeed: "Zoom speed",
context_saveas: "Save {{var0}} as ...",
context_searchwith: "Search {{var0}} with ...",
context_videoactions: "Video Actions",
@@ -2120,4 +2166,4 @@ module.exports = (_ => {
}
};
})(window.BDFDB_Global.PluginUtils.buildPlugin(changeLog));
})();
})();