2020-10-20 23:25:34 +02:00
/ * *
* @ name ImageUtilities
2021-03-05 13:26:41 +01:00
* @ author DevilBro
2020-10-20 23:25:34 +02:00
* @ authorId 278543574059057154
2021-07-13 12:47:15 +02:00
* @ version 4.4 . 4
2021-03-05 13:26:41 +01:00
* @ description Adds several Utilities for Images / Videos ( Gallery , Download , Reverse Search , Zoom , Copy , etc . )
2020-10-20 23:25:34 +02:00
* @ invite Jx3TjNS
2020-11-19 16:45:36 +01:00
* @ donate https : //www.paypal.me/MircoWittrien
* @ patreon https : //www.patreon.com/MircoWittrien
2021-03-09 15:10:55 +01:00
* @ website https : //mwittrien.github.io/
* @ source https : //github.com/mwittrien/BetterDiscordAddons/tree/master/Plugins/ImageUtilities/
2021-03-10 09:17:37 +01:00
* @ updateUrl https : //mwittrien.github.io/BetterDiscordAddons/Plugins/ImageUtilities/ImageUtilities.plugin.js
2020-10-20 23:25:34 +02:00
* /
2020-08-14 14:37:10 +02:00
2020-09-19 20:49:33 +02:00
module . exports = ( _ => {
2020-10-09 21:09:35 +02:00
const config = {
2020-09-19 20:49:33 +02:00
"info" : {
"name" : "ImageUtilities" ,
"author" : "DevilBro" ,
2021-07-13 12:47:15 +02:00
"version" : "4.4.4" ,
2021-03-04 12:15:46 +01:00
"description" : "Adds several Utilities for Images/Videos (Gallery, Download, Reverse Search, Zoom, Copy, etc.)"
2021-06-03 16:36:02 +02:00
} ,
"changeLog" : {
2021-07-07 14:39:01 +02:00
"fixed" : {
2021-07-13 12:47:15 +02:00
"Bigger Stream Preview" : "Works now with the Plugin"
2021-06-03 16:36:02 +02:00
}
2020-08-14 15:18:33 +02:00
}
2020-09-19 20:49:33 +02:00
} ;
2020-10-15 20:10:00 +02:00
2021-06-15 13:42:02 +02:00
return ( window . Lightcord || window . LightCord ) ? class {
getName ( ) { return config . info . name ; }
getAuthor ( ) { return config . info . author ; }
getVersion ( ) { return config . info . version ; }
getDescription ( ) { return "Do not use LightCord!" ; }
load ( ) { BdApi . alert ( "Attention!" , "By using LightCord you are risking your Discord Account, due to using a 3rd Party Client. Switch to an official Discord Client (https://discord.com/) with the proper BD Injection (https://betterdiscord.app/)" ) ; }
start ( ) { }
stop ( ) { }
} : ! window . BDFDB _Global || ( ! window . BDFDB _Global . loaded && ! window . BDFDB _Global . started ) ? class {
2021-01-06 12:38:36 +01:00
getName ( ) { return config . info . name ; }
getAuthor ( ) { return config . info . author ; }
getVersion ( ) { return config . info . version ; }
2021-02-01 17:13:13 +01:00
getDescription ( ) { return ` The Library Plugin needed for ${ config . info . name } is missing. Open the Plugin Settings to download it. \n \n ${ config . info . description } ` ; }
downloadLibrary ( ) {
require ( "request" ) . get ( "https://mwittrien.github.io/BetterDiscordAddons/Library/0BDFDB.plugin.js" , ( e , r , b ) => {
2021-03-05 13:14:18 +01:00
if ( ! e && b && r . statusCode == 200 ) require ( "fs" ) . writeFile ( require ( "path" ) . join ( BdApi . Plugins . folder , "0BDFDB.plugin.js" ) , b , _ => BdApi . showToast ( "Finished downloading BDFDB Library" , { type : "success" } ) ) ;
2021-03-06 14:59:48 +01:00
else BdApi . alert ( "Error" , "Could not download BDFDB Library Plugin. Try again later or download it manually from GitHub: https://mwittrien.github.io/downloader/?library" ) ;
2021-02-01 17:13:13 +01:00
} ) ;
}
2020-09-19 20:49:33 +02:00
2021-01-06 12:38:36 +01:00
load ( ) {
2020-11-19 16:51:14 +01:00
if ( ! window . BDFDB _Global || ! Array . isArray ( window . BDFDB _Global . pluginQueue ) ) window . BDFDB _Global = Object . assign ( { } , window . BDFDB _Global , { pluginQueue : [ ] } ) ;
2020-09-19 20:49:33 +02:00
if ( ! window . BDFDB _Global . downloadModal ) {
window . BDFDB _Global . downloadModal = true ;
2021-01-14 16:14:44 +01:00
BdApi . showConfirmationModal ( "Library Missing" , ` The Library Plugin needed for ${ config . info . name } is missing. Please click "Download Now" to install it. ` , {
2020-09-19 20:49:33 +02:00
confirmText : "Download Now" ,
cancelText : "Cancel" ,
onCancel : _ => { delete window . BDFDB _Global . downloadModal ; } ,
2020-09-20 08:15:13 +02:00
onConfirm : _ => {
delete window . BDFDB _Global . downloadModal ;
2021-02-01 17:13:13 +01:00
this . downloadLibrary ( ) ;
2020-09-20 08:15:13 +02:00
}
2020-09-19 20:49:33 +02:00
} ) ;
}
if ( ! window . BDFDB _Global . pluginQueue . includes ( config . info . name ) ) window . BDFDB _Global . pluginQueue . push ( config . info . name ) ;
2020-10-09 21:09:35 +02:00
}
2021-01-06 12:38:36 +01:00
start ( ) { this . load ( ) ; }
stop ( ) { }
getSettingsPanel ( ) {
2020-11-28 23:12:09 +01:00
let template = document . createElement ( "template" ) ;
2021-01-14 16:14:44 +01:00
template . innerHTML = ` <div style="color: var(--header-primary); font-size: 16px; font-weight: 300; white-space: pre; line-height: 22px;">The Library Plugin needed for ${ config . info . name } is missing. \n Please click <a style="font-weight: 500;">Download Now</a> to install it.</div> ` ;
2021-02-01 17:13:13 +01:00
template . content . firstElementChild . querySelector ( "a" ) . addEventListener ( "click" , this . downloadLibrary ) ;
2020-11-28 23:12:09 +01:00
return template . content . firstElementChild ;
}
2020-10-09 21:09:35 +02:00
} : ( ( [ Plugin , BDFDB ] ) => {
2021-01-23 23:19:06 +01:00
var firedEvents = [ ] , clickedImage ;
2021-04-24 22:28:41 +02:00
var ownLocations = { } , downloadsFolder ;
2020-09-19 20:49:33 +02:00
2021-02-09 14:51:23 +01:00
const imgUrlReplaceString = "DEVILBRO_BD_REVERSEIMAGESEARCH_REPLACE_IMAGEURL" ;
2021-07-07 14:39:01 +02:00
2021-02-09 14:51:23 +01:00
const fileTypes = {
2021-03-02 08:53:42 +01:00
"3gp" : { copyable : false , searchable : false , video : true } ,
"3g2" : { copyable : false , searchable : false , video : true } ,
"amv" : { copyable : false , searchable : false , video : true } ,
"apng" : { copyable : false , searchable : true , video : false } ,
"avi" : { copyable : false , searchable : false , video : true } ,
"flv" : { copyable : false , searchable : false , video : true } ,
"jpeg" : { copyable : true , searchable : true , video : false } ,
"jpg" : { copyable : true , searchable : true , video : false } ,
"gif" : { copyable : false , searchable : true , video : false } ,
"m4v" : { copyable : false , searchable : false , video : true } ,
"mkv" : { copyable : false , searchable : false , video : true } ,
"mov" : { copyable : false , searchable : false , video : true } ,
"mp4" : { copyable : false , searchable : false , video : true } ,
"mpeg-1" : { copyable : false , searchable : false , video : true } ,
"mpeg-2" : { copyable : false , searchable : false , video : true } ,
"ogg" : { copyable : false , searchable : false , video : true } ,
"ogv" : { copyable : false , searchable : false , video : true } ,
"png" : { copyable : true , searchable : true , video : false } ,
"svg" : { copyable : false , searchable : false , video : false } ,
"webm" : { copyable : false , searchable : false , video : true } ,
2021-06-03 16:36:02 +02:00
"webp" : { copyable : false , searchable : true , video : false } ,
2021-03-02 08:53:42 +01:00
"wmv" : { copyable : false , searchable : false , video : true }
2021-02-09 14:51:23 +01:00
} ;
2020-09-19 20:49:33 +02:00
const ImageDetails = class ImageDetails extends BdApi . React . Component {
2021-01-20 16:00:29 +01:00
componentDidMount ( ) {
2020-11-26 09:53:49 +01:00
this . props . attachment = BDFDB . ReactUtils . findValue ( BDFDB . ObjectUtils . get ( this , ` ${ BDFDB . ReactUtils . instanceKey } .return ` ) , "attachment" , { up : true } ) ;
2020-08-14 15:18:33 +02:00
BDFDB . ReactUtils . forceUpdate ( this ) ;
}
2021-01-20 16:00:29 +01:00
componentDidUpdate ( ) {
2020-09-19 20:49:33 +02:00
if ( ( ! this . props . attachment || ! this . props . attachment . size ) && ! this . props . loaded ) {
this . props . loaded = true ;
2020-11-26 09:53:49 +01:00
this . props . attachment = BDFDB . ReactUtils . findValue ( BDFDB . ObjectUtils . get ( this , ` ${ BDFDB . ReactUtils . instanceKey } .return ` ) , "attachment" , { up : true } ) ;
2020-09-19 20:49:33 +02:00
BDFDB . ReactUtils . forceUpdate ( this ) ;
2020-08-14 14:37:10 +02:00
}
2020-09-19 20:49:33 +02:00
}
2021-01-20 16:00:29 +01:00
render ( ) {
2020-09-19 20:49:33 +02:00
return ! this . props . attachment ? null : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex , {
className : BDFDB . disCN . _imageutilitiesimagedetails ,
children : [
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex . Child , {
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Anchor , {
title : this . props . original ,
href : this . props . original ,
children : this . props . attachment . filename ,
onClick : event => {
BDFDB . ListenerUtils . stopEvent ( event ) ;
BDFDB . DiscordUtils . openLink ( this . props . original ) ;
}
} )
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex . Child , {
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TextElement , {
children : BDFDB . NumberUtils . formatBytes ( this . props . attachment . size )
} )
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex . Child , {
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TextElement , {
children : ` ${ this . props . attachment . width } x ${ this . props . attachment . height } px `
} )
} )
]
} ) ;
}
} ;
2020-10-09 21:09:35 +02:00
return class ImageUtilities extends Plugin {
2021-01-06 12:38:36 +01:00
onLoad ( ) {
2020-09-19 20:49:33 +02:00
firedEvents = [ ] ;
clickedImage = null ;
2021-07-07 14:39:01 +02:00
2020-09-19 20:49:33 +02:00
this . defaults = {
2021-04-24 22:28:41 +02:00
general : {
resizeImage : { value : true , description : "Always resize Image to fit the whole Image Modal" } ,
addDetails : { value : true , description : "Add Image Details (Name, Size, Amount) in the Image Modal" } ,
showAsHeader : { value : true , description : "Show Image Details as a Details Header above the Image in the Chat" } ,
showOnHover : { value : false , description : "Show Image Details as Tooltip in the Chat" } ,
enableGallery : { value : true , description : "Display previous/next Images in the same message in the Image Modal" } ,
enableZoom : { value : true , description : "Create a Zoom Lens if you press down on an Image in the Image Modal" } ,
pixelZoom : { value : false , description : "Zoom Lens will be pixelated instead of blurry" } ,
enableCopyImg : { value : true , description : "Add a copy Image Option in the Image Modal" } ,
enableSaveImg : { value : true , description : "Add a save Image as Option in the Image Modal" } ,
} ,
places : {
userAvatars : { value : true , description : "User Avatars" } ,
groupIcons : { value : true , description : "Group Icons" } ,
guildIcons : { value : true , description : "Server Icons" } ,
emojis : { value : true , description : "Custom Emojis/Emotes" }
2020-09-19 20:49:33 +02:00
} ,
amounts : {
2021-04-24 22:28:41 +02:00
hoverDelay : { value : 0 , min : 0 , description : "Image Tooltip Delay (in ms)" }
2020-09-19 20:49:33 +02:00
} ,
zoomSettings : {
2021-04-24 22:28:41 +02:00
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" }
2020-09-19 20:49:33 +02:00
} ,
engines : {
2020-11-19 16:51:14 +01:00
_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 } ,
2021-06-02 09:10:57 +02:00
Bing : { value : true , name : "Bing" , url : "https://www.bing.com/images/search?q=imgurl: " + imgUrlReplaceString + "&view=detailv2&iss=sbi&FORM=IRSBIQ" } ,
2020-12-15 15:03:09 +01:00
Google : { value : true , name : "Google" , url : "https://images.google.com/searchbyimage?image_url=" + imgUrlReplaceString } ,
2021-04-24 22:50:24 +02:00
ImgOps : { value : true , name : "ImgOps" , raw : true , url : "https://imgops.com/specialized+reverse/" + imgUrlReplaceString } ,
2020-11-19 16:51:14 +01:00
IQDB : { value : true , name : "IQDB" , url : "https://iqdb.org/?url=" + imgUrlReplaceString } ,
2020-12-15 15:03:09 +01:00
Reddit : { value : true , name : "Reddit" , url : "http://karmadecay.com/search?q=" + imgUrlReplaceString } ,
2020-11-19 16:51:14 +01:00
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" } ,
2020-12-15 15:03:09 +01:00
TinEye : { value : true , name : "TinEye" , url : "https://tineye.com/search?url=" + imgUrlReplaceString } ,
2020-11-19 16:51:14 +01:00
WhatAnime : { value : true , name : "WhatAnime" , url : "https://trace.moe/?url=" + imgUrlReplaceString } ,
2020-12-15 15:03:09 +01:00
Yandex : { value : true , name : "Yandex" , url : "https://yandex.com/images/search?url=" + imgUrlReplaceString + "&rpt=imageview" }
2020-09-19 20:49:33 +02:00
}
} ;
2020-08-14 14:37:10 +02:00
2020-09-19 20:49:33 +02:00
this . patchedModules = {
2020-10-16 19:47:23 +02:00
before : {
LazyImage : "render"
} ,
2020-09-19 20:49:33 +02:00
after : {
ImageModal : [ "render" , "componentDidMount" ] ,
2021-06-05 21:06:05 +02:00
LazyImage : [ "render" , "componentDidMount" ] ,
UserBanner : "default"
2020-09-19 20:49:33 +02:00
}
} ;
this . css = `
$ { BDFDB . dotCN . _imageutilitiesimagedetails } {
margin : 5 px 0 ;
}
$ { BDFDB . dotCNS . spoilerhidden + BDFDB . dotCN . _imageutilitiesimagedetails } {
visibility : hidden ;
max - width : 1 px ;
}
2020-12-15 15:03:09 +01:00
$ { BDFDB . dotCN . _imageutilitiesgallery } ,
$ { BDFDB . dotCN . _imageutilitiesdetailsadded } {
2020-09-19 20:49:33 +02:00
transform : unset ! important ;
}
$ { BDFDB . dotCN . _imageutilitiessibling } {
display : flex ;
align - items : center ;
position : fixed ;
top : 50 % ;
bottom : 50 % ;
cursor : pointer ;
}
$ { BDFDB . dotCN . _imageutilitiesprevious } {
justify - content : flex - end ;
right : 90 % ;
}
$ { BDFDB . dotCN . _imageutilitiesnext } {
justify - content : flex - start ;
left : 90 % ;
}
$ { BDFDB . dotCN . _imageutilitiesswitchicon } {
position : absolute ;
background : rgba ( 0 , 0 , 0 , 0.3 ) ;
border - radius : 50 % ;
padding : 15 px ;
transition : all 0.3 s ease ;
}
$ { BDFDB . dotCNS . _imageutilitiesprevious + BDFDB . dotCN . _imageutilitiesswitchicon } {
right : 10 px ;
}
$ { BDFDB . dotCNS . _imageutilitiesnext + BDFDB . dotCN . _imageutilitiesswitchicon } {
left : 10 px ;
}
$ { BDFDB . dotCN . _imageutilitiessibling } : hover $ { BDFDB . dotCN . _imageutilitiesswitchicon } {
background : rgba ( 0 , 0 , 0 , 0.5 ) ;
}
$ { BDFDB . dotCN . _imageutilitiesdetailswrapper } {
position : fixed ;
bottom : 10 px ;
left : 15 px ;
right : 15 px ;
pointer - events : none ;
}
$ { BDFDB . dotCN . _imageutilitiesdetails } {
2020-11-17 21:56:17 +01:00
color : # dcddde ;
2020-09-19 20:49:33 +02:00
margin - top : 5 px ;
font - size : 14 px ;
font - weight : 500 ;
2020-10-16 19:47:23 +02:00
white - space : nowrap ;
overflow : hidden ;
text - overflow : ellipsis ;
2020-09-19 20:49:33 +02:00
}
$ { BDFDB . dotCN . _imageutilitiesdetailslabel } {
font - weight : 600 ;
}
$ { BDFDB . dotCN . _imageutilitieslense } {
2021-05-13 20:58:14 +02:00
border : 2 px solid var ( -- bdfdb - blurple ) ;
2020-09-19 20:49:33 +02:00
}
$ { BDFDB . dotCN . _imageutilitiesoperations } {
position : absolute ;
display : flex ;
}
$ { BDFDB . dotCNS . _imageutilitiesoperations + BDFDB . dotCN . downloadlink } {
position : relative ! important ;
white - space : nowrap ! important ;
}
$ { BDFDB . dotCNS . _imageutilitiesoperations + BDFDB . dotCN . anchor + BDFDB . dotCN . downloadlink } {
margin : 0 ! important ;
}
` ;
2020-08-14 14:37:10 +02:00
}
2020-09-19 20:49:33 +02:00
2021-01-06 12:38:36 +01:00
onStart ( ) {
2020-08-14 14:37:10 +02:00
BDFDB . ListenerUtils . add ( this , document . body , "click" , BDFDB . dotCNS . message + BDFDB . dotCNS . imagewrapper + "img" , e => {
clickedImage = e . target ;
BDFDB . TimeUtils . timeout ( _ => { clickedImage = null ; } ) ;
} ) ;
2020-08-14 15:26:54 +02:00
2021-07-11 18:01:39 +02:00
BDFDB . PatchUtils . patch ( this , BDFDB . LibraryModules . MediaComponentUtils , "renderImageComponent" , { after : e => {
2021-04-28 18:00:01 +02:00
if ( this . settings . general . showAsHeader && e . returnValue && e . returnValue . type && ( e . returnValue . type . displayName == "LazyImageZoomable" || e . returnValue . type . displayName == "LazyImage" ) && e . methodArguments [ 0 ] . original && e . methodArguments [ 0 ] . src . indexOf ( "https://media.discordapp.net/attachments" ) == 0 && ( e . methodArguments [ 0 ] . className || "" ) . indexOf ( BDFDB . disCN . embedmedia ) == - 1 && ( e . methodArguments [ 0 ] . className || "" ) . indexOf ( BDFDB . disCN . embedthumbnail ) == - 1 ) {
return BDFDB . ReactUtils . createElement ( "div" , {
className : BDFDB . disCN . embedwrapper ,
children : [
BDFDB . ReactUtils . createElement ( ImageDetails , {
original : e . methodArguments [ 0 ] . original ,
attachment : {
height : 0 ,
width : 0 ,
filename : "unknown.png"
}
} ) ,
e . returnValue
]
} ) ;
}
2020-08-14 15:26:54 +02:00
} } ) ;
2020-08-14 14:37:10 +02:00
this . forceUpdateAll ( ) ;
}
2020-09-19 20:49:33 +02:00
2021-01-06 12:38:36 +01:00
onStop ( ) {
2020-08-15 10:38:15 +02:00
this . cleanupListeners ( "Gallery" ) ;
this . cleanupListeners ( "Zoom" ) ;
2020-08-14 14:37:10 +02:00
this . forceUpdateAll ( ) ;
}
2020-09-19 20:49:33 +02:00
getSettingsPanel ( collapseStates = { } ) {
2020-12-15 15:03:09 +01:00
let settingsPanel ;
2020-09-19 20:49:33 +02:00
2020-12-15 15:03:09 +01:00
return settingsPanel = BDFDB . PluginUtils . createSettingsPanel ( this , {
2020-09-19 20:49:33 +02:00
collapseStates : collapseStates ,
2020-12-15 15:03:09 +01:00
children : _ => {
let settingsItems = [ ] ;
settingsItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . CollapseContainer , {
title : "Settings" ,
collapseStates : collapseStates ,
2021-04-24 22:28:41 +02:00
children : Object . keys ( this . defaults . general ) . map ( key => BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsSaveItem , {
2020-12-15 15:03:09 +01:00
type : "Switch" ,
plugin : this ,
2021-04-24 22:28:41 +02:00
keys : [ "general" , key ] ,
label : this . defaults . general [ key ] . description ,
value : this . settings . general [ key ]
} ) ) . concat ( Object . keys ( this . defaults . amounts ) . map ( key => BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsSaveItem , {
2020-12-15 15:03:09 +01:00
type : "TextInput" ,
plugin : this ,
keys : [ "amounts" , key ] ,
label : this . defaults . amounts [ key ] . description ,
basis : "50%" ,
childProps : { type : "number" } ,
min : this . defaults . amounts [ key ] . min ,
max : this . defaults . amounts [ key ] . max ,
2021-04-24 22:28:41 +02:00
value : this . settings . amounts [ key ]
} ) ) )
2020-12-15 15:03:09 +01:00
} ) ) ;
settingsItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . CollapseContainer , {
title : "Download Locations" ,
collapseStates : collapseStates ,
children : [
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . FormComponents . FormTitle , {
className : BDFDB . disCN . marginbottom4 ,
tag : BDFDB . LibraryComponents . FormComponents . FormTitle . Tags . H3 ,
children : "Add additional Download Locations: "
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex , {
className : BDFDB . disCN . marginbottom8 ,
align : BDFDB . LibraryComponents . Flex . Align . END ,
children : [
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex . Child , {
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . FormComponents . FormItem , {
title : "Name:" ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TextInput , {
className : "input-newlocation input-name" ,
value : "" ,
placeholder : "Name"
} )
} )
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex . Child , {
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . FormComponents . FormItem , {
title : "Location:" ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TextInput , {
className : "input-newlocation input-location" ,
value : "" ,
placeholder : "Location"
} )
} )
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Button , {
style : { marginBottom : 1 } ,
onClick : _ => {
2021-02-09 14:51:23 +01:00
for ( let input of settingsPanel . props . _node . querySelectorAll ( ".input-newlocation " + BDFDB . dotCN . input ) ) if ( ! input . value || input . value . length == 0 || input . value . trim ( ) . length == 0 ) return BDFDB . NotificationUtils . toast ( "Fill out all fields to add a new Location." , { type : "danger" } ) ;
2020-12-15 15:03:09 +01:00
let name = settingsPanel . props . _node . querySelector ( ".input-name " + BDFDB . dotCN . input ) . value . trim ( ) ;
let location = settingsPanel . props . _node . querySelector ( ".input-location " + BDFDB . dotCN . input ) . value . trim ( ) ;
2021-02-09 14:51:23 +01:00
if ( ownLocations [ name ] || name == "Downloads" ) return BDFDB . NotificationUtils . toast ( "A Location with the choosen Name already exists, please choose another Name" , { type : "danger" } ) ;
else if ( ! BDFDB . LibraryRequires . fs . existsSync ( location ) ) return BDFDB . NotificationUtils . toast ( "The choosen download Location is not a valid Path to a Folder" , { type : "danger" } ) ;
2020-12-15 15:03:09 +01:00
else {
2020-12-17 20:33:36 +01:00
ownLocations [ name ] = { enabled : true , location : location } ;
2020-12-15 15:03:09 +01:00
BDFDB . DataUtils . save ( ownLocations , this , "ownLocations" ) ;
BDFDB . PluginUtils . refreshSettingsPanel ( this , settingsPanel , collapseStates ) ;
}
} ,
children : BDFDB . LanguageUtils . LanguageStrings . ADD
} )
]
} )
] . concat ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsPanelList , {
title : "Your own Download Locations:" ,
dividerTop : true ,
children : Object . keys ( ownLocations ) . map ( name => {
2021-01-20 14:30:38 +01:00
let locationName = name ;
2020-12-15 15:03:09 +01:00
let editable = name != "Downloads" ;
return BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Card , {
horizontal : true ,
children : [
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex . Child , {
grow : 0 ,
basis : "180px" ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TextInput , {
2021-01-20 14:30:38 +01:00
value : locationName ,
placeholder : locationName ,
2020-12-15 15:03:09 +01:00
size : BDFDB . LibraryComponents . TextInput . Sizes . MINI ,
maxLength : 100000000000000000000 ,
disabled : ! editable ,
onChange : ! editable ? null : value => {
2021-01-20 14:30:38 +01:00
ownLocations [ value ] = ownLocations [ locationName ] ;
delete ownLocations [ locationName ] ;
locationName = value ;
2020-12-15 15:03:09 +01:00
BDFDB . DataUtils . save ( ownLocations , this , "ownLocations" ) ;
}
} )
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex . Child , {
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TextInput , {
2021-01-20 14:30:38 +01:00
value : ownLocations [ locationName ] . location ,
placeholder : ownLocations [ locationName ] . location ,
2020-12-15 15:03:09 +01:00
size : BDFDB . LibraryComponents . TextInput . Sizes . MINI ,
maxLength : 100000000000000000000 ,
2021-07-11 17:16:54 +02:00
onChange : value => {
2021-01-20 14:30:38 +01:00
ownLocations [ locationName ] . location = value ;
2020-12-16 10:58:13 +01:00
BDFDB . DataUtils . save ( ownLocations , this , "ownLocations" ) ;
}
} )
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex . Child , {
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Switch , {
2021-01-20 14:30:38 +01:00
value : ownLocations [ locationName ] . enabled ,
2020-12-16 10:58:13 +01:00
size : BDFDB . LibraryComponents . Switch . Sizes . MINI ,
onChange : value => {
2021-01-20 14:30:38 +01:00
ownLocations [ locationName ] . enabled = value ;
2020-12-15 15:03:09 +01:00
BDFDB . DataUtils . save ( ownLocations , this , "ownLocations" ) ;
}
} )
} )
] ,
noRemove : ! editable ,
onRemove : ! editable ? null : _ => {
2021-01-20 14:30:38 +01:00
delete ownLocations [ locationName ] ;
2020-12-15 15:03:09 +01:00
BDFDB . DataUtils . save ( ownLocations , this , "ownLocations" ) ;
BDFDB . PluginUtils . refreshSettingsPanel ( this , settingsPanel ) ;
}
} ) ;
} )
} ) ) . filter ( n => n )
} ) ) ;
settingsItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . CollapseContainer , {
title : "Context Menu Entries" ,
collapseStates : collapseStates ,
children : [ BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . FormComponents . FormTitle , {
className : BDFDB . disCN . marginbottom4 ,
tag : BDFDB . LibraryComponents . FormComponents . FormTitle . Tags . H3 ,
children : "Add additional Context Menu Entry for: "
2021-04-24 22:28:41 +02:00
} ) ] . concat ( Object . keys ( this . defaults . places ) . map ( key => BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsSaveItem , {
2020-12-15 15:03:09 +01:00
type : "Switch" ,
plugin : this ,
2021-04-24 22:28:41 +02:00
keys : [ "places" , key ] ,
label : this . defaults . places [ key ] . description ,
value : this . settings . places [ key ]
2020-12-15 15:03:09 +01:00
} ) ) )
} ) ) ;
settingsItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . CollapseContainer , {
title : "Search Engines" ,
collapseStates : collapseStates ,
2021-04-24 22:28:41 +02:00
children : Object . keys ( this . defaults . engines ) . map ( key => key != "_all" && BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsSaveItem , {
2020-12-15 15:03:09 +01:00
type : "Switch" ,
plugin : this ,
keys : [ "engines" , key ] ,
label : this . defaults . engines [ key ] . name ,
2021-04-24 22:28:41 +02:00
value : this . settings . engines [ key ]
} ) ) . filter ( n => n )
2020-12-15 15:03:09 +01:00
} ) ) ;
return settingsItems ;
}
} ) ;
2020-09-19 20:49:33 +02:00
}
2021-01-06 12:38:36 +01:00
onSettingsClosed ( ) {
2020-09-19 20:49:33 +02:00
if ( this . SettingsUpdated ) {
delete this . SettingsUpdated ;
this . forceUpdateAll ( ) ;
}
}
2020-08-14 14:37:10 +02:00
2021-01-06 12:38:36 +01:00
forceUpdateAll ( ) {
2021-07-07 14:39:01 +02:00
const loadedLocations = BDFDB . DataUtils . load ( this , "ownLocations" ) ;
ownLocations = Object . assign ( ! loadedLocations || ! loadedLocations . Downloads ? { "Downloads" : { enabled : true , location : this . getDownloadLocation ( ) } } : { } , loadedLocations ) ;
2020-08-14 14:37:10 +02:00
2020-09-19 20:49:33 +02:00
BDFDB . PatchUtils . forceAllUpdates ( this ) ;
BDFDB . MessageUtils . rerenderAll ( ) ;
2020-08-14 14:37:10 +02:00
}
2020-09-19 20:49:33 +02:00
onGuildContextMenu ( e ) {
2021-04-24 22:28:41 +02:00
if ( e . instance . props . guild && this . settings . places . guildIcons ) {
2020-09-19 20:49:33 +02:00
let banner = 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 ( banner ) {
2021-06-05 21:06:05 +02:00
if ( e . instance . props . guild . banner ) this . injectItem ( e , ( BDFDB . LibraryModules . IconUtils . getGuildBannerURL ( e . instance . props . guild ) || "" ) . replace ( /\.webp|\.gif/ , ".png" ) ) ;
2020-09-19 20:49:33 +02:00
}
2021-06-05 21:06:05 +02:00
else if ( e . type != "GuildChannelListContextMenu" ) this . injectItem ( e , ( e . instance . props . guild . getIconURL ( ) || "" ) . replace ( /\.webp|\.gif/ , ".png" ) , e . instance . props . guild . icon && BDFDB . LibraryModules . IconUtils . isAnimatedIconHash ( e . instance . props . guild . icon ) && e . instance . props . guild . getIconURL ( true ) ) ;
2020-09-13 19:22:10 +02:00
}
}
2020-08-14 14:37:10 +02:00
2020-09-19 20:49:33 +02:00
onUserContextMenu ( e ) {
2021-06-05 21:06:05 +02:00
if ( e . instance . props . user && this . settings . places . userAvatars ) this . injectItem ( e , ( e . instance . props . user . getAvatarURL ( ) || "" ) . replace ( /\.webp|\.gif/ , ".png" ) , BDFDB . LibraryModules . IconUtils . isAnimatedIconHash ( e . instance . props . user . avatar ) && e . instance . props . user . getAvatarURL ( null , true ) ) ;
2020-08-14 14:37:10 +02:00
}
2021-02-25 16:41:14 +01:00
onGroupDMContextMenu ( e ) {
2021-06-05 21:06:05 +02:00
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" ) ) ;
2021-02-25 16:41:14 +01:00
}
2020-09-19 20:49:33 +02:00
onNativeContextMenu ( e ) {
if ( e . type == "NativeImageContextMenu" && ( e . instance . props . href || e . instance . props . src ) ) {
this . injectItem ( e , e . instance . props . href || e . instance . props . src ) ;
2020-08-14 14:37:10 +02:00
}
}
2020-09-19 20:49:33 +02:00
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 ) ;
2021-02-09 14:51:23 +01:00
else if ( e . instance . props . 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" ) ) this . injectItem ( e , e . instance . props . target . href ) ;
2020-09-19 20:49:33 +02:00
else if ( e . instance . props . target . tagName == "IMG" ) {
2021-04-27 12:25:44 +02:00
if ( BDFDB . DOMUtils . containsClass ( e . instance . props . target . parentElement , BDFDB . disCN . imagewrapper ) ) this . injectItem ( e , { file : e . instance . props . target . src , original : this . getTargetLink ( e . instance . props . target ) } ) ;
2021-04-24 22:28:41 +02:00
else if ( BDFDB . DOMUtils . containsClass ( e . instance . props . target , BDFDB . disCN . embedauthoricon ) && this . settings . places . userAvatars ) this . injectItem ( e , e . instance . props . target . src ) ;
else if ( BDFDB . DOMUtils . containsClass ( e . instance . props . target , BDFDB . disCN . emojiold , "emote" , false ) && this . settings . places . emojis ) this . injectItem ( e , e . instance . props . target . src ) ;
2020-08-31 21:41:39 +02:00
}
2021-02-09 14:51:23 +01:00
else if ( e . instance . props . target . tagName == "VIDEO" ) {
2021-04-27 12:25:44 +02:00
if ( BDFDB . DOMUtils . containsClass ( e . instance . props . target , BDFDB . disCN . embedvideo ) || BDFDB . DOMUtils . getParent ( BDFDB . dotCN . attachmentvideo , e . instance . props . target ) ) this . injectItem ( e , { file : e . instance . props . target . src , original : this . getTargetLink ( e . instance . props . target ) } ) ;
2021-02-09 14:51:23 +01:00
}
2020-09-19 20:49:33 +02:00
else {
let reaction = BDFDB . DOMUtils . getParent ( BDFDB . dotCN . messagereaction , e . instance . props . target ) ;
2021-04-24 22:28:41 +02:00
if ( reaction && this . settings . places . emojis ) this . injectItem ( e , reaction . querySelector ( BDFDB . dotCN . emojiold ) . src ) ;
2020-08-24 21:10:15 +02:00
}
2020-09-19 20:49:33 +02:00
}
}
2021-04-27 12:25:44 +02:00
getTargetLink ( target ) {
let ele = target ;
let src = "" , href = "" ;
while ( ele instanceof Node ) ele instanceof HTMLImageElement && null != ele . src && ( src = ele . src ) , ele instanceof HTMLAnchorElement && null != ele . href && ( href = ele . href ) , ele = ele . parentNode ;
return href || src ;
}
2020-09-19 20:49:33 +02:00
injectItem ( e , ... urls ) {
2021-06-05 21:06:05 +02:00
let validUrls = this . filterUrls ( ... urls ) ;
2020-09-19 20:49:33 +02:00
if ( ! validUrls . length ) return ;
2021-02-09 14:51:23 +01:00
2021-02-13 21:16:28 +01:00
let [ removeParent , removeIndex ] = BDFDB . ContextMenuUtils . findItem ( e . returnvalue , { id : "copy-native-link" , group : true } ) ;
if ( removeIndex > - 1 ) {
removeParent . splice ( removeIndex , 1 ) ;
removeIndex -= 1 ;
}
let [ removeParent2 , removeIndex2 ] = BDFDB . ContextMenuUtils . findItem ( e . returnvalue , { id : "copy-image" , group : true } ) ;
if ( removeIndex2 > - 1 ) removeParent2 . splice ( removeIndex2 , 1 ) ;
2021-02-12 11:33:45 +01:00
2021-04-24 22:28:41 +02:00
let type = this . isValid ( validUrls [ 0 ] . file , "video" ) ? BDFDB . LanguageUtils . LanguageStrings . VIDEO : BDFDB . LanguageUtils . LanguageStrings . IMAGE ;
2021-02-13 21:16:28 +01:00
let isNative = validUrls . length == 1 && removeIndex > - 1 ;
2021-06-05 21:06:05 +02:00
let subMenu = this . createSubMenus ( e . instance , validUrls ) ;
2021-02-13 21:16:28 +01:00
let [ children , index ] = isNative ? [ removeParent , removeIndex ] : BDFDB . ContextMenuUtils . findItem ( e . returnvalue , { id : "devmode-copy-id" , group : true } ) ;
children . splice ( index > - 1 ? index : children . length , 0 , isNative ? subMenu : BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuGroup , {
2020-09-19 20:49:33 +02:00
children : BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuItem , {
2021-02-09 14:51:23 +01:00
label : type + " " + BDFDB . LanguageUtils . LanguageStrings . ACTIONS ,
2020-09-19 20:49:33 +02:00
id : BDFDB . ContextMenuUtils . createItemId ( this . name , "main-subitem" ) ,
2021-02-13 21:16:28 +01:00
children : subMenu
2020-09-19 20:49:33 +02:00
} )
} ) ) ;
}
2021-06-05 21:06:05 +02:00
filterUrls ( ... urls ) {
let fileTypes = [ ] ;
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" ) ;
let url = srcUrl . replace ( /[\?\&](height|width)=\d+/g , "" ) . split ( "%3A" ) [ 0 ] ;
let original = ( n . original || n ) . replace ( /^url\(|\)$|"|'/g , "" ) . replace ( /\?size\=\d+$/ , "?size=4096" ) . replace ( /[\?\&](height|width)=\d+/g , "" ) . split ( "%3A" ) [ 0 ] ;
if ( url . indexOf ( "https://images-ext-1.discordapp.net/external/" ) > - 1 || url . indexOf ( "https://images-ext-2.discordapp.net/external/" ) > - 1 ) {
if ( url . split ( "/https/" ) . length > 1 ) url = "https://" + url . split ( "/https/" ) . pop ( ) ;
else if ( url . split ( "/http/" ) . length > 1 ) url = "http://" + url . split ( "/http/" ) . pop ( ) ;
}
const file = url && ( BDFDB . LibraryModules . URLParser . parse ( url ) . pathname || "" ) . toLowerCase ( ) ;
const fileType = file && ( file . split ( "." ) . pop ( ) || "" ) ;
return url && fileType && ! fileTypes . includes ( fileType ) && fileTypes . push ( fileType ) && { file : url , src : srcUrl , original : original , fileType } ;
} ) . filter ( n => n ) ;
}
2021-05-28 20:17:33 +02:00
isValid ( url , type ) {
if ( ! url ) return false ;
const file = url && ( BDFDB . LibraryModules . URLParser . parse ( url ) . pathname || "" ) . split ( "%3A" ) [ 0 ] . toLowerCase ( ) ;
2021-07-27 18:34:05 +02:00
return file && ( ! type && ( url . indexOf ( "discord.com/streams/guild:" ) > - 1 || url . indexOf ( "discordapp.com/streams/guild:" ) > - 1 || url . indexOf ( "discordapp.net/streams/guild:" ) > - 1 || url . startsWith ( "https://images-ext-1.discordapp.net/" ) || url . startsWith ( "https://images-ext-2.discordapp.net/" ) || Object . keys ( fileTypes ) . some ( t => file . endsWith ( ` / ${ t } ` ) || file . endsWith ( ` . ${ t } ` ) ) ) || type && Object . keys ( fileTypes ) . filter ( t => fileTypes [ t ] [ type ] ) . some ( t => file . endsWith ( ` / ${ t } ` ) || file . endsWith ( ` . ${ t } ` ) ) ) ;
2021-05-28 20:17:33 +02:00
}
2021-06-05 21:06:05 +02:00
createSubMenus ( instance , validUrls ) {
return validUrls . length == 1 ? this . createUrlMenu ( instance , validUrls [ 0 ] ) : validUrls . map ( ( urlData , i ) => BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuItem , {
label : urlData . fileType . toUpperCase ( ) ,
id : BDFDB . ContextMenuUtils . createItemId ( this . name , "subitem" , i ) ,
children : this . createUrlMenu ( instance , urlData )
} ) ) ;
}
createUrlMenu ( instance , urls ) {
2021-04-24 22:28:41 +02:00
let enabledEngines = BDFDB . ObjectUtils . filter ( this . settings . engines , n => n ) ;
2020-09-19 20:49:33 +02:00
let enginesWithoutAll = BDFDB . ObjectUtils . filter ( enabledEngines , n => n != "_all" , true ) ;
let engineKeys = Object . keys ( enginesWithoutAll ) ;
2020-12-16 10:58:13 +01:00
let locations = Object . keys ( ownLocations ) . filter ( n => ownLocations [ n ] . enabled ) ;
2021-04-24 22:28:41 +02:00
let isVideo = this . isValid ( urls . file , "video" ) ;
2021-02-09 14:51:23 +01:00
let type = isVideo ? BDFDB . LanguageUtils . LanguageStrings . VIDEO : BDFDB . LanguageUtils . LanguageStrings . IMAGE ;
2021-02-13 21:16:28 +01:00
return BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuGroup , {
children : [
BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuItem , {
label : BDFDB . LanguageUtils . LanguageStrings . OPEN _LINK ,
id : BDFDB . ContextMenuUtils . createItemId ( this . name , "open-link" ) ,
2021-04-24 22:50:24 +02:00
action : _ => { BDFDB . DiscordUtils . openLink ( urls . original ) ; }
2021-02-13 21:16:28 +01:00
} ) ,
BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuItem , {
label : BDFDB . LanguageUtils . LanguageStrings . COPY _LINK ,
id : BDFDB . ContextMenuUtils . createItemId ( this . name , "copy-link" ) ,
action : _ => {
2021-04-24 22:50:24 +02:00
BDFDB . LibraryRequires . electron . clipboard . write ( { text : urls . original } ) ;
2021-04-24 22:28:41 +02:00
BDFDB . NotificationUtils . toast ( BDFDB . LanguageUtils . LanguageStrings . LINK _COPIED , { type : "success" } ) ;
}
} ) ,
2021-04-24 22:50:24 +02:00
urls . file != urls . original && BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuItem , {
2021-04-24 22:28:41 +02:00
label : BDFDB . LanguageUtils . LanguageStrings . COPY _MEDIA _LINK ,
id : BDFDB . ContextMenuUtils . createItemId ( this . name , "copy-media-link" ) ,
action : _ => {
BDFDB . LibraryRequires . electron . clipboard . write ( { text : urls . file } ) ;
2021-02-13 21:16:28 +01:00
BDFDB . NotificationUtils . toast ( BDFDB . LanguageUtils . LanguageStrings . LINK _COPIED , { type : "success" } ) ;
}
} ) ,
2021-03-06 18:30:44 +01:00
BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuItem , {
2021-02-13 21:16:28 +01:00
label : this . labels . context _view . replace ( "{{var0}}" , type ) ,
id : BDFDB . ContextMenuUtils . createItemId ( this . name , "view-file" ) ,
action : _ => {
2021-03-06 18:30:44 +01:00
let img = document . createElement ( isVideo ? "video" : "img" ) ;
img . addEventListener ( isVideo ? "loadedmetadata" : "load" , function ( ) {
2021-02-13 21:16:28 +01:00
BDFDB . LibraryModules . ModalUtils . openModal ( modalData => {
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 , {
2021-03-06 18:30:44 +01:00
animated : ! ! isVideo ,
2021-04-24 22:28:41 +02:00
src : urls . src || urls . file ,
original : urls . file ,
2021-03-06 18:30:44 +01:00
width : isVideo ? this . videoWidth : this . width ,
height : isVideo ? this . videoHeight : this . height ,
2021-02-13 21:16:28 +01:00
className : BDFDB . disCN . imagemodalimage ,
shouldAnimate : true ,
2021-03-06 18:30:44 +01:00
renderLinkComponent : props => BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Anchor , props ) ,
2021-03-08 16:28:12 +01:00
children : ! isVideo ? null : ( videoData => BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Video , {
2021-04-24 22:28:41 +02:00
src : urls . src || urls . file ,
2021-03-06 18:30:44 +01:00
width : videoData . size . width ,
height : videoData . size . height ,
naturalWidth : this . videoWidth ,
naturalHeight : this . videoHeight ,
play : true
} ) )
2021-02-13 21:16:28 +01:00
} )
} ) , true ) ;
} ) ;
2021-03-06 18:30:44 +01:00
} ) ;
2021-04-24 22:28:41 +02:00
img . src = urls . file ;
2021-02-13 21:16:28 +01:00
}
} ) ,
2021-04-24 22:28:41 +02:00
! this . isValid ( urls . file , "copyable" ) ? null : BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuItem , {
2021-02-13 21:16:28 +01:00
label : this . labels . context _copy . replace ( "{{var0}}" , type ) ,
id : BDFDB . ContextMenuUtils . createItemId ( this . name , "copy-file" ) ,
2021-04-24 22:28:41 +02:00
action : _ => this . copyFile ( urls . file )
2021-02-13 21:16:28 +01:00
} ) ,
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 : _ => {
2021-04-24 22:28:41 +02:00
this . downloadFileAs ( urls . file ) ;
2021-02-13 21:16:28 +01:00
} ,
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 : _ => {
2021-04-24 22:28:41 +02:00
this . downloadFile ( urls . file , ownLocations [ name ] . location ) ;
2021-02-13 21:16:28 +01:00
}
} ) )
} )
} ) ,
2021-04-24 22:28:41 +02:00
! this . isValid ( urls . file , "searchable" ) ? null : engineKeys . length == 1 ? BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuItem , {
2021-02-13 21:16:28 +01:00
label : this . labels . context _searchwith . replace ( "{{var0}}" , type ) . replace ( "..." , this . defaults . engines [ engineKeys [ 0 ] ] . name ) ,
id : BDFDB . ContextMenuUtils . createItemId ( this . name , "single-search" ) ,
2020-09-19 20:49:33 +02:00
persisting : true ,
action : event => {
2021-06-05 21:06:05 +02:00
if ( ! event . shiftKey ) BDFDB . ContextMenuUtils . close ( instance ) ;
2021-04-24 22:28:41 +02:00
BDFDB . DiscordUtils . openLink ( this . defaults . engines [ engineKeys [ 0 ] ] . url . replace ( imgUrlReplaceString , encodeURIComponent ( urls . file ) ) , {
2021-01-10 11:41:01 +01:00
minimized : event . shiftKey
} ) ;
2020-09-19 20:49:33 +02:00
}
2021-02-13 21:16:28 +01:00
} ) : BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuItem , {
label : this . labels . context _searchwith . replace ( "{{var0}}" , type ) ,
id : BDFDB . ContextMenuUtils . createItemId ( this . name , "submenu-search" ) ,
children : ! engineKeys . length ? BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuItem , {
label : this . labels . submenu _disabled ,
id : BDFDB . ContextMenuUtils . createItemId ( this . name , "disabled" ) ,
disabled : true
} ) : Object . keys ( enabledEngines ) . map ( key => BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuItem , {
label : this . defaults . engines [ key ] . name ,
id : BDFDB . ContextMenuUtils . createItemId ( this . name , "search" , key ) ,
color : key == "_all" ? BDFDB . LibraryComponents . MenuItems . Colors . DANGER : BDFDB . LibraryComponents . MenuItems . Colors . DEFAULT ,
persisting : true ,
action : event => {
2021-04-24 22:50:24 +02:00
const open = ( url , k ) => BDFDB . DiscordUtils . openLink ( this . defaults . engines [ k ] . url . replace ( imgUrlReplaceString , this . defaults . engines [ k ] . raw ? url : encodeURIComponent ( url ) ) , { minimized : event . shiftKey } ) ;
2021-06-05 21:06:05 +02:00
if ( ! event . shiftKey ) BDFDB . ContextMenuUtils . close ( instance ) ;
2021-02-13 21:16:28 +01:00
if ( key == "_all" ) {
2021-04-24 22:50:24 +02:00
for ( let key2 in enginesWithoutAll ) open ( urls . file , key2 ) ;
2021-02-13 21:16:28 +01:00
}
2021-04-24 22:50:24 +02:00
else open ( urls . file , key ) ;
2021-02-13 21:16:28 +01:00
}
} ) )
} )
] . filter ( n => n )
} ) ;
2020-09-19 20:49:33 +02:00
}
processImageModal ( e ) {
if ( clickedImage ) e . instance . props . cachedImage = clickedImage ;
2021-01-23 23:19:06 +01:00
let url = this . getImageSrc ( e . instance . props . cachedImage && e . instance . props . cachedImage . src ? e . instance . props . cachedImage : e . instance . props . src ) ;
2021-03-06 22:23:21 +01:00
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 ;
2021-03-06 18:30:44 +01:00
let isVideo = this . isValid ( url , "video" ) ;
2021-01-23 23:19:06 +01:00
let messages = this . getMessageGroupOfImage ( url ) ;
2020-09-19 20:49:33 +02:00
if ( e . returnvalue ) {
let [ children , index ] = BDFDB . ReactUtils . findParent ( e . returnvalue , { props : [ [ "className" , BDFDB . disCN . downloadlink ] ] } ) ;
if ( index > - 1 ) {
2021-02-12 11:33:45 +01:00
let type = isVideo ? BDFDB . LanguageUtils . LanguageStrings . VIDEO : BDFDB . LanguageUtils . LanguageStrings . IMAGE ;
2020-09-19 20:49:33 +02:00
let openContext = event => {
BDFDB . ContextMenuUtils . open ( this , event , BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuGroup , {
2021-04-24 22:28:41 +02:00
children : Object . keys ( this . defaults . zoomSettings ) . map ( type => BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuSliderItem , Object . assign ( {
2020-09-19 20:49:33 +02:00
id : BDFDB . ContextMenuUtils . createItemId ( this . name , type ) ,
2021-04-24 22:28:41 +02:00
value : this . settings . zoomSettings [ type ] ,
2020-09-19 20:49:33 +02:00
renderLabel : value => {
return ( this . labels [ this . defaults . zoomSettings [ type ] . label ] || BDFDB . LanguageUtils . LanguageStrings [ this . defaults . zoomSettings [ type ] . label ] ) + ": " + value + this . defaults . zoomSettings [ type ] . unit ;
} ,
onValueRender : value => {
return value + this . defaults . zoomSettings [ type ] . unit ;
} ,
onValueChange : value => {
2021-04-24 22:28:41 +02:00
this . settings . zoomSettings [ type ] = value ;
BDFDB . DataUtils . save ( this . settings . zoomSettings , this , "zoomSettings" ) ;
2020-08-14 14:37:10 +02:00
}
2020-09-19 20:49:33 +02:00
} , BDFDB . ObjectUtils . extract ( this . defaults . zoomSettings [ type ] , "digits" , "minValue" , "maxValue" ) ) ) )
} ) ) ;
} ;
children [ index ] = BDFDB . ReactUtils . createElement ( "span" , {
className : BDFDB . disCN . _imageutilitiesoperations ,
children : [
children [ index ] ,
2021-04-24 22:28:41 +02:00
this . settings . general . enableSaveImg && [
2020-09-19 20:49:33 +02:00
BDFDB . ReactUtils . createElement ( "span" , {
className : BDFDB . disCN . downloadlink ,
children : "|" ,
style : { margin : "0 5px" }
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Anchor , {
className : BDFDB . disCN . downloadlink ,
2021-02-09 14:51:23 +01:00
children : this . labels . context _saveas . replace ( "{{var0}}" , type ) ,
2020-09-19 20:49:33 +02:00
onClick : event => {
BDFDB . ListenerUtils . stopEvent ( event ) ;
2021-02-09 14:51:23 +01:00
this . downloadFileAs ( url ) ;
2020-12-15 15:03:09 +01:00
} ,
onContextMenu : event => {
2020-12-16 10:58:13 +01:00
let locations = Object . keys ( ownLocations ) . filter ( n => ownLocations [ n ] . enabled ) ;
if ( locations . length ) BDFDB . ContextMenuUtils . open ( this , event , BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuGroup , {
2021-01-23 23:19:06 +01:00
children : locations . map ( ( name , i ) => BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuItem , {
2020-12-15 15:03:09 +01:00
id : BDFDB . ContextMenuUtils . createItemId ( this . name , "download" , name , i ) ,
label : name ,
2021-02-09 14:51:23 +01:00
action : _ => this . downloadFile ( url , ownLocations [ name ] . location )
2020-12-15 15:03:09 +01:00
} ) )
} ) ) ;
2020-09-19 20:49:33 +02:00
}
} )
] ,
2021-04-24 22:28:41 +02:00
this . settings . general . enableCopyImg && this . isValid ( url , "copyable" ) && [
2020-09-19 20:49:33 +02:00
BDFDB . ReactUtils . createElement ( "span" , {
className : BDFDB . disCN . downloadlink ,
children : "|" ,
style : { margin : "0 5px" }
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Anchor , {
className : BDFDB . disCN . downloadlink ,
2021-02-09 14:51:23 +01:00
children : this . labels . context _copy . replace ( "{{var0}}" , type ) ,
2020-09-19 20:49:33 +02:00
onClick : event => {
BDFDB . ListenerUtils . stopEvent ( event ) ;
2021-02-09 14:51:23 +01:00
this . copyFile ( url ) ;
2020-09-19 20:49:33 +02:00
}
} )
] ,
2021-04-24 22:28:41 +02:00
this . settings . general . enableZoom && ! isVideo && [
2020-09-19 20:49:33 +02:00
BDFDB . ReactUtils . createElement ( "span" , {
className : BDFDB . disCN . downloadlink ,
children : "|" ,
style : { margin : "0 5px" }
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Anchor , {
className : BDFDB . disCN . downloadlink ,
children : ` Zoom ${ BDFDB . LanguageUtils . LanguageStrings . SETTINGS } ` ,
onClick : openContext ,
onContextMenu : openContext
} )
]
] . flat ( 10 ) . filter ( n => n )
} ) ;
2020-08-14 14:37:10 +02:00
}
2020-09-19 20:49:33 +02:00
let imageIndex = 0 , amount = 1 ;
2021-01-23 23:19:06 +01:00
if ( messages . length ) {
let data = this . getSiblingsAndPosition ( url , messages ) ;
2020-10-16 19:47:23 +02:00
imageIndex = data . index ;
amount = data . amount ;
if ( data . previous ) {
2020-09-19 20:49:33 +02:00
if ( e . instance . previousRef ) e . returnvalue . props . children . push ( this . createImageWrapper ( e . instance , e . instance . previousRef , "previous" , BDFDB . LibraryComponents . SvgIcon . Names . LEFT _CARET ) ) ;
2020-10-16 19:47:23 +02:00
else this . loadImage ( e . instance , data . previous , "previous" ) ;
2020-09-19 20:49:33 +02:00
}
2020-10-16 19:47:23 +02:00
if ( data . next ) {
2020-09-19 20:49:33 +02:00
if ( e . instance . nextRef ) e . returnvalue . props . children . splice ( 1 , 0 , this . createImageWrapper ( e . instance , e . instance . nextRef , "next" , BDFDB . LibraryComponents . SvgIcon . Names . RIGHT _CARET ) ) ;
2020-10-16 19:47:23 +02:00
else this . loadImage ( e . instance , data . next , "next" ) ;
2020-09-19 20:49:33 +02:00
}
2020-08-14 14:37:10 +02:00
}
2021-04-24 22:28:41 +02:00
if ( this . settings . general . addDetails ) e . returnvalue . props . children . push ( BDFDB . ReactUtils . createElement ( "div" , {
2020-09-19 20:49:33 +02:00
className : BDFDB . disCN . _imageutilitiesdetailswrapper ,
2020-08-14 15:41:21 +02:00
children : [
2021-02-12 11:33:45 +01:00
{ label : "Source" , text : url } ,
2021-02-04 14:21:47 +01:00
{ label : "Size" , text : ` ${ e . instance . props . width } x ${ e . instance . props . height } px ` } ,
2020-09-19 20:49:33 +02:00
{ label : "Image" , text : ` ${ imageIndex + 1 } of ${ amount } ` }
] . 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 . dotCNC . modal + BDFDB . dotCN . layermodal , e . node ) ;
if ( modal ) {
2021-04-24 22:28:41 +02:00
modal . className = BDFDB . DOMUtils . formatClassName ( modal . className , messages . length && BDFDB . disCN . _imageutilitiesgallery , this . settings . general . addDetails && BDFDB . disCN . _imageutilitiesdetailsadded ) ;
2020-09-19 20:49:33 +02:00
this . cleanupListeners ( "Gallery" ) ;
2021-01-23 23:19:06 +01:00
if ( messages . length ) {
2020-09-19 20:49:33 +02:00
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" ) ;
}
} ;
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 ) ;
}
2020-08-14 14:37:10 +02:00
}
}
}
2020-09-19 20:49:33 +02:00
processLazyImage ( e ) {
if ( e . node ) {
2020-11-17 18:46:57 +01:00
if ( e . instance . props . resized ) e . instance . state . readyState = BDFDB . LibraryComponents . Image . ImageReadyStates . READY ;
2021-02-12 11:33:45 +01:00
let isVideo = ( typeof e . instance . props . children == "function" && e . instance . props . children ( Object . assign ( { } , e . instance . props , { size : e . instance . props } ) ) || { type : { } } ) . type . displayName == "Video" ;
2021-07-13 12:47:15 +02:00
if ( this . settings . general . enableZoom && ! isVideo && ! BDFDB . DOMUtils . containsClass ( e . node . parentElement , BDFDB . disCN . _imageutilitiessibling ) && BDFDB . ReactUtils . findOwner ( BDFDB . ReactUtils . getInstance ( e . node ) , { name : "ImageModal" , up : true } ) ) {
2020-09-19 20:49:33 +02:00
e . node . addEventListener ( "mousedown" , event => {
if ( event . which != 1 ) return ;
BDFDB . ListenerUtils . stopEvent ( event ) ;
2020-08-14 14:37:10 +02:00
2021-02-25 12:13:10 +01:00
let vanishObserver ;
2020-09-19 20:49:33 +02:00
let imgRects = BDFDB . DOMUtils . getRects ( e . node . firstElementChild ) ;
2020-08-14 14:37:10 +02:00
2021-04-24 22:28:41 +02:00
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=" ${ 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 . general . pixelZoom ? " image-rendering: pixelated !important;" : "" } " ${ e . node . firstElementChild . tagName == "VIDEO" ? " loop autoplay" : "" } ></ ${ e . node . firstElementChild . tagName } ></div></div> ` ) ;
2020-11-29 20:18:28 +01:00
let pane = lens . firstElementChild . firstElementChild ;
2020-09-19 20:49:33 +02:00
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 ) ;
2020-11-29 20:18:28 +01:00
appMount . appendChild ( lens ) ;
2020-09-19 20:49:33 +02:00
appMount . appendChild ( backdrop ) ;
2020-08-15 10:38:15 +02:00
2020-11-29 20:18:28 +01:00
let lensRects = BDFDB . DOMUtils . getRects ( lens ) ;
2020-09-19 20:49:33 +02:00
2020-11-29 20:18:28 +01:00
let halfW = lensRects . width / 2 , halfH = lensRects . height / 2 ;
2020-09-19 20:49:33 +02:00
let minX = imgRects . left , maxX = minX + imgRects . width ;
let minY = imgRects . top , maxY = minY + imgRects . height ;
2020-11-29 20:18:28 +01:00
lens . update = _ => {
2020-09-19 20:49:33 +02:00
let x = event . clientX > maxX ? maxX - halfW : event . clientX < minX ? minX - halfW : event . clientX - halfW ;
let y = event . clientY > maxY ? maxY - halfH : event . clientY < minY ? minY - halfH : event . clientY - halfH ;
2020-11-29 20:18:28 +01:00
lens . style . setProperty ( "left" , x + "px" , "important" ) ;
lens . style . setProperty ( "top" , y + "px" , "important" ) ;
2021-04-24 22:28:41 +02:00
lens . style . setProperty ( "width" , this . settings . zoomSettings . lensSize + "px" , "important" ) ;
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" ) ;
2020-09-19 20:49:33 +02:00
} ;
2020-11-29 20:18:28 +01:00
lens . update ( ) ;
2020-09-19 20:49:33 +02:00
let dragging = event2 => {
event = event2 ;
2020-11-29 20:18:28 +01:00
lens . update ( ) ;
2020-09-19 20:49:33 +02:00
} ;
let releasing = _ => {
this . cleanupListeners ( "Zoom" ) ;
document . removeEventListener ( "mousemove" , dragging ) ;
document . removeEventListener ( "mouseup" , releasing ) ;
2021-02-25 12:13:10 +01:00
if ( vanishObserver ) vanishObserver . disconnect ( ) ;
2020-11-29 20:18:28 +01:00
BDFDB . DOMUtils . remove ( lens , backdrop ) ;
2021-04-24 22:28:41 +02:00
BDFDB . DataUtils . save ( this . settings . zoomSettings , this , "zoomSettings" ) ;
2020-09-19 20:49:33 +02:00
} ;
document . addEventListener ( "mousemove" , dragging ) ;
document . addEventListener ( "mouseup" , releasing ) ;
2020-08-15 10:38:15 +02:00
this . cleanupListeners ( "Zoom" ) ;
2020-09-19 20:49:33 +02:00
document . wheelImageUtilitiesZoomListener = event2 => {
if ( ! document . contains ( e . node ) ) this . cleanupListeners ( "Zoom" ) ;
else {
2021-04-24 22:28:41 +02:00
if ( event2 . deltaY < 0 && ( this . settings . zoomSettings . zoomLevel + 0.1 ) <= this . defaults . zoomSettings . zoomLevel . maxValue ) {
this . settings . zoomSettings . zoomLevel += 0.1 ;
2020-11-29 20:18:28 +01:00
lens . update ( ) ;
2020-09-19 20:49:33 +02:00
}
2021-04-24 22:28:41 +02:00
else if ( event2 . deltaY > 0 && ( this . settings . zoomSettings . zoomLevel - 0.1 ) >= this . defaults . zoomSettings . zoomLevel . minValue ) {
this . settings . zoomSettings . zoomLevel -= 0.1 ;
2020-11-29 20:18:28 +01:00
lens . update ( ) ;
2020-09-19 20:49:33 +02:00
}
2020-08-15 10:38:15 +02:00
}
2020-09-19 20:49:33 +02:00
} ;
document . keydownImageUtilitiesZoomListener = event2 => {
if ( ! document . contains ( e . node ) ) this . cleanupListeners ( "Zoom" ) ;
else if ( ! firedEvents . includes ( "Zoom" ) ) {
firedEvents . push ( "Zoom" ) ;
2021-04-24 22:28:41 +02:00
if ( event2 . keyCode == 187 && ( this . settings . zoomSettings . zoomLevel + 0.5 ) <= this . defaults . zoomSettings . zoomLevel . maxValue ) {
this . settings . zoomSettings . zoomLevel += 0.5 ;
2020-11-29 20:18:28 +01:00
lens . update ( ) ;
2020-09-19 20:49:33 +02:00
}
2021-04-24 22:28:41 +02:00
else if ( event2 . keyCode == 189 && ( this . settings . zoomSettings . zoomLevel - 0.5 ) >= this . defaults . zoomSettings . zoomLevel . minValue ) {
this . settings . zoomSettings . zoomLevel -= 0.5 ;
2020-11-29 20:18:28 +01:00
lens . update ( ) ;
2020-09-19 20:49:33 +02:00
}
2020-08-15 10:38:15 +02:00
}
2020-09-19 20:49:33 +02:00
} ;
document . keyupImageUtilitiesZoomListener = _ => {
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 ) ;
2021-02-25 12:13:10 +01:00
vanishObserver = new MutationObserver ( changes => { if ( ! document . contains ( e . node ) ) releasing ( ) ; } ) ;
vanishObserver . observe ( appMount , { childList : true , subtree : true } ) ;
2020-09-19 20:49:33 +02:00
} ) ;
}
}
else if ( e . returnvalue ) {
2021-04-24 22:28:41 +02:00
if ( this . settings . general . showOnHover && e . instance . props . original && e . instance . props . src . indexOf ( "https://media.discordapp.net/attachments" ) == 0 && typeof e . returnvalue . props . children == "function" ) {
2020-11-19 16:51:14 +01:00
let attachment = BDFDB . ReactUtils . findValue ( e . instance , "attachment" , { up : true } ) ;
2020-09-19 20:49:33 +02:00
if ( attachment ) {
let renderChildren = e . returnvalue . props . children ;
2021-07-05 16:33:10 +02:00
e . returnvalue . props . children = BDFDB . TimeUtils . suppress ( ( ... args ) => {
2020-09-19 20:49:33 +02:00
return BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TooltipContainer , {
text : ` ${ attachment . filename } \n ${ BDFDB . NumberUtils . formatBytes ( attachment . size ) } \n ${ attachment . width } x ${ attachment . height } px ` ,
tooltipConfig : {
type : "right" ,
2021-04-24 22:28:41 +02:00
delay : this . settings . amounts . hoverDelay
2020-09-19 20:49:33 +02:00
} ,
children : renderChildren ( ... args )
} ) ;
2021-07-05 16:33:10 +02:00
} , "" , this ) ;
2020-09-19 20:49:33 +02:00
}
}
}
2020-10-16 19:47:23 +02:00
else {
2021-07-13 12:47:15 +02:00
if ( this . settings . general . resizeImage && BDFDB . ReactUtils . findOwner ( BDFDB . ObjectUtils . get ( e , ` instance. ${ BDFDB . ReactUtils . instanceKey } ` ) , { name : "ImageModal" , up : true } ) ) {
2021-04-24 22:28:41 +02:00
let data = this . settings . general . enableGallery ? this . getSiblingsAndPosition ( e . instance . props . src , this . getMessageGroupOfImage ( e . instance . props . src ) ) : { } ;
2020-10-16 19:47:23 +02:00
let aRects = BDFDB . DOMUtils . getRects ( document . querySelector ( BDFDB . dotCN . appmount ) ) ;
2021-04-24 22:28:41 +02:00
let ratio = Math . min ( ( aRects . width * ( data . previous || data . next ? 0.8 : 1 ) - 20 ) / e . instance . props . width , ( aRects . height - ( this . settings . general . addDetails ? 310 : 100 ) ) / e . instance . props . height ) ;
2020-10-16 19:47:23 +02:00
let width = Math . round ( ratio * e . instance . props . width ) ;
let height = Math . round ( ratio * e . instance . props . height ) ;
e . instance . props . width = width ;
e . instance . props . maxWidth = width ;
e . instance . props . height = height ;
e . instance . props . maxHeight = height ;
e . instance . props . src = e . instance . props . src . replace ( /width=\d+/ , ` width= ${ width } ` ) . replace ( /height=\d+/ , ` height= ${ height } ` ) ;
2020-11-17 18:46:57 +01:00
e . instance . props . resized = true ;
2020-10-16 19:47:23 +02:00
}
}
2020-09-19 20:49:33 +02:00
}
2021-06-05 21:06:05 +02:00
processUserBanner ( e ) {
if ( e . instance . props . user && this . settings . places . userAvatars && BDFDB . UserUtils . getBanner ( e . instance . props . user . id ) ) e . returnvalue . props . onContextMenu = event => {
let validUrls = this . filterUrls ( ( e . instance . props . user . getBannerURL ( ) || "" ) . replace ( /\.webp|\.gif/ , ".png" ) , BDFDB . LibraryModules . IconUtils . isAnimatedIconHash ( e . instance . props . user . banner ) && e . instance . props . user . getBannerURL ( true ) ) ;
if ( validUrls . length ) BDFDB . ContextMenuUtils . open ( this , event , BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuGroup , {
children : validUrls . length == 1 ? this . createSubMenus ( { } , validUrls ) : BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuItem , {
label : BDFDB . LanguageUtils . LanguageStrings . IMAGE + " " + BDFDB . LanguageUtils . LanguageStrings . ACTIONS ,
id : BDFDB . ContextMenuUtils . createItemId ( this . name , "main-subitem" ) ,
children : this . createSubMenus ( { } , validUrls )
} )
} ) ) ;
} ;
}
2021-02-09 14:51:23 +01:00
downloadFile ( url , path ) {
2020-12-15 15:03:09 +01:00
url = url . startsWith ( "/assets" ) ? ( window . location . origin + url ) : url ;
BDFDB . LibraryRequires . request ( url , { encoding : null } , ( error , response , body ) => {
2021-02-09 14:51:23 +01:00
let type = this . isValid ( url , "video" ) ? BDFDB . LanguageUtils . LanguageStrings . VIDEO : BDFDB . LanguageUtils . LanguageStrings . IMAGE ;
if ( error ) BDFDB . NotificationUtils . toast ( this . labels . toast _save _failed . replace ( "{{var0}}" , type ) . replace ( "{{var1}}" , path ) , { type : "danger" } ) ;
2020-12-15 15:03:09 +01:00
else {
BDFDB . LibraryRequires . fs . writeFile ( this . getFileName ( path , url . split ( "/" ) . pop ( ) . split ( "." ) . slice ( 0 , - 1 ) . join ( "." ) , response . headers [ "content-type" ] . split ( "/" ) . pop ( ) . split ( "+" ) [ 0 ] , 0 ) , body , error => {
2021-02-09 14:51:23 +01:00
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" } ) ;
2020-12-15 15:03:09 +01:00
} ) ;
}
} ) ;
}
2021-02-09 14:51:23 +01:00
downloadFileAs ( url ) {
2020-12-15 15:03:09 +01:00
url = url . startsWith ( "/assets" ) ? ( window . location . origin + url ) : url ;
2020-09-19 20:49:33 +02:00
BDFDB . LibraryRequires . request ( url , { encoding : null } , ( error , response , body ) => {
let hrefURL = window . URL . createObjectURL ( new Blob ( [ body ] ) ) ;
let tempLink = document . createElement ( "a" ) ;
tempLink . href = hrefURL ;
2021-02-12 11:33:45 +01:00
tempLink . download = ` ${ url . split ( "/" ) . pop ( ) . split ( "." ) . slice ( 0 , - 1 ) . join ( "." ) || "unknown" } . ${ response . headers [ "content-type" ] . split ( "/" ) . pop ( ) . split ( "+" ) [ 0 ] } ` ;
2020-09-19 20:49:33 +02:00
tempLink . click ( ) ;
window . URL . revokeObjectURL ( hrefURL ) ;
2020-08-14 14:37:10 +02:00
} ) ;
}
2020-09-19 20:49:33 +02:00
2021-02-09 14:51:23 +01:00
copyFile ( url ) {
2021-05-07 22:22:36 +02:00
BDFDB . LibraryRequires . request ( url , { encoding : null } , ( error , response , body ) => {
2021-02-09 14:51:23 +01:00
let type = this . isValid ( url , "video" ) ? BDFDB . LanguageUtils . LanguageStrings . VIDEO : BDFDB . LanguageUtils . LanguageStrings . IMAGE ;
if ( error ) BDFDB . NotificationUtils . toast ( this . labels . toast _copy _failed . replace ( "{{var0}}" , type ) , { type : "danger" } ) ;
2021-05-07 22:22:36 +02:00
else if ( body ) {
2020-09-19 20:49:33 +02:00
if ( BDFDB . LibraryRequires . process . platform === "win32" || BDFDB . LibraryRequires . process . platform === "darwin" ) {
2021-05-07 22:22:36 +02:00
BDFDB . LibraryRequires . electron . clipboard . write ( { image : BDFDB . LibraryRequires . electron . nativeImage . createFromBuffer ( body ) } ) ;
2020-09-19 20:49:33 +02:00
}
else {
2021-07-07 14:39:01 +02:00
let file = BDFDB . LibraryRequires . path . join ( BDFDB . LibraryRequires . process . resourcesPath , "imageutilstempimg.png" ) ;
2021-05-07 22:22:36 +02:00
BDFDB . LibraryRequires . fs . writeFileSync ( file , body , { encoding : null } ) ;
2020-09-19 20:49:33 +02:00
BDFDB . LibraryRequires . electron . clipboard . write ( { image : file } ) ;
BDFDB . LibraryRequires . fs . unlinkSync ( file ) ;
}
2021-02-09 14:51:23 +01:00
BDFDB . NotificationUtils . toast ( this . labels . toast _copy _success . replace ( "{{var0}}" , type ) , { type : "success" } ) ;
2020-08-14 14:37:10 +02:00
}
2020-09-19 20:49:33 +02:00
} ) ;
}
2021-01-06 12:38:36 +01:00
getDownloadLocation ( ) {
2020-12-15 15:03:09 +01:00
if ( downloadsFolder && BDFDB . LibraryRequires . fs . existsSync ( downloadsFolder ) ) return downloadsFolder ;
2021-07-11 18:01:39 +02:00
let homePath = BDFDB . LibraryRequires . process . env . USERPROFILE || BDFDB . LibraryRequires . process . env . HOMEPATH || BDFDB . LibraryRequires . process . env . HOME ;
let downloadPath = homePath && BDFDB . LibraryRequires . path . join ( homePath , "Downloads" ) ;
if ( downloadPath && BDFDB . LibraryRequires . fs . existsSync ( downloadPath ) ) return downloadsFolder = downloadPath ;
2021-07-07 14:39:01 +02:00
else {
downloadsFolder = BDFDB . LibraryRequires . path . join ( BDFDB . BDUtils . getPluginsFolder ( ) , "downloads" ) ;
if ( ! BDFDB . LibraryRequires . fs . existsSync ( downloadsFolder ) ) BDFDB . LibraryRequires . fs . mkdirSync ( downloadsFolder ) ;
return downloadsFolder ;
}
2020-09-19 20:49:33 +02:00
}
getFileName ( path , fileName , extension , i ) {
let wholePath = BDFDB . LibraryRequires . path . join ( path , i ? ` ${ fileName } ( ${ i } ). ${ extension } ` : ` ${ fileName } . ${ extension } ` ) ;
if ( BDFDB . LibraryRequires . fs . existsSync ( wholePath ) ) return this . getFileName ( path , fileName , extension , i + 1 ) ;
else return wholePath ;
}
2020-08-14 14:37:10 +02:00
2020-09-19 20:49:33 +02:00
getMessageGroupOfImage ( src ) {
2021-04-24 22:28:41 +02:00
if ( src && this . settings . general . enableGallery ) for ( let message of document . querySelectorAll ( BDFDB . dotCN . message ) ) for ( let img of message . querySelectorAll ( BDFDB . dotCNS . imagewrapper + "img" ) ) if ( this . isSameImage ( src , img ) ) {
2020-09-19 20:49:33 +02:00
let previousSiblings = [ ] , nextSiblings = [ ] ;
let previousSibling = message . previousSibling , nextSibling = message . nextSibling ;
if ( ! BDFDB . DOMUtils . containsClass ( message , BDFDB . disCN . messagegroupstart ) ) while ( previousSibling ) {
previousSiblings . push ( previousSibling ) ;
if ( BDFDB . DOMUtils . containsClass ( previousSibling , BDFDB . disCN . messagegroupstart ) ) previousSibling = null ;
else previousSibling = previousSibling . previousSibling ;
}
while ( nextSibling ) {
if ( ! BDFDB . DOMUtils . containsClass ( nextSibling , BDFDB . disCN . messagegroupstart ) ) {
nextSiblings . push ( nextSibling ) ;
nextSibling = nextSibling . nextSibling ;
}
else nextSibling = null ;
2020-08-14 14:37:10 +02:00
}
2020-09-19 20:49:33 +02:00
return [ ] . concat ( previousSiblings . reverse ( ) , message , nextSiblings ) . filter ( n => n && BDFDB . DOMUtils . containsClass ( n , BDFDB . disCN . message ) ) ;
2020-08-14 14:37:10 +02:00
}
2020-09-19 20:49:33 +02:00
return [ ] ;
}
2021-01-23 23:19:06 +01:00
getSiblingsAndPosition ( url , messages ) {
let images = messages . map ( n => Array . from ( n . querySelectorAll ( BDFDB . dotCNS . imagewrapper + "img" ) ) ) . flat ( ) . filter ( img => ! BDFDB . DOMUtils . getParent ( BDFDB . dotCN . spoilerhidden , img ) ) ;
2020-10-16 19:47:23 +02:00
let next , previous , index = 0 , amount = images . length ;
for ( let i = 0 ; i < amount ; i ++ ) if ( this . isSameImage ( url , images [ i ] ) ) {
index = i ;
previous = images [ i - 1 ] ;
next = images [ i + 1 ] ;
break ;
}
return { next , previous , index , amount } ;
}
2020-09-19 20:49:33 +02:00
isSameImage ( src , img ) {
return img . src && ( Node . prototype . isPrototypeOf ( src ) && img == src || ! Node . prototype . isPrototypeOf ( src ) && this . getImageSrc ( img ) == this . getImageSrc ( src ) ) ;
2020-08-14 14:37:10 +02:00
}
2020-09-19 20:49:33 +02:00
getImageSrc ( img ) {
if ( ! img ) return null ;
2021-03-02 19:20:11 +01:00
return ( typeof img == "string" ? img : ( img . src || ( img . querySelector ( "canvas" ) ? img . querySelector ( "canvas" ) . src : "" ) ) ) . split ( "?width=" ) [ 0 ] ;
2020-09-19 20:49:33 +02:00
}
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
} )
]
2020-08-14 14:37:10 +02:00
} ) ;
2020-09-19 20:49:33 +02:00
}
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 ,
} ) ;
BDFDB . ReactUtils . forceUpdate ( instance ) ;
} ;
}
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 . props . cachedImage = img ;
2020-08-14 14:37:10 +02:00
BDFDB . ReactUtils . forceUpdate ( instance ) ;
2020-08-15 10:38:15 +02:00
}
2020-08-14 14:37:10 +02:00
2020-09-19 20:49:33 +02:00
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 ` ] ;
}
2020-08-14 14:37:10 +02:00
}
2021-01-06 12:38:36 +01:00
setLabelsByLanguage ( ) {
2020-09-19 20:49:33 +02:00
switch ( BDFDB . LanguageUtils . getLanguage ( ) . id ) {
2020-12-21 19:56:36 +01:00
case "bg" : // Bulgarian
2020-09-19 20:49:33 +02:00
return {
2021-02-09 14:51:23 +01:00
context _copy : "Копирайте {{var0}}" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "Размер на обектива" ,
2021-02-09 14:51:23 +01:00
context _saveas : "Запазете {{var0}} като ..." ,
context _searchwith : "Търсете {{var0}} с ..." ,
context _view : "Преглед {{var0}}" ,
2020-12-21 19:56:36 +01:00
submenu _disabled : "Всички инвалиди" ,
2021-02-09 14:51:23 +01:00
toast _copy _failed : "{{var0}} не можа да бъде копиран в клипборда" ,
toast _copy _success : "{{var0}} беше копиран в клипборда" ,
toast _save _failed : "{{var0}} не можа да бъде запазен в '{{var1}}'" ,
toast _save _success : "{{var0}} б е запазено в '{{var1}}'"
2020-09-19 20:49:33 +02:00
} ;
2021-07-08 16:59:41 +02:00
case "cs" : // Czech
return {
context _copy : "Zkopírovat {{var0}}" ,
context _lenssize : "Velikost lupy" ,
context _saveas : "Uložit {{var0}} jako..." ,
context _searchwith : "Hledat {{var0}} pomocí..." ,
context _view : "Zobrazit {{var0}}" ,
submenu _disabled : "Vše zakázáno" ,
toast _copy _failed : "{{var0}} nemohl být zkopírován do schránky" ,
toast _copy _success : "{{var0}} byl zkopírován do schránky" ,
toast _save _failed : "{{var0}} nemohl být uložen do '{{var1}}'" ,
toast _save _success : "{{var0}} bylo uložen do '{{var1}}'"
} ;
2020-12-21 19:56:36 +01:00
case "da" : // Danish
2020-09-19 20:49:33 +02:00
return {
2021-02-09 14:51:23 +01:00
context _copy : "Kopiér {{var0}}" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "Objektivstørrelse" ,
2021-02-09 14:51:23 +01:00
context _saveas : "Gem {{var0}} som ..." ,
context _searchwith : "Søg i {{var0}} med ..." ,
context _view : "Se {{var0}}" ,
2020-12-21 19:56:36 +01:00
submenu _disabled : "Alle handicappede" ,
2021-02-09 14:51:23 +01:00
toast _copy _failed : "{{var0}} kunne ikke kopieres til udklipsholderen" ,
toast _copy _success : "{{var0}} blev kopieret til udklipsholderen" ,
toast _save _failed : "{{var0}} kunne ikke gemmes i '{{var1}}'" ,
toast _save _success : "{{var0}} blev gemt i '{{var1}}'"
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "de" : // German
2020-09-19 20:49:33 +02:00
return {
2021-02-09 14:51:23 +01:00
context _copy : "{{var0}} kopieren" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "Linsengröße" ,
2021-02-09 14:51:23 +01:00
context _saveas : "{{var0}} speichern als ..." ,
context _searchwith : "{{var0}} suchen mit ..." ,
context _view : "{{var0}} ansehen" ,
2020-12-21 19:56:36 +01:00
submenu _disabled : "Alle deaktiviert" ,
2021-02-09 14:51:23 +01:00
toast _copy _failed : "{{var0}} konnte nicht in die Zwischenablage kopiert werden" ,
toast _copy _success : "{{var0}} wurde in die Zwischenablage kopiert" ,
toast _save _failed : "{{var0}} konnte nicht in '{{var1}}' gespeichert werden" ,
toast _save _success : "{{var0}} wurde in '{{var1}}' gespeichert"
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "el" : // Greek
2020-09-19 20:49:33 +02:00
return {
2021-02-09 14:51:23 +01:00
context _copy : "Αντιγραφή {{var0}}" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "Μέγεθος φακού" ,
2021-02-09 14:51:23 +01:00
context _saveas : "Αποθήκευση {{var0}} ως ..." ,
context _searchwith : "Αναζήτηση {{var0}} με ..." ,
context _view : "Προβολή {{var0}}" ,
2020-12-21 19:56:36 +01:00
submenu _disabled : "Όλα τα άτομα με ειδικές ανάγκες" ,
2021-02-09 14:51:23 +01:00
toast _copy _failed : "Δεν ήταν δυνατή η αντιγραφή του {{var0}} στο πρόχειρο" ,
toast _copy _success : "Τ ο {{var0}} αντιγράφηκε στο πρόχειρο" ,
toast _save _failed : "Δεν ήταν δυνατή η αποθήκευση του {{var0}} στο '{{var1}}'" ,
toast _save _success : "Τ ο {{var0}} αποθηκεύτηκε στο '{{var1}}'"
2020-12-21 19:56:36 +01:00
} ;
case "es" : // Spanish
return {
2021-02-09 14:51:23 +01:00
context _copy : "Copiar {{var0}}" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "Tamaño de la lente" ,
2021-02-09 14:51:23 +01:00
context _saveas : "Guardar {{var0}} como ..." ,
context _searchwith : "Buscar {{var0}} con ..." ,
context _view : "Ver {{var0}}" ,
2020-12-21 19:56:36 +01:00
submenu _disabled : "Todos discapacitados" ,
2021-02-09 14:51:23 +01:00
toast _copy _failed : "{{var0}} no se pudo copiar al portapapeles" ,
toast _copy _success : "{{var0}} se copió en el portapapeles" ,
toast _save _failed : "{{var0}} no se pudo guardar en '{{var1}}'" ,
toast _save _success : "{{var0}} se guardó en '{{var1}}'"
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "fi" : // Finnish
2020-09-19 20:49:33 +02:00
return {
2021-02-09 14:51:23 +01:00
context _copy : "Kopioi {{var0}}" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "Linssin koko" ,
2021-02-09 14:51:23 +01:00
context _saveas : "Tallenna {{var0}} nimellä ..." ,
context _searchwith : "Tee haku {{var0}} ..." ,
context _view : "Näytä {{var0}}" ,
2020-12-21 19:56:36 +01:00
submenu _disabled : "Kaikki vammaiset" ,
2021-02-09 14:51:23 +01:00
toast _copy _failed : "Kohdetta {{var0}} ei voitu kopioida leikepöydälle" ,
toast _copy _success : "{{var0}} kopioitiin leikepöydälle" ,
toast _save _failed : "Kohdetta {{var0}} ei voitu tallentaa kansioon '{{var1}}'" ,
toast _save _success : "{{var0}} tallennettiin kansioon '{{var1}}'"
2020-12-21 19:56:36 +01:00
} ;
case "fr" : // French
return {
2021-02-09 14:51:23 +01:00
context _copy : "Copier {{var0}}" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "Taille de l'objectif" ,
2021-02-09 14:51:23 +01:00
context _saveas : "Enregistrer {{var0}} sous ..." ,
context _searchwith : "Rechercher {{var0}} avec ..." ,
context _view : "Afficher {{var0}}" ,
2020-12-21 19:56:36 +01:00
submenu _disabled : "Tout désactivé" ,
2021-02-09 14:51:23 +01:00
toast _copy _failed : "{{var0}} n'a pas pu être copié dans le presse-papiers" ,
toast _copy _success : "{{var0}} a été copié dans le presse-papiers" ,
toast _save _failed : "{{var0}} n'a pas pu être enregistré dans '{{var1}}'" ,
toast _save _success : "{{var0}} a été enregistré dans '{{var1}}'"
2020-12-21 19:56:36 +01:00
} ;
2021-07-08 16:59:41 +02:00
case "hi" : // Hindi
return {
context _copy : "कॉपी {{var0}}" ,
context _lenssize : "लेंस का आकार" ,
context _saveas : "{{var0}} को इस रूप में सेव करें..." ,
context _searchwith : "इसके साथ {{var0}} खोजें ..." ,
context _view : "देखें {{var0}}" ,
submenu _disabled : "सभी अक्षम" ,
toast _copy _failed : "{{var0}} को क्लिपबोर्ड पर कॉपी नहीं किया जा सका" ,
toast _copy _success : "{{var0}} को क्लिपबोर्ड पर कॉपी किया गया था" ,
toast _save _failed : "{{var0}} '{{var1}}' में सहेजा नहीं जा सका" ,
toast _save _success : "{{var0}} '{{var1}}' में सहेजा गया था"
} ;
2020-12-21 19:56:36 +01:00
case "hr" : // Croatian
return {
2021-02-09 14:51:23 +01:00
context _copy : "Kopiraj {{var0}}" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "Veličina leće" ,
2021-02-09 14:51:23 +01:00
context _saveas : "Spremi {{var0}} kao ..." ,
context _searchwith : "Traži {{var0}} sa ..." ,
context _view : "Pogledajte {{var0}}" ,
2020-12-21 19:56:36 +01:00
submenu _disabled : "Svi invalidi" ,
2021-02-09 14:51:23 +01:00
toast _copy _failed : "{{var0}} nije moguće kopirati u međuspremnik" ,
toast _copy _success : "{{var0}} je kopirano u međuspremnik" ,
toast _save _failed : "{{var0}} nije moguće spremiti u '{{var1}}'" ,
toast _save _success : "{{var0}} spremljeno je u '{{var1}}'"
2020-12-21 19:56:36 +01:00
} ;
case "hu" : // Hungarian
return {
2021-02-09 14:51:23 +01:00
context _copy : "{{var0}} másolása" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "Lencse mérete" ,
2021-02-09 14:51:23 +01:00
context _saveas : "{{var0}} mentése másként ..." ,
context _searchwith : "Keresés a következőben: {{var0}} a következővel:" ,
context _view : "Megtekintés: {{var0}}" ,
2020-12-21 19:56:36 +01:00
submenu _disabled : "Minden fogyatékkal él" ,
2021-02-09 14:51:23 +01:00
toast _copy _failed : "A {{var0}} fájl nem másolható a vágólapra" ,
toast _copy _success : "A {{var0}} elemet a vágólapra másolta" ,
toast _save _failed : "A {{var0}} fájl mentése nem sikerült a '{{var1}}' mappába" ,
toast _save _success : "{{var0}} mentve a '{{var1}}' mappába"
2020-12-21 19:56:36 +01:00
} ;
case "it" : // Italian
return {
2021-02-09 14:51:23 +01:00
context _copy : "Copia {{var0}}" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "Dimensione della lente" ,
2021-02-09 14:51:23 +01:00
context _saveas : "Salva {{var0}} come ..." ,
context _searchwith : "Cerca {{var0}} con ..." ,
context _view : "Visualizza {{var0}}" ,
2020-12-21 19:56:36 +01:00
submenu _disabled : "Tutti disabilitati" ,
2021-02-09 14:51:23 +01:00
toast _copy _failed : "{{var0}} non può essere copiato negli appunti" ,
toast _copy _success : "{{var0}} è stato copiato negli appunti" ,
toast _save _failed : "Impossibile salvare {{var0}} in '{{var1}}'" ,
toast _save _success : "{{var0}} è stato salvato in '{{var1}}'"
2020-12-21 19:56:36 +01:00
} ;
case "ja" : // Japanese
return {
2021-02-09 14:51:23 +01:00
context _copy : "{{var0}} をコピーします" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "レンズサイズ" ,
2021-02-09 14:51:23 +01:00
context _saveas : "{{var0}} を...として保存します" ,
context _searchwith : "{{var0}} を...で検索" ,
context _view : "{{var0}} を表示" ,
2020-12-21 19:56:36 +01:00
submenu _disabled : "すべて無効" ,
2021-02-09 14:51:23 +01:00
toast _copy _failed : "{{var0}} をクリップボードにコピーできませんでした" ,
toast _copy _success : "{{var0}} がクリップボードにコピーされました" ,
toast _save _failed : "{{var0}} を「'{{var1}}'」に保存できませんでした" ,
toast _save _success : "{{var0}} は「'{{var1}}'」に保存されました"
2020-12-21 19:56:36 +01:00
} ;
case "ko" : // Korean
return {
2021-02-09 14:51:23 +01:00
context _copy : "{{var0}} 복사" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "렌즈 크기" ,
2021-02-09 14:51:23 +01:00
context _saveas : "{{var0}} 을 다른 이름으로 저장 ..." ,
context _searchwith : "{{var0}} 검색 ..." ,
context _view : "{{var0}} 보기" ,
2020-12-21 19:56:36 +01:00
submenu _disabled : "모두 비활성화 됨" ,
2021-02-09 14:51:23 +01:00
toast _copy _failed : "{{var0}} 을 클립 보드에 복사 할 수 없습니다." ,
toast _copy _success : "{{var0}} 이 클립 보드에 복사되었습니다." ,
toast _save _failed : "{{var0}} 을 '{{var1}}'에 저장할 수 없습니다." ,
toast _save _success : "{{var0}} 이 '{{var1}}'에 저장되었습니다."
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "lt" : // Lithuanian
2020-09-19 20:49:33 +02:00
return {
2021-02-09 14:51:23 +01:00
context _copy : "Kopijuoti {{var0}}" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "Objektyvo dydis" ,
2021-02-09 14:51:23 +01:00
context _saveas : "Išsaugoti '{{var0}}' kaip ..." ,
context _searchwith : "Ieškoti {{var0}} naudojant ..." ,
context _view : "Žiūrėti {{var0}}" ,
2020-12-21 19:56:36 +01:00
submenu _disabled : "Visi neįgalūs" ,
2021-02-09 14:51:23 +01:00
toast _copy _failed : "{{var0}} nepavyko nukopijuoti į mainų sritį" ,
toast _copy _success : "{{var0}} buvo nukopijuota į mainų sritį" ,
toast _save _failed : "Nepavyko išsaugoti {{var0}} aplanke '{{var1}}'" ,
toast _save _success : "{{var0}} išsaugotas aplanke '{{var1}}'"
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "nl" : // Dutch
2020-09-19 20:49:33 +02:00
return {
2021-02-09 14:51:23 +01:00
context _copy : "Kopieer {{var0}}" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "Lens Maat" ,
2021-02-09 14:51:23 +01:00
context _saveas : "Bewaar {{var0}} als ..." ,
context _searchwith : "Zoek {{var0}} met ..." ,
context _view : "Bekijk {{var0}}" ,
2020-12-21 19:56:36 +01:00
submenu _disabled : "Allemaal uitgeschakeld" ,
2021-02-09 14:51:23 +01:00
toast _copy _failed : "{{var0}} kan niet naar het klembord worden gekopieerd" ,
toast _copy _success : "{{var0}} is naar het klembord gekopieerd" ,
toast _save _failed : "{{var0}} kan niet worden opgeslagen in '{{var1}}'" ,
toast _save _success : "{{var0}} is opgeslagen in '{{var1}}'"
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "no" : // Norwegian
2020-09-19 20:49:33 +02:00
return {
2021-02-09 14:51:23 +01:00
context _copy : "Kopier {{var0}}" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "Linsestørrelse" ,
2021-02-09 14:51:23 +01:00
context _saveas : "Lagre {{var0}} som ..." ,
context _searchwith : "Søk på {{var0}} med ..." ,
context _view : "Vis {{var0}}" ,
2020-12-21 19:56:36 +01:00
submenu _disabled : "Alle funksjonshemmede" ,
2021-02-09 14:51:23 +01:00
toast _copy _failed : "{{var0}} kunne ikke kopieres til utklippstavlen" ,
toast _copy _success : "{{var0}} ble kopiert til utklippstavlen" ,
toast _save _failed : "{{var0}} kunne ikke lagres i '{{var1}}'" ,
toast _save _success : "{{var0}} ble lagret i '{{var1}}'"
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "pl" : // Polish
2020-09-19 20:49:33 +02:00
return {
2021-02-09 14:51:23 +01:00
context _copy : "Kopiuj {{var0}}" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "Rozmiar soczewki" ,
2021-02-09 14:51:23 +01:00
context _saveas : "Zapisz {{var0}} jako ..." ,
context _searchwith : "Wyszukaj {{var0}} za pomocą ..." ,
context _view : "Wyświetl {{var0}}" ,
2020-12-21 19:56:36 +01:00
submenu _disabled : "Wszystkie wyłączone" ,
2021-02-09 14:51:23 +01:00
toast _copy _failed : "Nie można skopiować {{var0}} do schowka" ,
toast _copy _success : "{{var0}} został skopiowany do schowka" ,
toast _save _failed : "Nie można zapisać {{var0}} w '{{var1}}'" ,
toast _save _success : "{{var0}} został zapisany w '{{var1}}'"
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "pt-BR" : // Portuguese (Brazil)
2020-09-19 20:49:33 +02:00
return {
2021-02-09 14:51:23 +01:00
context _copy : "Copiar {{var0}}" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "Tamanho da lente" ,
2021-02-09 14:51:23 +01:00
context _saveas : "Salve {{var0}} como ..." ,
context _searchwith : "Pesquise {{var0}} com ..." ,
context _view : "Veja {{var0}}" ,
2020-12-21 19:56:36 +01:00
submenu _disabled : "Todos desativados" ,
2021-02-09 14:51:23 +01:00
toast _copy _failed : "{{var0}} não pôde ser copiado para a área de transferência" ,
toast _copy _success : "{{var0}} foi copiado para a área de transferência" ,
toast _save _failed : "{{var0}} não pôde ser salvo em '{{var1}}'" ,
toast _save _success : "{{var0}} foi salvo em '{{var1}}'"
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "ro" : // Romanian
2020-09-19 20:49:33 +02:00
return {
2021-02-09 14:51:23 +01:00
context _copy : "Copiați {{var0}}" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "Dimensiunea obiectivului" ,
2021-02-09 14:51:23 +01:00
context _saveas : "Salvați {{var0}} ca ..." ,
context _searchwith : "Căutați {{var0}} cu ..." ,
context _view : "Vizualizați {{var0}}" ,
2020-12-21 19:56:36 +01:00
submenu _disabled : "Toate sunt dezactivate" ,
2021-02-09 14:51:23 +01:00
toast _copy _failed : "{{var0}} nu a putut fi copiat în clipboard" ,
toast _copy _success : "{{var0}} a fost copiat în clipboard" ,
toast _save _failed : "{{var0}} nu a putut fi salvat în '{{var1}}'" ,
toast _save _success : "{{var0}} a fost salvat în '{{var1}}'"
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "ru" : // Russian
2020-09-19 20:49:33 +02:00
return {
2021-02-09 14:51:23 +01:00
context _copy : "Скопируйте {{var0}}" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "Размер линзы" ,
2021-02-09 14:51:23 +01:00
context _saveas : "Сохранить {{var0}} как ..." ,
context _searchwith : "Искать {{var0}} с помощью ..." ,
context _view : "Посмотреть {{var0}}" ,
2020-12-21 19:56:36 +01:00
submenu _disabled : "В с е отключены" ,
2021-02-09 14:51:23 +01:00
toast _copy _failed : "{{var0}} не удалось скопировать в буфер обмена" ,
toast _copy _success : "{{var0}} скопирован в буфер обмена" ,
toast _save _failed : "{{var0}} не удалось сохранить в '{{var1}}'" ,
toast _save _success : "{{var0}} был сохранен в '{{var1}}'"
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "sv" : // Swedish
2020-09-19 20:49:33 +02:00
return {
2021-02-09 14:51:23 +01:00
context _copy : "Kopiera {{var0}}" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "Linsstorlek" ,
2021-02-09 14:51:23 +01:00
context _saveas : "Spara {{var0}} som ..." ,
context _searchwith : "Sök {{var0}} med ..." ,
context _view : "Visa {{var0}}" ,
2020-12-21 19:56:36 +01:00
submenu _disabled : "Alla funktionshindrade" ,
2021-02-09 14:51:23 +01:00
toast _copy _failed : "{{var0}} kunde inte kopieras till Urklipp" ,
toast _copy _success : "{{var0}} kopierades till Urklipp" ,
toast _save _failed : "{{var0}} kunde inte sparas i '{{var1}}'" ,
toast _save _success : "{{var0}} sparades i '{{var1}}'"
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "th" : // Thai
2020-09-19 20:49:33 +02:00
return {
2021-02-22 20:52:51 +01:00
context _copy : "คัดลอก{{var0}}" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "ขนาดเลนส์" ,
2021-02-22 20:52:51 +01:00
context _saveas : "บันทึก{{var0}}เป็น ..." ,
context _searchwith : "ค้นหา{{var0}} ้วย ..." ,
context _view : "ดู{{var0}}" ,
2020-12-21 19:56:36 +01:00
submenu _disabled : "ปิดใช้งานทั้งหมด" ,
2021-02-22 20:52:51 +01:00
toast _copy _failed : "ไม่สามารถคัดลอก{{var0}}ไปยังคลิปบอร์ดได้" ,
toast _copy _success : "คัดลอก{{var0}}ไปยังคลิปบอร์ดแล้ว" ,
toast _save _failed : "ไม่สามารถบันทึก{{var0}}ใน '{{var1}}'" ,
toast _save _success : "{{var0}} ูกบันทึกใน '{{var1}}'"
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "tr" : // Turkish
2020-09-19 20:49:33 +02:00
return {
2021-02-09 14:51:23 +01:00
context _copy : "{{var0}} kopyala" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "Lens Boyutu" ,
2021-02-09 14:51:23 +01:00
context _saveas : "{{var0}} farklı kaydet ..." ,
context _searchwith : "{{var0}} şununla ara ..." ,
context _view : "{{var0}} görüntüle" ,
2020-12-21 19:56:36 +01:00
submenu _disabled : "Hepsi devre dı şı " ,
2021-02-09 14:51:23 +01:00
toast _copy _failed : "{{var0}} panoya kopyalanamadı " ,
toast _copy _success : "{{var0}} panoya kopyalandı " ,
toast _save _failed : "{{var0}}, '{{var1}}' konumuna kaydedilemedi" ,
toast _save _success : "{{var0}}, '{{var1}}' konumuna kaydedildi"
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "uk" : // Ukrainian
2020-09-19 20:49:33 +02:00
return {
2021-02-09 14:51:23 +01:00
context _copy : "Копіювати {{var0}}" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "Розмір лінзи" ,
2021-02-09 14:51:23 +01:00
context _saveas : "Збережіть {{var0}} як ..." ,
context _searchwith : "Шукати {{var0}} за допомогою ..." ,
context _view : "Переглянути {{var0}}" ,
2020-12-21 19:56:36 +01:00
submenu _disabled : "В с і інваліди" ,
2021-02-09 14:51:23 +01:00
toast _copy _failed : "Н е вдалося скопіювати {{var0}} у буфер обміну" ,
toast _copy _success : "{{var0}} скопійовано в буфер обміну" ,
toast _save _failed : "Н е вдалося зберегти {{var0}} у '{{var1}}'" ,
toast _save _success : "{{var0}} було збережено у '{{var1}}'"
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "vi" : // Vietnamese
2020-09-19 20:49:33 +02:00
return {
2021-02-09 14:51:23 +01:00
context _copy : "Sao chép {{var0}}" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "Kích thước ống kính" ,
2021-02-09 14:51:23 +01:00
context _saveas : "Lưu {{var0}} dưới dạng ..." ,
context _searchwith : "Tìm kiếm {{var0}} bằng ..." ,
context _view : "Xem {{var0}}" ,
2020-12-21 19:56:36 +01:00
submenu _disabled : "Tất cả đã bị vô hiệu hóa" ,
2021-02-09 14:51:23 +01:00
toast _copy _failed : "Không thể sao chép {{var0}} vào khay nhớ tạm" ,
toast _copy _success : "{{var0}} đã được sao chép vào khay nhớ tạm" ,
toast _save _failed : "Không thể lưu {{var0}} trong '{{var1}}'" ,
toast _save _success : "{{var0}} đã được lưu trong '{{var1}}'"
2020-09-19 20:49:33 +02:00
} ;
2021-01-15 17:54:22 +01:00
case "zh-CN" : // Chinese (China)
2020-09-19 20:49:33 +02:00
return {
2021-02-09 14:51:23 +01:00
context _copy : "复制 {{var0}}" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "镜片尺寸" ,
2021-02-09 14:51:23 +01:00
context _saveas : "将 {{var0}} 另存为 ..." ,
context _searchwith : "用搜索 {{var0}} ..." ,
context _view : "查看 {{var0}}" ,
2020-12-21 19:56:36 +01:00
submenu _disabled : "全部禁用" ,
2021-02-09 14:51:23 +01:00
toast _copy _failed : "{{var0}} 无法复制到剪贴板" ,
toast _copy _success : "{{var0}} 已复制到剪贴板" ,
toast _save _failed : "{{var0}} 无法保存在'{{var1}}'中" ,
toast _save _success : "{{var0}} 已保存在'{{var1}}'中"
2020-09-19 20:49:33 +02:00
} ;
2021-01-15 17:54:22 +01:00
case "zh-TW" : // Chinese (Taiwan)
2020-09-19 20:49:33 +02:00
return {
2021-02-09 14:51:23 +01:00
context _copy : "複製 {{var0}}" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "鏡片尺寸" ,
2021-02-09 14:51:23 +01:00
context _saveas : "將 {{var0}} 另存為 ..." ,
context _searchwith : "用搜索 {{var0}} ..." ,
context _view : "查看 {{var0}}" ,
2020-12-21 19:56:36 +01:00
submenu _disabled : "全部禁用" ,
2021-02-09 14:51:23 +01:00
toast _copy _failed : "{{var0}} 無法複製到剪貼板" ,
toast _copy _success : "{{var0}} 已復製到剪貼板" ,
toast _save _failed : "{{var0}} 無法保存在'{{var1}}'中" ,
toast _save _success : "{{var0}} 已保存在'{{var1}}'中"
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
default : // English
2020-09-19 20:49:33 +02:00
return {
2021-02-09 14:51:23 +01:00
context _copy : "Copy {{var0}}" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "Lens Size" ,
2021-02-09 14:51:23 +01:00
context _saveas : "Save {{var0}} as ..." ,
context _searchwith : "Search {{var0}} with ..." ,
context _view : "View {{var0}}" ,
2020-12-21 19:56:36 +01:00
submenu _disabled : "All disabled" ,
2021-02-09 14:51:23 +01:00
toast _copy _failed : "{{var0}} could not be copied to the Clipboard" ,
toast _copy _success : "{{var0}} was copied to the Clipboard" ,
toast _save _failed : "{{var0}} could not be saved in '{{var1}}'" ,
toast _save _success : "{{var0}} was saved in '{{var1}}'"
2020-09-19 20:49:33 +02:00
} ;
}
}
} ;
2020-10-09 21:09:35 +02:00
} ) ( window . BDFDB _Global . PluginUtils . buildPlugin ( config ) ) ;
2021-03-02 14:23:42 +01:00
} ) ( ) ;