diff --git a/Plugins/ImageUtilities/ImageUtilities.plugin.js b/Plugins/ImageUtilities/ImageUtilities.plugin.js index fca83a9782..bde3fa247e 100644 --- a/Plugins/ImageUtilities/ImageUtilities.plugin.js +++ b/Plugins/ImageUtilities/ImageUtilities.plugin.js @@ -2,7 +2,7 @@ * @name ImageUtilities * @author DevilBro * @authorId 278543574059057154 - * @version 5.0.4 + * @version 5.0.5 * @description Adds several Utilities for Images/Videos (Gallery, Download, Reverse Search, Zoom, Copy, etc.) * @invite Jx3TjNS * @donate https://www.paypal.me/MircoWittrien @@ -170,7 +170,7 @@ module.exports = (_ => { height: 16, onClick: event => { BDFDB.ListenerUtils.stopEvent(event); - _this.downloadFile(this.props.attachment.proxy_url || this.props.original); + _this.downloadFile({url: this.props.attachment.proxy_url || this.props.original}); }, onContextMenu: event => { let locations = Object.keys(ownLocations).filter(n => ownLocations[n].enabled); @@ -178,7 +178,7 @@ module.exports = (_ => { children: locations.map((name, i) => BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuItem, { id: BDFDB.ContextMenuUtils.createItemId(_this.name, "download", name, i), label: name, - action: _ => _this.downloadFile(this.props.attachment.proxy_url || this.props.original, ownLocations[name].location) + action: _ => _this.downloadFile({url: this.props.attachment.proxy_url || this.props.original}, ownLocations[name].location) })) })); } @@ -666,51 +666,50 @@ module.exports = (_ => { } onGuildContextMenu (e) { - if (e.instance.props.guild && this.settings.places.guildIcons) { - 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) { - 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); - } - 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); + 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) { + 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); } + 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); } onUserContextMenu (e) { - if (e.instance.props.user && this.settings.places.userAvatars) { - const guildId = BDFDB.LibraryStores.SelectedGuildStore.getGuildId(); - const member = BDFDB.LibraryStores.GuildMemberStore.getMember(guildId, e.instance.props.user.id); - this.injectItem(e, [(e.instance.props.user.getAvatarURL(null, 4096) || "").replace(/\.webp|\.gif/, ".png"), BDFDB.LibraryModules.IconUtils.isAnimatedIconHash(e.instance.props.user.avatar) && e.instance.props.user.getAvatarURL(null, 4096, true), (e.instance.props.user.getAvatarURL(guildId, 4096) || "").replace(/\.webp|\.gif/, ".png"), member && member.avatar && BDFDB.LibraryModules.IconUtils.isAnimatedIconHash(member.avatar) && e.instance.props.user.getAvatarURL(guildId, 4096, true)]); - } + if (!this.settings.places.userAvatars || !e.instance.props.user) return; + const guildId = BDFDB.LibraryStores.SelectedGuildStore.getGuildId(); + const member = BDFDB.LibraryStores.GuildMemberStore.getMember(guildId, e.instance.props.user.id); + this.injectItem(e, [(e.instance.props.user.getAvatarURL(null, 4096) || "").replace(/\.webp|\.gif/, ".png"), BDFDB.LibraryModules.IconUtils.isAnimatedIconHash(e.instance.props.user.avatar) && e.instance.props.user.getAvatarURL(null, 4096, true), (e.instance.props.user.getAvatarURL(guildId, 4096) || "").replace(/\.webp|\.gif/, ".png"), member && member.avatar && BDFDB.LibraryModules.IconUtils.isAnimatedIconHash(member.avatar) && e.instance.props.user.getAvatarURL(guildId, 4096, true)]); } onGroupDMContextMenu (e) { - if (e.instance.props.channel && e.instance.props.channel.isGroupDM() && this.settings.places.groupIcons) this.injectItem(e, [(BDFDB.DMUtils.getIcon(e.instance.props.channel.id) || "").replace(/\.webp|\.gif/, ".png")]); + if (!this.settings.places.groupIcons || !e.instance.props.channel || !e.instance.props.channel.isGroupDM()) return; + this.injectItem(e, [(BDFDB.DMUtils.getIcon(e.instance.props.channel.id) || "").replace(/\.webp|\.gif/, ".png")]); } onImageContextMenu (e) { - if (e.instance.props.href || e.instance.props.src) this.injectItem(e, [e.instance.props.href || e.instance.props.src]); + if (!e.instance.props.href && !e.instance.props.src) return; + this.injectItem(e, [e.instance.props.href || e.instance.props.src]); } onMessageContextMenu (e) { - if (e.instance.props.message && e.instance.props.channel && e.instance.props.target) { - if (e.instance.props.attachment) this.injectItem(e, [e.instance.props.attachment.url]); + if (!e.instance.props.message || !e.instance.props.channel || !e.instance.props.target) return; + if (e.instance.props.attachment) this.injectItem(e, [e.instance.props.attachment.url]); + 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]); + 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)}]); + else if (BDFDB.DOMUtils.containsClass(target, BDFDB.disCN.embedauthoricon) && this.settings.places.userAvatars) this.injectItem(e, [target.src]); + 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")}]); + } + 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)}]); + } 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]); - 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)}]); - else if (BDFDB.DOMUtils.containsClass(target, BDFDB.disCN.embedauthoricon) && this.settings.places.userAvatars) this.injectItem(e, [target.src]); - 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")}]); - } - 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)}]); - } - 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")}]); - } + 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")}]); } } } @@ -868,12 +867,12 @@ module.exports = (_ => { BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuItem, { label: this.labels.context_saveas.replace("{{var0}}", type), id: BDFDB.ContextMenuUtils.createItemId(this.name, "download-file-as"), - action: _ => this.downloadFile(urlData.src, null, urlData.original, urlData.alternativeName), + action: _ => this.downloadFile({url: urlData.src, fallbackUrl: urlData.file || urlData.original}, null, urlData.alternativeName), children: locations.length && BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuGroup, { children: locations.map((name, i) => BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuItem, { id: BDFDB.ContextMenuUtils.createItemId(this.name, "download", name, i), label: name, - action: _ => this.downloadFile(urlData.src, ownLocations[name].location, urlData.original, urlData.alternativeName) + action: _ => this.downloadFile({url: urlData.src, fallbackUrl: urlData.file || urlData.original}, ownLocations[name].location, urlData.alternativeName) })) }) }), @@ -995,7 +994,7 @@ module.exports = (_ => { children: this.labels.context_saveas.replace("{{var0}}", type), onClick: event => { BDFDB.ListenerUtils.stopEvent(event); - this.downloadFile(url); + this.downloadFile({url: url}); }, onContextMenu: event => { let locations = Object.keys(ownLocations).filter(n => ownLocations[n].enabled); @@ -1003,7 +1002,7 @@ module.exports = (_ => { children: locations.map((name, i) => BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuItem, { id: BDFDB.ContextMenuUtils.createItemId(this.name, "download", name, i), label: name, - action: _ => this.downloadFile(url, ownLocations[name].location) + action: _ => this.downloadFile({url: url}, ownLocations[name].location) })) })); } @@ -1305,7 +1304,7 @@ module.exports = (_ => { e.instance.props.resized = true; } } - if (this.settings.rescaleSettings.messages != "NONE" && (!e.instance.props.className || e.instance.props.className.indexOf(BDFDB.disCN.embedthumbnail) == -1) && (!e.instance.props.containerClassName || e.instance.props.containerClassName.indexOf(BDFDB.disCN.embedthumbnail) == -1) && BDFDB.ReactUtils.findOwner(reactInstance, {name: "LazyImageZoomable", up: true})) { + if (this.settings.rescaleSettings.messages != "NONE" && (!e.instance.props.className || e.instance.props.className.indexOf(BDFDB.disCN.embedthumbnail) == -1) && (!e.instance.props.containerClassName || e.instance.props.containerClassName.indexOf(BDFDB.disCN.embedthumbnail) == -1 && e.instance.props.containerClassName.indexOf(BDFDB.disCN.embedvideoimagecomponent) == -1) && BDFDB.ReactUtils.findOwner(reactInstance, {name: "LazyImageZoomable", up: true})) { let aRects = BDFDB.DOMUtils.getRects(document.querySelector(BDFDB.dotCN.appmount)); let mRects = BDFDB.DOMUtils.getRects(document.querySelector(BDFDB.dotCNC.messageaccessory + BDFDB.dotCN.messagecontents)); let mwRects = BDFDB.DOMUtils.getRects(document.querySelector(BDFDB.dotCN.messagewrapper)); @@ -1440,13 +1439,13 @@ module.exports = (_ => { }, 1000); } - downloadFile (url, path, fallbackUrl, alternativeName, fallbackToRequest) { - if (!url) return BDFDB.NotificationUtils.toast(this.labels.toast_save_failed.replace("{{var0}}", BDFDB.LanguageUtils.LanguageStrings.IMAGE).replace("{{var1}}", path || "PC"), {type: "danger"}); - url = url.startsWith("/assets") ? (window.location.origin + url) : url; + 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"}); + let url = urls.url.startsWith("/assets") ? (window.location.origin + urls.url) : urls.url; if (!fallbackToRequest) BDFDB.DiscordUtils.requestFileData(url, {timeout: 3000}, (error, buffer) => { if (error || !buffer) { - if (fallbackUrl) this.downloadFile(fallbackUrl, path, null, alternativeName); - else this.downloadFile(url, path, null, alternativeName, true); + 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)); @@ -1470,7 +1469,7 @@ module.exports = (_ => { }); else BDFDB.LibraryRequires.request(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 (fallbackUrl) this.downloadFile(fallbackUrl, path, null, alternativeName, true); + 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 { @@ -1540,7 +1539,7 @@ module.exports = (_ => { } filterMessagesForImages (messages, img) { - return messages.filter(m => m && m.channel_id == img.channelId && !BDFDB.LibraryStores.RelationshipStore.isBlocked(m.author.id) && (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 => { + 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; 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] || "";