This commit is contained in:
Mirco Wittrien 2022-03-19 19:01:43 +01:00
parent 183b399922
commit abea614b7d
2 changed files with 301 additions and 182 deletions

View File

@ -2,7 +2,7 @@
* @name EditUsers
* @author DevilBro
* @authorId 278543574059057154
* @version 4.5.3
* @version 4.5.4
* @description Allows you to locally edit Users
* @invite Jx3TjNS
* @donate https://www.paypal.me/MircoWittrien
@ -17,8 +17,13 @@ module.exports = (_ => {
"info": {
"name": "EditUsers",
"author": "DevilBro",
"version": "4.5.3",
"version": "4.5.4",
"description": "Allows you to locally edit Users"
},
"changeLog": {
"fixed": {
"Voice Channels": "Works in Voice Channels again"
}
}
};
@ -130,8 +135,9 @@ module.exports = (_ => {
QuickSwitchUserResult: "render",
SearchPopoutComponent: "render",
PrivateChannelCallParticipants: "render",
VideoParticipants: "default",
ChannelCall: "render",
ChannelCallGrid: "default",
HorizontalVideoParticipants: "default",
PictureInPictureVideo: "default",
UserSummaryItem: "render"
},
@ -1228,18 +1234,19 @@ module.exports = (_ => {
}
}
processVideoParticipants (e) {
processChannelCall (e) {
if (BDFDB.ArrayUtils.is(e.instance.props.participants) && this.settings.places.voiceChat) {
e.instance.props.participants = [].concat(e.instance.props.participants);
for (let i in e.instance.props.participants) if (e.instance.props.participants[i] && e.instance.props.participants[i].user) e.instance.props.participants[i] = Object.assign({}, e.instance.props.participants[i], {user: this.getUserData(e.instance.props.participants[i].user.id)});
}
}
processChannelCall (e) {
if (BDFDB.ArrayUtils.is(e.instance.props.participants) && this.settings.places.voiceChat) {
e.instance.props.participants = [].concat(e.instance.props.participants);
for (let i in e.instance.props.participants) if (e.instance.props.participants[i] && e.instance.props.participants[i].user) e.instance.props.participants[i] = Object.assign({}, e.instance.props.participants[i], {user: this.getUserData(e.instance.props.participants[i].user.id)});
}
processChannelCallGrid (e) {
this.processChannelCall(e);
}
processHorizontalVideoParticipants (e) {
this.processChannelCall(e);
}
processPictureInPictureVideo (e) {

View File

@ -2,7 +2,7 @@
* @name ImageUtilities
* @author DevilBro
* @authorId 278543574059057154
* @version 4.6.6
* @version 4.6.7
* @description Adds several Utilities for Images/Videos (Gallery, Download, Reverse Search, Zoom, Copy, etc.)
* @invite Jx3TjNS
* @donate https://www.paypal.me/MircoWittrien
@ -17,21 +17,12 @@ module.exports = (_ => {
"info": {
"name": "ImageUtilities",
"author": "DevilBro",
"version": "4.6.6",
"version": "4.6.7",
"description": "Adds several Utilities for Images/Videos (Gallery, Download, Reverse Search, Zoom, Copy, etc.)"
},
"changeLog": {
"progress": {
"Settings": "<strong style='color: red;'>SETTINGS HAVE BEEN REORGANIZED AND CAUSED SOME SETTINGS TO RESET, CHECK YOUR PLUGIN SETTINGS IF SOMETHING IS BEHAVING DIFFERENTLY</strong>"
},
"fixed": {
"Banners": "No longer show in low Resolution"
},
"added": {
"Resize in Chat": "Added Option to resize Images in Messages"
},
"improved": {
"Gallery Mode": "Now allows you to switch between all currently loaded Images in a Channel"
"Gallery Mode Channel Wide": "Gallery Mode now let's you move between all images/gifs in a channel, it will automatically load new images/gifs once you hit the last/first in the current queue"
}
}
};
@ -75,9 +66,13 @@ module.exports = (_ => {
}
} : (([Plugin, BDFDB]) => {
var _this;
var firedEvents = [], clickedImage;
var firedEvents = [];
var ownLocations = {}, downloadsFolder;
var firstViewedImage, viewedImage, viewedImageTimeout;
var cachedImages;
var eventTypes = {};
const imgUrlReplaceString = "DEVILBRO_BD_REVERSEIMAGESEARCH_REPLACE_IMAGEURL";
const fileTypes = {
@ -105,6 +100,42 @@ module.exports = (_ => {
"wmv": {copyable: false, searchable: false, video: true}
};
const LazyImageSiblingComponent = class LazyImageSibling extends BdApi.React.Component {
render() {
if (!this.props.loadedImage) {
const instace = this;
const imageThrowaway = document.createElement("img");
imageThrowaway.addEventListener("load", function() {
let aRects = BDFDB.DOMUtils.getRects(document.querySelector(BDFDB.dotCN.appmount));
let resizeX = (aRects.width/this.width) * 0.8, resizeY = (aRects.height/this.height) * 0.65
let ratio = resizeX < resizeY ? resizeX : resizeY;
instace.props.loadedImage = BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.LazyImage, {
src: imageThrowaway.src,
width: this.width,
height: this.height,
maxWidth: this.width * ratio,
maxHeight: this.height * ratio
});
BDFDB.ReactUtils.forceUpdate(instace);
});
imageThrowaway.src = this.props.url;
}
return BDFDB.ReactUtils.createElement("div", {
className: BDFDB.DOMUtils.formatClassName(BDFDB.disCN._imageutilitiessibling, this.props.className),
onClick: _ => _this.switchImages(this.props.modalInstance, this.props.offset),
children: [
this.props.loadedImage || BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Spinner, {
type: BDFDB.LibraryComponents.Spinner.Type.SPINNING_CIRCLE
}),
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SvgIcon, {
className: BDFDB.disCNS._imageutilitiesswitchicon + BDFDB.disCN.svgicon,
name: this.props.svgIcon
})
]
});
}
};
const ImageDetailsComponent = class ImageDetails extends BdApi.React.Component {
componentDidMount() {
this.props.attachment = BDFDB.ReactUtils.findValue(BDFDB.ObjectUtils.get(this, `${BDFDB.ReactUtils.instanceKey}.return`), "attachment", {up: true});
@ -168,7 +199,9 @@ module.exports = (_ => {
onLoad () {
_this = this;
firedEvents = [];
clickedImage = null;
firstViewedImage = null;
viewedImage = null;
cachedImages = null;
this.defaults = {
viewerSettings: {
@ -219,7 +252,7 @@ module.exports = (_ => {
LazyImage: "render"
},
after: {
ImageModal: ["render", "componentDidMount"],
ImageModal: ["render", "componentDidMount", "componentWillUnmount"],
LazyImage: "componentDidMount",
LazyImageZoomable: "render",
UserBanner: "default"
@ -338,10 +371,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 => {
clickedImage = (BDFDB.DOMUtils.getParent(BDFDB.dotCN.imagewrapper, e.target) || e.target).querySelector("img") || e.target;
BDFDB.TimeUtils.timeout(_ => {clickedImage = null;}, 1000);
});
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.PatchUtils.patch(this, BDFDB.LibraryModules.MediaComponentUtils, "renderImageComponent", {
after: e => {
@ -767,17 +797,14 @@ module.exports = (_ => {
id: BDFDB.ContextMenuUtils.createItemId(this.name, "copy-file"),
action: _ => this.copyFile(urlData.original)
}),
BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuItem, {
!document.querySelector(BDFDB.dotCN.imagemodal) && BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuItem, {
label: this.labels.context_view.replace("{{var0}}", type),
id: BDFDB.ContextMenuUtils.createItemId(this.name, "view-file"),
action: _ => {
let img = document.createElement(isVideo ? "video" : "img");
img.addEventListener(isVideo ? "loadedmetadata" : "load", function() {
const imageThrowaway = document.createElement(isVideo ? "video" : "img");
imageThrowaway.addEventListener(isVideo ? "loadedmetadata" : "load", function() {
BDFDB.LibraryModules.ModalUtils.openModal(modalData => {
if (target) {
clickedImage = (BDFDB.DOMUtils.getParent(BDFDB.dotCN.imagewrapper, target) || target).querySelector("img") || target;
BDFDB.TimeUtils.timeout(_ => {clickedImage = null;}, 1000);
}
_this.cacheClickedImage(target);
return BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.ModalComponents.ModalRoot, Object.assign({
className: BDFDB.disCN.imagemodal
}, modalData, {
@ -785,7 +812,7 @@ module.exports = (_ => {
"aria-label": BDFDB.LanguageUtils.LanguageStrings.IMAGE,
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.ImageModal, {
animated: !!isVideo,
src: urlData.src || urlData.file,
src: imageThrowaway.src,
original: urlData.original,
width: isVideo ? this.videoWidth : this.width,
height: isVideo ? this.videoHeight : this.height,
@ -804,7 +831,7 @@ module.exports = (_ => {
}), true);
});
});
img.src = urlData.src || urlData.file;
imageThrowaway.src = urlData.src || urlData.file;
}
}),
BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuItem, {
@ -854,14 +881,24 @@ module.exports = (_ => {
].filter(n => n)
});
}
processImageModal (e) {
if (clickedImage) e.instance._cachedImage = clickedImage;
let url = this.getImageSrc(e.instance._cachedImage && e.instance._cachedImage.src ? e.instance._cachedImage : e.instance.props.src);
url = this.getImageSrc(typeof e.instance.props.children == "function" && e.instance.props.children(Object.assign({}, e.instance.props, {size: e.instance.props})).props.src) || url;
let isVideo = this.isValid(url, "video");
let messages = this.getAllGalleryImages();
if (e.returnvalue) {
if (e.methodname == "componentDidMount") {
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);
}
else if (e.methodname == "componentWillUnmount") {
firstViewedImage = null;
viewedImage = null;
cachedImages = null;
this.cleanupListeners("Gallery");
}
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;
@ -966,60 +1003,94 @@ module.exports = (_ => {
]
].flat(10).filter(n => n)
});
}
let imageIndex = 0, amount = 1;
if (messages.length) {
let data = this.getSiblingsAndPosition(e.instance._cachedImage || url, messages);
imageIndex = data.index;
amount = data.amount;
if (data.previous) {
if (e.instance.previousRef) e.returnvalue.props.children.push(this.createImageWrapper(e.instance, e.instance.previousRef, "previous", BDFDB.LibraryComponents.SvgIcon.Names.LEFT_CARET));
else this.loadImage(e.instance, data.previous, "previous");
}
if (data.next) {
if (e.instance.nextRef) e.returnvalue.props.children.push(this.createImageWrapper(e.instance, e.instance.nextRef, "next", BDFDB.LibraryComponents.SvgIcon.Names.RIGHT_CARET));
else this.loadImage(e.instance, data.next, "next");
if (this.settings.viewerSettings.details) {
e.returnvalue.props.children.push(BDFDB.ReactUtils.createElement("div", {
className: BDFDB.disCN._imageutilitiesdetailswrapper,
children: [
e.instance.props.alt && {label: "Alt", text: e.instance.props.alt},
{label: "Source", text: url},
{label: "Size", text: `${e.instance.props.width}x${e.instance.props.height}px`},
{label: "Image", text: `${cachedImages && (cachedImages.index + 1) || 1} of ${cachedImages && cachedImages.amount || 1}`}
].filter(n => n).map(data => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TextElement, {
className: BDFDB.disCN._imageutilitiesdetails,
children: [
BDFDB.ReactUtils.createElement("div", {
className: BDFDB.disCN._imageutilitiesdetailslabel,
children: data.label + ":"
}),
data.text
]
}))
}));
}
}
if (this.settings.viewerSettings.details) e.returnvalue.props.children.push(BDFDB.ReactUtils.createElement("div", {
className: BDFDB.disCN._imageutilitiesdetailswrapper,
children: [
e.instance.props.alt && {label: "Alt", text: e.instance.props.alt},
{label: "Source", text: url},
{label: "Size", text: `${e.instance.props.width}x${e.instance.props.height}px`},
{label: "Image", text: `${imageIndex + 1} of ${amount}`}
].filter(n => n).map(data => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TextElement, {
className: BDFDB.disCN._imageutilitiesdetails,
children: [
BDFDB.ReactUtils.createElement("div", {
className: BDFDB.disCN._imageutilitiesdetailslabel,
children: data.label + ":"
}),
data.text
]
}))
}));
}
if (e.node) {
let modal = BDFDB.DOMUtils.getParent(BDFDB.dotCN.modal, e.node);
if (modal) {
modal.className = BDFDB.DOMUtils.formatClassName(modal.className, messages.length && BDFDB.disCN._imageutilitiesgallery, this.settings.viewerSettings.details && BDFDB.disCN._imageutilitiesdetailsadded);
this.cleanupListeners("Gallery");
if (messages.length) {
document.keydownImageUtilitiesGalleryListener = event => {
if (!document.contains(e.node)) this.cleanupListeners("Gallery");
else if (!firedEvents.includes("Gallery")) {
firedEvents.push("Gallery");
if (event.keyCode == 37) this.switchImages(e.instance, "previous");
else if (event.keyCode == 39) this.switchImages(e.instance, "next");
if (this.settings.viewerSettings.galleryMode && viewedImage) {
if (!cachedImages) {
BDFDB.TimeUtils.clear(viewedImageTimeout);
let channel = BDFDB.LibraryModules.ChannelStore.getChannel(viewedImage.channelId);
BDFDB.LibraryModules.APIUtils.get({
url: channel && channel.guild_id ? BDFDB.DiscordConstants.Endpoints.SEARCH_GUILD(channel && channel.guild_id) : BDFDB.DiscordConstants.Endpoints.SEARCH_CHANNEL(BDFDB.DiscordConstants.ME),
query: BDFDB.LibraryModules.APIEncodeUtils.stringify({
channel_id: channel && channel.guild_id ? channel && channel.id : null,
has: "image",
around: viewedImage.messageId
})
}).then(result => {
if (result) {
const messages = result.body.messages.flat(10).reverse();
cachedImages = {all: this.filterMessagesForImages(messages, viewedImage)};
const index = this.getImageIndex(cachedImages.all, viewedImage);
cachedImages = Object.assign(cachedImages, {
firstReached: index == 0,
oldestId: messages[0] ? messages[0].id : null,
index: index,
amount: cachedImages.all.length,
newestId: messages[messages.length-1] ? messages[messages.length-1].id : null,
lastReached: index == (cachedImages.all.length - 1)
});
}
};
document.keyupImageUtilitiesGalleryListener = _ => {
BDFDB.ArrayUtils.remove(firedEvents, "Gallery", true);
if (!document.contains(e.node)) this.cleanupListeners("Gallery");
};
document.addEventListener("keydown", document.keydownImageUtilitiesGalleryListener);
document.addEventListener("keyup", document.keyupImageUtilitiesGalleryListener);
else cachedImages = {
firstReached: null,
oldestId: null,
all: [],
index: -1,
amount: 0,
newestId: null,
lastReached: null
};
BDFDB.ReactUtils.forceUpdate(e.instance);
});
return BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Spinner, {
type: BDFDB.LibraryComponents.Spinner.Type.SPINNING_CIRCLE
});
}
else {
if (cachedImages.all[cachedImages.index - 1]) e.returnvalue.props.children.push(BDFDB.ReactUtils.createElement(LazyImageSiblingComponent, {
className: BDFDB.disCN._imageutilitiesprevious,
modalInstance: e.instance,
url: this.getImageSrc(cachedImages.all[cachedImages.index - 1].thumbnail || cachedImages.all[cachedImages.index - 1]),
offset: -1,
svgIcon: BDFDB.LibraryComponents.SvgIcon.Names.LEFT_CARET
}));
if (cachedImages.all[cachedImages.index + 1]) e.returnvalue.props.children.push(BDFDB.ReactUtils.createElement(LazyImageSiblingComponent, {
className: BDFDB.disCN._imageutilitiesnext,
modalInstance: e.instance,
url: this.getImageSrc(cachedImages.all[cachedImages.index + 1].thumbnail || cachedImages.all[cachedImages.index + 1]),
offset: 1,
svgIcon: BDFDB.LibraryComponents.SvgIcon.Names.RIGHT_CARET
}));
if (cachedImages.all[cachedImages.index - 1] || cachedImages.all[cachedImages.index + 1]) {
this.addListener("keydown", "Gallery", event => {
if (!firedEvents.includes("Gallery")) {
firedEvents.push("Gallery");
if (event.keyCode == 37) this.switchImages(e.instance, -1);
else if (event.keyCode == 39) this.switchImages(e.instance, 1);
}
});
this.addListener("keyup", "Gallery", _ => BDFDB.ArrayUtils.remove(firedEvents, "Gallery", true));
}
}
}
}
@ -1089,7 +1160,7 @@ module.exports = (_ => {
document.addEventListener("mouseup", releasing);
this.cleanupListeners("Zoom");
document.wheelImageUtilitiesZoomListener = event2 => {
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) {
@ -1101,8 +1172,8 @@ module.exports = (_ => {
lens.update();
}
}
};
document.keydownImageUtilitiesZoomListener = event2 => {
});
this.addListener("keydown", "Zoom", event2 => {
if (!document.contains(e.node)) this.cleanupListeners("Zoom");
else if (!firedEvents.includes("Zoom")) {
firedEvents.push("Zoom");
@ -1115,14 +1186,11 @@ module.exports = (_ => {
lens.update();
}
}
};
document.keyupImageUtilitiesZoomListener = _ => {
});
this.addListener("keyup", "Zoom", _ => {
BDFDB.ArrayUtils.remove(firedEvents, "Zoom", true);
if (!document.contains(e.node)) this.cleanupListeners("Zoom");
};
document.addEventListener("wheel", document.wheelImageUtilitiesZoomListener);
document.addEventListener("keydown", document.keydownImageUtilitiesZoomListener);
document.addEventListener("keyup", document.keyupImageUtilitiesZoomListener);
});
vanishObserver = new MutationObserver(changes => {if (!document.contains(e.node)) releasing();});
vanishObserver.observe(appMount, {childList: true, subtree: true});
@ -1130,10 +1198,9 @@ module.exports = (_ => {
}
}
else {
if (!e.instance.props.resized && this.settings.resizeSettings.imageViewer && BDFDB.ReactUtils.findOwner(BDFDB.ObjectUtils.get(e, `instance.${BDFDB.ReactUtils.instanceKey}`), {name: "ImageModal", up: true})) {
let data = this.settings.viewerSettings.galleryMode ? this.getSiblingsAndPosition(e.instance.props.src, this.getAllGalleryImages()) : {};
if (this.settings.resizeSettings.imageViewer && BDFDB.ReactUtils.findOwner(BDFDB.ObjectUtils.get(e, `instance.${BDFDB.ReactUtils.instanceKey}`), {name: "ImageModal", up: true})) {
let aRects = BDFDB.DOMUtils.getRects(document.querySelector(BDFDB.dotCN.appmount));
let ratio = Math.min((aRects.width * (data.previous || data.next ? 0.8 : 1) - 20) / e.instance.props.width, (aRects.height - (this.settings.viewerSettings.details ? 280 : 100)) / e.instance.props.height);
let ratio = Math.min((aRects.width * (this.settings.viewerSettings.galleryMode ? 0.8 : 1) - 20) / e.instance.props.width, (aRects.height - (this.settings.viewerSettings.details ? 280 : 100)) / e.instance.props.height);
let width = Math.round(ratio * e.instance.props.width);
let height = Math.round(ratio * e.instance.props.height);
e.instance.props.width = width;
@ -1143,13 +1210,19 @@ module.exports = (_ => {
e.instance.props.src = e.instance.props.src.replace(/width=\d+/, `width=${width}`).replace(/height=\d+/, `height=${height}`);
e.instance.props.resized = true;
}
if (!e.instance.props.resized && this.settings.resizeSettings.messages && BDFDB.ReactUtils.findOwner(BDFDB.ObjectUtils.get(e, `instance.${BDFDB.ReactUtils.instanceKey}`), {name: "LazyImageZoomable", up: true})) {
if (this.settings.resizeSettings.messages && BDFDB.ReactUtils.findOwner(BDFDB.ObjectUtils.get(e, `instance.${BDFDB.ReactUtils.instanceKey}`), {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));
if (mRects.width || mwRects.width) {
let ratio = (mRects.width || (mwRects.width - 120)) / e.instance.props.width;
let width = Math.round(ratio * e.instance.props.width);
let height = Math.round(ratio * e.instance.props.height);
if (height > (aRects.height * 0.66)) {
let newHeight = Math.round(aRects.height * 0.66);
width = (newHeight/height) * width;
height = newHeight;
}
e.instance.props.width = width;
e.instance.props.maxWidth = width;
e.instance.props.height = height;
@ -1204,6 +1277,19 @@ module.exports = (_ => {
};
}
cacheClickedImage (target) {
const image = (BDFDB.DOMUtils.getParent(BDFDB.dotCN.imagewrapper, target) || target).querySelector("img") || target;
if (!image) return;
const message = BDFDB.ReactUtils.findValue(image, "message", {up: true});
if (!message) return;
firstViewedImage = {messageId: message.id, channelId: message.channel_id, proxy_url: image.src};
viewedImage = firstViewedImage;
viewedImageTimeout = BDFDB.TimeUtils.timeout(_ => {
firstViewedImage = null;
viewedImage = null;
}, 1000);
}
downloadFile (url, path, fallbackUrl, alternativeName) {
url = url.startsWith("/assets") ? (window.location.origin + url) : url;
BDFDB.LibraryRequires.request(url, {agentOptions: {rejectUnauthorized: false}, encoding: null}, (error, response, body) => {
@ -1282,91 +1368,118 @@ module.exports = (_ => {
if (ext == "quicktime") ext = "mov";
return ext;
}
getAllGalleryImages () {
if (!this.settings.viewerSettings.galleryMode) return [];
return Array.from(document.querySelectorAll(BDFDB.dotCNS.messagelistitem + BDFDB.dotCNS.imagewrapper + "img"));
}
getSiblingsAndPosition (imgOrUrl, images) {
images = images.flat(10).filter(img => !BDFDB.DOMUtils.getParent(BDFDB.dotCN.spoilerhidden, img));
let next, previous, index = 0, amount = images.length;
for (let i = 0; i < amount; i++) if (this.isSameImage(imgOrUrl, images[i])) {
index = i;
previous = images[i-1];
next = images[i+1];
break;
}
return {next, previous, index, amount};
}
isSameImage (src, img) {
return img.src && (Node.prototype.isPrototypeOf(src) && img == src || !Node.prototype.isPrototypeOf(src) && this.getImageSrc(img) == this.getImageSrc(src));
}
getImageSrc (img) {
if (!img) return null;
return (typeof img == "string" ? img : (img.src || (img.querySelector("canvas") ? img.querySelector("canvas").src : ""))).split("?width=")[0];
return (typeof img == "string" ? img : (img.proxy_url || img.src || (img.querySelector("canvas") ? img.querySelector("canvas").src : ""))).split("?width=")[0];
}
createImageWrapper (instance, imgRef, type, svgIcon) {
return BDFDB.ReactUtils.createElement("div", {
className: BDFDB.disCNS._imageutilitiessibling + BDFDB.disCN[`_imageutilities${type}`],
onClick: _ => this.switchImages(instance, type),
children: [
imgRef,
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SvgIcon, {
className: BDFDB.disCNS._imageutilitiesswitchicon + BDFDB.disCN.svgicon,
name: svgIcon
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));
}
filterMessagesForImages (messages, img) {
return messages.filter(m => m && m.hit && (m.id == firstViewedImage.messageId || m.id == img.messageId || m.embeds.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.thumbnail, i.video))).flat(10);
}
switchImages (modalInstance, offset) {
const newIndex = parseInt(cachedImages.index) + parseInt(offset);
if (newIndex < 0 || newIndex > (cachedImages.amount - 1)) return;
cachedImages.index = newIndex;
const oldImage = viewedImage;
viewedImage = cachedImages.all[cachedImages.index];
if (offset > 0 && !cachedImages.lastReached && cachedImages.index == (cachedImages.amount - 1)) {
let channel = BDFDB.LibraryModules.ChannelStore.getChannel(viewedImage.channelId);
BDFDB.LibraryModules.APIUtils.get({
url: channel && channel.guild_id ? BDFDB.DiscordConstants.Endpoints.SEARCH_GUILD(channel && channel.guild_id) : BDFDB.DiscordConstants.Endpoints.SEARCH_CHANNEL(BDFDB.DiscordConstants.ME),
query: BDFDB.LibraryModules.APIEncodeUtils.stringify({
channel_id: channel && channel.guild_id ? channel && channel.id : null,
has: "image",
min_id: (BigInt(cachedImages.newestId) - BigInt(1)).toString()
})
]
});
}
loadImage (instance, img, type) {
let imageThrowaway = document.createElement("img");
let src = this.getImageSrc(img);
imageThrowaway.src = src;
imageThrowaway.onload = _ => {
let arects = BDFDB.DOMUtils.getRects(document.querySelector(BDFDB.dotCN.appmount));
let resizeY = (arects.height/imageThrowaway.naturalHeight) * 0.65, resizeX = (arects.width/imageThrowaway.naturalWidth) * 0.8;
let resize = resizeX < resizeY ? resizeX : resizeY;
let newHeight = imageThrowaway.naturalHeight * resize;
let newWidth = imageThrowaway.naturalWidth * resize;
instance[type + "Img"] = img;
instance[type + "Ref"] = BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.LazyImage, {
src: src,
height: imageThrowaway.naturalHeight,
width: imageThrowaway.naturalWidth,
maxHeight: newHeight,
maxWidth: newWidth,
}).then(result => {
if (result) {
const messages = result.body.messages.flat(10).reverse();
const newCachedImages = this.filterMessagesForImages(messages, viewedImage);
const lastOldIndex = this.getImageIndex(newCachedImages, cachedImages.all[cachedImages.all.length-1]);
if (lastOldIndex > -1) {
cachedImages = Object.assign(cachedImages, {all: [].concat(cachedImages.all, newCachedImages.slice(lastOldIndex + 1))});
const index = this.getImageIndex(cachedImages.all, viewedImage);
cachedImages = Object.assign(cachedImages, {
index: index,
amount: cachedImages.all.length,
newestId: messages[messages.length-1] ? messages[messages.length-1].id : null,
lastReached: index == (cachedImages.all.length - 1)
});
}
BDFDB.ReactUtils.forceUpdate(modalInstance);
}
});
BDFDB.ReactUtils.forceUpdate(instance);
};
}
if (offset < 0 && !cachedImages.firstReached && cachedImages.index == 0) {
console.log("first");
let channel = BDFDB.LibraryModules.ChannelStore.getChannel(viewedImage.channelId);
BDFDB.LibraryModules.APIUtils.get({
url: channel && channel.guild_id ? BDFDB.DiscordConstants.Endpoints.SEARCH_GUILD(channel && channel.guild_id) : BDFDB.DiscordConstants.Endpoints.SEARCH_CHANNEL(BDFDB.DiscordConstants.ME),
query: BDFDB.LibraryModules.APIEncodeUtils.stringify({
channel_id: channel && channel.guild_id ? channel && channel.id : null,
has: "image",
max_id: (BigInt(cachedImages.oldestId) + BigInt(1)).toString()
})
}).then(result => {
if (result) {
const messages = result.body.messages.flat(10).reverse();
const newCachedImages = this.filterMessagesForImages(messages, viewedImage);
const firstOldIndex = this.getImageIndex(newCachedImages, cachedImages.all[0]);
if (firstOldIndex > -1) {
cachedImages = Object.assign(cachedImages, {all: [].concat(newCachedImages.slice(0, firstOldIndex), cachedImages.all)});
const index = this.getImageIndex(cachedImages.all, viewedImage);
cachedImages = Object.assign(cachedImages, {
firstReached: index == 0,
oldestId: messages[0] ? messages[0].id : null,
index: index,
amount: cachedImages.all.length
});
}
BDFDB.ReactUtils.forceUpdate(modalInstance);
}
});
}
let isVideo = this.isValid(viewedImage.proxy_url, "video");
modalInstance.props.animated = !!isVideo;
modalInstance.props.original = viewedImage.proxy_url;
modalInstance.props.placeholder = viewedImage.thumbnail && viewedImage.thumbnail.proxy_url || viewedImage.proxy_url;
modalInstance.props.src = viewedImage.proxy_url;
modalInstance.props.width = viewedImage.width;
modalInstance.props.height = viewedImage.height;
modalInstance.props.children = !isVideo ? null : (videoData => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Video, {
src: viewedImage.proxy_url,
width: videoData.size.width,
height: videoData.size.height,
naturalWidth: viewedImage.width,
naturalHeight: viewedImage.height,
play: true
}));
BDFDB.ReactUtils.forceUpdate(modalInstance);
}
switchImages (instance, type) {
let img = instance[type + "Img"];
let imgRef = instance[type + "Ref"];
if (!img || !imgRef) return;
delete instance.previousRef;
delete instance.nextRef;
delete instance.previousImg;
delete instance.nextImg;
instance.props.original = imgRef.props.src;
instance.props.placeholder = imgRef.props.src;
instance.props.src = imgRef.props.src;
instance.props.height = imgRef.props.height;
instance.props.width = imgRef.props.width;
instance._cachedImage = img;
BDFDB.ReactUtils.forceUpdate(instance);
addListener (eventType, type, callback) {
if (!type || !eventType || typeof callback != "function") return;
if (!eventTypes[type]) eventTypes[type] = [];
if (!eventTypes[type].includes(eventType)) eventTypes[type].push(eventType);
document.removeEventListener(eventType, document[`${eventType}${this.name}${type}Listener`]);
delete document[`${eventType}${this.name}${type}Listener`];
document[`${eventType}${this.name}${type}Listener`] = callback;
document.addEventListener(eventType, document[`${eventType}${this.name}${type}Listener`]);
}
cleanupListeners (type) {
if (!type) return;
for (let eventType of ["wheel", "keydown", "keyup"]) {
document.removeEventListener("wheel", document[`${eventType}ImageUtilities${type}Listener`]);
delete document[`${eventType}ImageUtilities${type}Listener`];
if (!type || !eventTypes[type]) return;
for (let eventType of eventTypes[type]) {
document.removeEventListener(eventType, document[`${eventType}${this.name}${type}Listener`]);
delete document[`${eventType}${this.name}${type}Listener`];
}
}
@ -1746,7 +1859,6 @@ module.exports = (_ => {
submenu_disabled: "All disabled",
toast_copy_failed: "{{var0}} could not be copied to the Clipboard",
toast_copy_success: "{{var0}} was copied to the Clipboard",
toast_message_deleted: "Message was successfully deleted",
toast_save_failed: "{{var0}} could not be saved in '{{var1}}'",
toast_save_success: "{{var0}} was saved in '{{var1}}'"
};