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
2023-11-04 10:33:32 +01:00
* @ version 5.3 . 3
2022-03-03 07:47: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 = ( _ => {
2022-09-01 14:40:11 +02:00
const changeLog = {
2023-09-05 12:38:07 +02:00
2020-09-19 20:49:33 +02:00
} ;
2020-10-15 20:10:00 +02:00
2022-02-05 21:14:17 +01:00
return ! window . BDFDB _Global || ( ! window . BDFDB _Global . loaded && ! window . BDFDB _Global . started ) ? class {
2022-09-01 14:55:22 +02:00
constructor ( meta ) { for ( let key in meta ) this [ key ] = meta [ key ] ; }
getName ( ) { return this . name ; }
getAuthor ( ) { return this . author ; }
getVersion ( ) { return this . version ; }
getDescription ( ) { return ` The Library Plugin needed for ${ this . name } is missing. Open the Plugin Settings to download it. \n \n ${ this . description } ` ; }
2021-02-01 17:13:13 +01:00
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 ;
2022-09-01 14:55:22 +02:00
BdApi . showConfirmationModal ( "Library Missing" , ` The Library Plugin needed for ${ this . 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
} ) ;
}
2022-09-01 14:55:22 +02:00
if ( ! window . BDFDB _Global . pluginQueue . includes ( this . name ) ) window . BDFDB _Global . pluginQueue . push ( this . 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" ) ;
2022-09-01 14:55:22 +02: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 ${ this . 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 ] ) => {
2022-02-25 17:47:56 +01:00
var _this ;
2022-03-19 19:01:43 +01:00
var firedEvents = [ ] ;
2021-04-24 22:28:41 +02:00
var ownLocations = { } , downloadsFolder ;
2020-09-19 20:49:33 +02:00
2022-03-19 19:01:43 +01:00
var firstViewedImage , viewedImage , viewedImageTimeout ;
2023-01-22 20:08:42 +01:00
var switchedImageProps ;
2022-03-19 19:01:43 +01:00
var cachedImages ;
var eventTypes = { } ;
2021-02-09 14:51:23 +01:00
const imgUrlReplaceString = "DEVILBRO_BD_REVERSEIMAGESEARCH_REPLACE_IMAGEURL" ;
2021-07-07 14:39:01 +02:00
2022-06-24 17:25:57 +02:00
const rescaleOptions = {
2022-06-23 20:08:50 +02:00
NONE : "No Resize" ,
2022-06-24 17:25:57 +02:00
ORIGINAL : "Resize to Original Size" ,
2022-06-23 20:08:50 +02:00
WINDOW : "Resize to Window Size"
} ;
2021-02-09 14:51:23 +01:00
const fileTypes = {
2023-03-20 11:27:46 +01:00
"3gp" : { copyable : false , searchable : false , gif : false , video : true , signs : [ [ 0x66 , 0x74 , 0x79 , 0x70 , 0x33 , 0x67 ] ] } ,
"avi" : { copyable : false , searchable : false , gif : false , video : true , signs : [ [ 0x41 , 0x56 , 0x49 , 0x20 ] ] } ,
"flv" : { copyable : false , searchable : false , gif : false , video : true , signs : [ [ 0x46 , 0x4C , 0x56 ] ] } ,
"jpeg" : { copyable : true , searchable : true , gif : false , video : false , signs : [ [ 0xFF , 0xD8 , 0xFF , 0xEE ] ] } ,
"jpg" : { copyable : true , searchable : true , gif : false , video : false , signs : [ [ 0xFF , 0xD8 , 0xFF , 0xDB ] , [ 0xFF , 0xD8 , 0xFF , 0xE0 ] , [ 0xFF , 0xD8 , 0xFF , 0xE1 ] ] } ,
"gif" : { copyable : false , searchable : true , gif : true , video : false , signs : [ [ 0x47 , 0x49 , 0x46 , 0x38 , 0x37 , 0x61 ] , [ 0x47 , 0x49 , 0x46 , 0x38 , 0x39 , 0x61 ] ] } ,
"mov" : { copyable : false , searchable : false , gif : false , video : true , signs : [ [ null , null , null , null , 0x6D , 0x6F , 0x6F , 0x76 ] , [ null , null , null , null , 0x66 , 0x74 , 0x79 , 0x70 , 0x71 , 0x74 , 0x20 , 0x20 ] ] } ,
"mp4" : { copyable : false , searchable : false , gif : false , video : true , signs : [ [ null , null , null , null , 0x66 , 0x74 , 0x79 , 0x70 ] ] } ,
"mpeg-1" : { copyable : false , searchable : false , gif : false , video : true , signs : [ [ 0x00 , 0x00 , 0x01 , 0xBA ] ] } ,
"mpeg-2" : { copyable : false , searchable : false , gif : false , video : true , signs : [ [ 0x00 , 0x00 , 0x01 , 0xB3 ] ] } ,
"ogg" : { copyable : false , searchable : false , gif : false , video : true , signs : [ [ 0x4F , 0x67 , 0x67 , 0x53 ] ] } ,
"png" : { copyable : true , searchable : true , gif : false , video : false , signs : [ [ 0x89 , 0x50 , 0x4E , 0x47 , 0x0D , 0x0A , 0x1A , 0x0A ] ] } ,
"svg" : { copyable : false , searchable : false , gif : false , video : false , signs : [ [ 0x3C ] ] } ,
"webm" : { copyable : false , searchable : false , gif : false , video : true , signs : [ [ 0x1A , 0x45 , 0xDF , 0xA3 ] ] } ,
"webp" : { copyable : false , searchable : true , gif : false , video : false , signs : [ [ 0x52 , 0x49 , 0x46 , 0x46 , null , null , null , null , 0x57 , 0x45 , 0x42 , 0x50 ] ] } ,
"wmv" : { copyable : false , searchable : false , gif : false , video : true , signs : [ [ 0x30 , 0x26 , 0xB2 , 0x75 , 0x8E , 0x66 , 0xCF , 0x11 ] , [ 0xA6 , 0xD9 , 0x00 , 0xAA , 0x00 , 0x62 , 0xCE , 0x6C ] ] }
2021-02-09 14:51:23 +01:00
} ;
2022-03-19 19:01:43 +01:00
const LazyImageSiblingComponent = class LazyImageSibling extends BdApi . React . Component {
render ( ) {
if ( ! this . props . loadedImage ) {
2022-12-15 14:56:39 +01:00
const instance = this ;
2022-03-19 19:01:43 +01:00
const imageThrowaway = document . createElement ( "img" ) ;
imageThrowaway . addEventListener ( "load" , function ( ) {
let aRects = BDFDB . DOMUtils . getRects ( document . querySelector ( BDFDB . dotCN . appmount ) ) ;
let resizeX = ( aRects . width / this . width ) * 0.8 , resizeY = ( aRects . height / this . height ) * 0.65
let ratio = resizeX < resizeY ? resizeX : resizeY ;
2022-12-15 14:56:39 +01:00
instance . props . loadedImage = BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . LazyImage , {
2022-03-19 19:01:43 +01:00
src : imageThrowaway . src ,
width : this . width ,
height : this . height ,
maxWidth : this . width * ratio ,
maxHeight : this . height * ratio
} ) ;
2022-12-15 14:56:39 +01:00
BDFDB . ReactUtils . forceUpdate ( instance ) ;
2022-03-19 19:01:43 +01:00
} ) ;
2022-12-15 14:56:39 +01:00
imageThrowaway . src = ! _this . isValid ( this . props . url , "video" ) ? this . props . url : _this . getPosterUrl ( this . props . url ) ;
2022-03-19 19:01:43 +01:00
}
return BDFDB . ReactUtils . createElement ( "div" , {
className : BDFDB . DOMUtils . formatClassName ( BDFDB . disCN . _imageutilitiessibling , this . props . className ) ,
2022-07-24 13:56:12 +02:00
onClick : event => {
BDFDB . ListenerUtils . stopEvent ( event ) ;
2023-03-20 11:27:46 +01:00
_this . switchImages ( this . props . offset , _this . isValid ( this . props . url , "video" ) ) ;
2022-07-24 13:56:12 +02:00
} ,
2022-03-19 19:01:43 +01:00
children : [
2022-10-02 16:49:10 +02:00
this . props . loadedImage || BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SpinnerComponents . Spinner , {
2023-02-15 19:22:09 +01:00
type : BDFDB . LibraryComponents . SpinnerComponents . Types . WANDERING _CUBES
2022-03-19 19:01:43 +01:00
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SvgIcon , {
className : BDFDB . disCNS . _imageutilitiesswitchicon + BDFDB . disCN . svgicon ,
name : this . props . svgIcon
} )
]
} ) ;
}
} ;
2021-10-26 17:13:45 +02:00
const ImageDetailsComponent = class ImageDetails extends BdApi . React . Component {
2021-01-20 16:00:29 +01:00
componentDidMount ( ) {
2023-03-06 21:34:32 +01:00
BDFDB . DOMUtils . addClass ( BDFDB . DOMUtils . getParent ( BDFDB . dotCN . imagemosaiconebyonegridsingle , BDFDB . ReactUtils . findDOMNode ( this ) ) , BDFDB . disCN . _imageutilitiesimagedetailsadded ) ;
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 ( ) {
2022-02-25 17:47:56 +01:00
return ! this . props . attachment ? null : BDFDB . ReactUtils . createElement ( "span" , {
2020-09-19 20:49:33 +02:00
className : BDFDB . disCN . _imageutilitiesimagedetails ,
children : [
2022-02-25 17:47:56 +01:00
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 ( "span" , {
children : BDFDB . NumberUtils . formatBytes ( this . props . attachment . size )
} ) ,
BDFDB . ReactUtils . createElement ( "span" , {
children : ` ${ this . props . attachment . width } x ${ this . props . attachment . height } px `
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TooltipContainer , {
text : BDFDB . LanguageUtils . LibraryStrings . download ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SvgIcon , {
className : BDFDB . disCN . cursorpointer ,
name : BDFDB . LibraryComponents . SvgIcon . Names . DOWNLOAD ,
width : 16 ,
height : 16 ,
2020-09-19 20:49:33 +02:00
onClick : event => {
BDFDB . ListenerUtils . stopEvent ( event ) ;
2022-12-16 11:40:29 +01:00
_this . downloadFile ( { url : this . props . attachment . proxy _url || this . props . original } ) ;
2022-02-25 17:47:56 +01:00
} ,
onContextMenu : event => {
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 , {
children : locations . map ( ( name , i ) => BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuItem , {
id : BDFDB . ContextMenuUtils . createItemId ( _this . name , "download" , name , i ) ,
label : name ,
2022-12-16 11:40:29 +01:00
action : _ => _this . downloadFile ( { url : this . props . attachment . proxy _url || this . props . original } , ownLocations [ name ] . location )
2022-02-25 17:47:56 +01:00
} ) )
} ) ) ;
2020-09-19 20:49:33 +02:00
}
} )
} )
]
} ) ;
}
} ;
2020-10-09 21:09:35 +02:00
return class ImageUtilities extends Plugin {
2021-01-06 12:38:36 +01:00
onLoad ( ) {
2022-02-25 17:47:56 +01:00
_this = this ;
2020-09-19 20:49:33 +02:00
firedEvents = [ ] ;
2022-03-19 19:01:43 +01:00
firstViewedImage = null ;
viewedImage = null ;
cachedImages = null ;
2021-07-07 14:39:01 +02:00
2020-09-19 20:49:33 +02:00
this . defaults = {
2022-06-22 15:34:42 +02:00
general : {
2022-09-22 19:41:02 +02:00
nsfwMode : { value : false , description : "Blurs Media that is posted in NSFW Channels" }
2022-06-22 15:34:42 +02:00
} ,
2022-03-14 18:22:45 +01:00
viewerSettings : {
2022-09-22 19:41:02 +02:00
zoomMode : { value : true , description : "Enables Zoom Mode to zoom into Images while holding down your Mouse" } ,
galleryMode : { value : true , description : "Enables Gallery Mode to quick-switch between Images" } ,
details : { value : true , description : "Adds Image Details (Name, Size, Amount)" } ,
copyImage : { value : true , description : "Adds a 'Copy Image' Option" } ,
saveImage : { value : true , description : "Adds a 'Save Image as' Option" } ,
jumpTo : { value : true , description : "Adds a 'Jump to Message' Option in Gallery Mode" }
2021-04-24 22:28:41 +02:00
} ,
2022-12-01 20:44:25 +01:00
galleryFilter : { } ,
2022-03-14 18:22:45 +01:00
zoomSettings : {
2022-09-22 19:41:02 +02:00
pixelMode : { value : false , label : "Uses Pixel Lens instead of a Blur Lens" } ,
2023-06-22 16:33:20 +02:00
clickMode : { value : false , label : "Click Image to zoom instead of holding the Mouse Button" } ,
2023-02-20 09:15:40 +01:00
lensSize : { value : 200 , digits : 0 , minValue : 50 , maxValue : 5000 , unit : "px" , label : "context_lenssize" } ,
2022-03-14 18:22:45 +01:00
zoomLevel : { value : 2 , digits : 1 , minValue : 1 , maxValue : 20 , unit : "x" , label : "ACCESSIBILITY_ZOOM_LEVEL_LABEL" } ,
2023-02-20 09:15:40 +01:00
zoomSpeed : { value : 0.1 , digits : 2 , minValue : 0.01 , maxValue : 1 , unit : "" , label : "context_zoomspeed" }
2020-09-19 20:49:33 +02:00
} ,
2022-06-24 17:25:57 +02:00
rescaleSettings : {
2022-06-23 20:08:50 +02:00
messages : { value : "NONE" , description : "Messages" } ,
imageViewer : { value : "NONE" , description : "Image Viewer" }
2020-09-19 20:49:33 +02:00
} ,
2022-03-14 18:22:45 +01:00
detailsSettings : {
footnote : { value : true , description : "in the Image Description" } ,
tooltip : { value : false , description : "as a Hover Tooltip" } ,
tooltipDelay : { value : 0 , min : 0 , description : "Image Tooltip Delay (in ms)" }
} ,
places : {
userAvatars : { value : true , description : "User Avatars" } ,
groupIcons : { value : true , description : "Group Icons" } ,
guildIcons : { value : true , description : "Server Icons" } ,
2023-03-31 16:35:45 +02:00
streamPreviews : { value : true , description : "Stream Previews" } ,
2022-03-14 18:22:45 +01:00
emojis : { value : true , description : "Custom Emojis/Emotes" }
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 } ,
2023-03-20 11:27:46 +01:00
Baidu : { value : true , name : "Baidu" , url : "http://image.baidu.com/pcdutu?queryImageUrl=" + imgUrlReplaceString } ,
Bing : { value : true , name : "Bing" , url : "https://www.bing.com/images/search?q=imgurl:" + imgUrlReplaceString + "&view=detailv2&iss=sbi&FORM=IRSBIQ" } ,
2023-09-05 12:38:07 +02:00
Google : { value : true , name : "Google" , url : "https://www.google.com/searchbyimage?sbisrc=cr_1&image_url=" + imgUrlReplaceString } ,
2023-03-20 11:27:46 +01:00
GoogleLens : { value : true , name : "Google Lens" , url : "https://lens.google.com/uploadbyurl?url=" + imgUrlReplaceString } ,
ImgOps : { value : true , name : "ImgOps" , raw : true , url : "https://imgops.com/specialized+reverse/" + imgUrlReplaceString } ,
IQDB : { value : true , name : "IQDB" , url : "https://iqdb.org/?url=" + imgUrlReplaceString } ,
Reddit : { value : true , name : "Reddit" , url : "http://karmadecay.com/search?q=" + imgUrlReplaceString } ,
SauceNAO : { value : true , name : "SauceNAO" , url : "https://saucenao.com/search.php?db=999&url=" + imgUrlReplaceString } ,
Sogou : { value : true , name : "Sogou" , url : "http://pic.sogou.com/ris?flag=1&drag=0&query=" + imgUrlReplaceString + "&flag=1" } ,
TinEye : { value : true , name : "TinEye" , url : "https://tineye.com/search?url=" + imgUrlReplaceString } ,
WhatAnime : { value : true , name : "WhatAnime" , url : "https://trace.moe/?url=" + imgUrlReplaceString } ,
Yandex : { value : true , name : "Yandex" , url : "https://yandex.com/images/search?url=" + imgUrlReplaceString + "&rpt=imageview" }
2020-09-19 20:49:33 +02:00
}
} ;
2022-12-01 20:44:25 +01:00
for ( let fileType in fileTypes ) this . defaults . galleryFilter [ fileType ] = { value : true } ;
2020-08-14 14:37:10 +02:00
2022-10-13 12:20:55 +02:00
this . modulePatches = {
before : [
2023-01-22 20:08:42 +01:00
"ImageModal" ,
2023-03-20 11:27:46 +01:00
"ImageVideoModal" ,
2022-10-13 12:20:55 +02:00
"MessageAccessories" ,
"Spoiler"
] ,
after : [
"ImageModal" ,
2023-03-20 11:27:46 +01:00
"ImageVideoModal" ,
2022-10-13 12:20:55 +02:00
"LazyImage" ,
"LazyImageZoomable" ,
"ModalCarousel" ,
"Spoiler" ,
2022-12-01 20:44:25 +01:00
"UserBanner"
2022-10-13 12:20:55 +02:00
] ,
componentDidMount : [
2023-01-22 20:08:42 +01:00
"LazyImage"
2022-10-13 12:20:55 +02:00
] ,
componentDidUpdate : [
"LazyImage"
] ,
componentWillUnmount : [
2023-01-22 20:08:42 +01:00
"LazyImage"
2022-10-13 12:20:55 +02:00
]
2020-09-19 20:49:33 +02:00
} ;
this . css = `
2023-03-30 16:45:02 +02:00
$ { BDFDB . dotCN . _imageutilitiesimagedetailsadded } {
max - height : unset ! important ;
}
2023-02-08 15:02:11 +01:00
$ { BDFDB . dotCNS . _imageutilitiesimagedetailsadded + BDFDB . dotCN . imagewrapper } {
2023-03-20 13:40:11 +01:00
border - radius : 8 px ! important ;
2023-02-06 16:21:17 +01:00
height : calc ( 100 % - 1 rem - 16 px ) ! important ;
max - height : unset ! important ;
2023-05-26 14:40:30 +02:00
margin - left : unset ! important ;
2023-02-06 16:21:17 +01:00
}
$ { BDFDB . dotCNS . _imageutilitiesimagedetailsadded + BDFDB . dotCN . imagealttextcontainer } {
bottom : calc ( 1 rem + 16 px ) ! important ;
}
2022-03-02 00:10:26 +01:00
$ { BDFDB . dotCN . _imageutilitiesimagedetails } {
display : inline - flex ;
2022-10-13 12:20:55 +02:00
font - weight : 500 ;
color : var ( -- text - muted ) ;
font - size : 12 px ;
margin : . 25 rem 0 . 75 rem ;
line - height : 16 px ;
2022-03-02 00:10:26 +01:00
}
2022-03-14 19:02:07 +01:00
$ { BDFDB . dotCNS . spoilerhidden + BDFDB . dotCN . _imageutilitiesimagedetails } {
2022-03-14 19:02:52 +01:00
visibility : hidden ;
2022-03-14 19:02:07 +01:00
}
2022-02-25 17:47:56 +01:00
span + $ { BDFDB . dotCN . _imageutilitiesimagedetails } {
margin - left : 12 px ;
}
$ { BDFDB . dotCN . _imageutilitiesimagedetails } > * {
display : inline - block ;
margin - right : 12 px ;
overflow : hidden ;
text - overflow : ellipsis ;
white - space : nowrap ;
}
$ { BDFDB . dotCN . _imageutilitiesimagedetails } > a {
2022-02-28 21:05:45 +01:00
max - width : 300 px ;
}
span + $ { BDFDB . dotCN . _imageutilitiesimagedetails } > a {
2022-02-25 17:47:56 +01:00
max - width : 200 px ;
2020-09-19 20:49:33 +02:00
}
2022-02-25 17:47:56 +01:00
$ { BDFDB . dotCN . _imageutilitiesimagedetails } > span {
max - width : 100 px ;
2020-09-19 20:49:33 +02:00
}
2023-02-25 14:14:37 +01:00
$ { BDFDB . dotCNS . _imageutilitiesgallery + BDFDB . dotCN . modal } ,
$ { BDFDB . dotCNS . _imageutilitiesdetailsadded + BDFDB . dotCN . modal } {
2020-09-19 20:49:33 +02:00
transform : unset ! important ;
2021-10-01 19:28:35 +02:00
filter : unset ! important ;
backdrop - filter : unset ! important ;
2020-09-19 20:49:33 +02:00
}
2023-02-25 14:14:37 +01:00
$ { BDFDB . dotCN . _imageutilitiesgallery } ~ $ { BDFDB . dotCN . imagemodalnavbutton } {
display : none ;
}
2023-03-20 11:27:46 +01:00
$ { BDFDB . dotCNS . imagemodal + BDFDB . dotCNS . attachment + BDFDB . dotCN . attachmentvideocontrols } ,
$ { BDFDB . dotCNS . imagemodal + BDFDB . dotCN . attachment + BDFDB . dotCNS . attachmentcontrolshidden + BDFDB . dotCN . attachmentvideocontrols } : hover {
bottom : - 10 px ;
transform : unset ! important ;
transition : bottom 0.3 s ease ;
}
$ { BDFDB . dotCNS . imagemodal + BDFDB . dotCN . attachment + BDFDB . dotCNS . attachmentcontrolshidden + BDFDB . dotCN . attachmentvideocontrols } {
bottom : - 42 px ;
}
2022-06-22 15:34:42 +02:00
$ { BDFDB . dotCNS . imagemodal + BDFDB . notCN . _imageutilitiessibling } > $ { BDFDB . dotCN . imagewrapper } {
display : flex ;
justify - content : center ;
align - items : center ;
min - width : 500 px ;
}
2022-07-08 17:29:11 +02:00
$ { BDFDB . dotCNS . imagemodal + BDFDB . notCN . _imageutilitiessibling } > $ { BDFDB . dotCN . imagewrapper } img {
object - fit : contain ;
width : unset ;
}
2022-08-18 08:50:18 +02:00
$ { BDFDB . dotCN . imagemodalnavbutton } {
background : rgba ( 0 , 0 , 0 , 0.3 ) ;
border - radius : 100 % ;
}
$ { BDFDB . dotCN . imagemodalnavbutton } : hover {
background : rgba ( 0 , 0 , 0 , 0.5 ) ;
}
2020-09-19 20:49:33 +02:00
$ { 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 ;
}
2022-03-14 18:22:45 +01:00
$ { BDFDB . dotCNS . _imageutilitiessibling + BDFDB . dotCN . spinner } {
position : absolute ;
2023-02-15 19:22:09 +01:00
width : 32 px ;
2022-03-14 18:22:45 +01:00
}
$ { BDFDB . dotCNS . _imageutilitiesprevious + BDFDB . dotCN . spinner } {
right : 21 px ;
}
$ { BDFDB . dotCNS . _imageutilitiesnext + BDFDB . dotCN . spinner } {
left : 21 px ;
}
2020-09-19 20:49:33 +02:00
$ { 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 } {
2022-03-14 18:22:45 +01:00
display : inline - block ;
width : 80 px ;
2020-09-19 20:49:33 +02:00
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 ( ) {
2023-03-20 11:27:46 +01:00
BDFDB . ListenerUtils . add ( this , document . body , "click" , [ BDFDB . dotCN . imageoriginallink , "img" , BDFDB . dotCN . attachmentcover , BDFDB . dotCN . attachmentcovericon , "video" ] . map ( n => BDFDB . dotCNS . message + BDFDB . dotCNS . imagewrapper + n ) . join ( ", " ) , e => this . cacheClickedImage ( e . target ) ) ;
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 = [ ] ;
2022-06-22 15:34:42 +02:00
settingsItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . CollapseContainer , {
title : "General" ,
collapseStates : collapseStates ,
children : Object . keys ( this . defaults . general ) . map ( key => BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsSaveItem , {
type : "Switch" ,
plugin : this ,
keys : [ "general" , key ] ,
label : this . defaults . general [ key ] . description ,
value : this . settings . general [ key ]
} ) )
} ) ) ;
2020-12-15 15:03:09 +01:00
settingsItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . CollapseContainer , {
2022-03-14 18:22:45 +01:00
title : "Image Viewer Settings" ,
2020-12-15 15:03:09 +01:00
collapseStates : collapseStates ,
2022-03-14 18:22:45 +01:00
children : Object . keys ( this . defaults . viewerSettings ) . map ( key => BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsSaveItem , {
2020-12-15 15:03:09 +01:00
type : "Switch" ,
plugin : this ,
2022-03-14 18:22:45 +01:00
keys : [ "viewerSettings" , key ] ,
label : this . defaults . viewerSettings [ key ] . description ,
value : this . settings . viewerSettings [ key ]
} ) )
} ) ) ;
2022-12-01 20:44:25 +01:00
settingsItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . CollapseContainer , {
title : "Gallery Filter Settings" ,
collapseStates : collapseStates ,
children : Object . keys ( this . defaults . galleryFilter ) . map ( key => BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsSaveItem , {
type : "Switch" ,
plugin : this ,
keys : [ "galleryFilter" , key ] ,
label : key ,
value : this . settings . galleryFilter [ key ]
} ) )
} ) ) ;
2022-03-14 18:22:45 +01:00
settingsItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . CollapseContainer , {
title : "Resize Settings" ,
collapseStates : collapseStates ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsPanelList , {
title : "Automatically Resize Images in: " ,
2022-06-24 17:25:57 +02:00
children : Object . keys ( this . defaults . rescaleSettings ) . map ( key => BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsSaveItem , {
2022-06-23 20:08:50 +02:00
type : "Select" ,
2022-03-14 18:22:45 +01:00
plugin : this ,
2022-06-24 17:25:57 +02:00
keys : [ "rescaleSettings" , key ] ,
label : this . defaults . rescaleSettings [ key ] . description ,
2022-06-23 20:08:50 +02:00
basis : "50%" ,
2022-06-24 17:25:57 +02:00
options : Object . keys ( rescaleOptions ) . map ( n => ( { value : n , label : rescaleOptions [ n ] } ) ) ,
value : this . settings . rescaleSettings [ key ]
2022-03-14 18:22:45 +01:00
} ) )
} )
} ) ) ;
settingsItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . CollapseContainer , {
title : "Image Details Settings" ,
collapseStates : collapseStates ,
children : [ BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsPanelList , {
title : "Show Image Details" ,
children : Object . keys ( this . defaults . detailsSettings ) . filter ( key => typeof this . defaults . detailsSettings [ key ] . value == "boolean" ) . map ( key => BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsSaveItem , {
type : "Switch" ,
plugin : this ,
keys : [ "detailsSettings" , key ] ,
label : this . defaults . detailsSettings [ key ] . description ,
value : this . settings . detailsSettings [ key ]
} ) )
} ) ] . concat ( Object . keys ( this . defaults . detailsSettings ) . filter ( key => typeof this . defaults . detailsSettings [ key ] . value != "boolean" ) . map ( key => BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsSaveItem , {
2020-12-15 15:03:09 +01:00
type : "TextInput" ,
plugin : this ,
2022-03-14 18:22:45 +01:00
keys : [ "detailsSettings" , key ] ,
label : this . defaults . detailsSettings [ key ] . description ,
value : this . settings . detailsSettings [ key ] ,
2020-12-15 15:03:09 +01:00
basis : "50%" ,
childProps : { type : "number" } ,
2022-03-14 18:22:45 +01:00
min : this . defaults . detailsSettings [ key ] . min ,
max : this . defaults . detailsSettings [ key ] . max ,
2021-04-24 22:28:41 +02:00
} ) ) )
2020-12-15 15:03:09 +01:00
} ) ) ;
2022-03-14 18:22:45 +01:00
const locationInputs = { name : "" , location : "" } ;
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 ,
2022-11-22 01:30:30 +01:00
tag : BDFDB . LibraryComponents . FormComponents . FormTags . H3 ,
2022-03-14 18:22:45 +01:00
children : "Add additional Download Locations"
2020-12-15 15:03:09 +01:00
} ) ,
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 , {
2022-03-14 18:22:45 +01:00
value : locationInputs . name ,
placeholder : "Name" ,
onChange : value => locationInputs . name = value
2020-12-15 15:03:09 +01:00
} )
} )
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex . Child , {
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . FormComponents . FormItem , {
title : "Location:" ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TextInput , {
2022-03-14 18:22:45 +01:00
value : locationInputs . location ,
placeholder : "Location" ,
onChange : value => locationInputs . location = value
2020-12-15 15:03:09 +01:00
} )
} )
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Button , {
style : { marginBottom : 1 } ,
onClick : _ => {
2022-03-14 18:22:45 +01:00
for ( let key in locationInputs ) if ( ! locationInputs [ key ] || ! locationInputs [ key ] . trim ( ) ) return BDFDB . NotificationUtils . toast ( "Fill out all fields to add a new Location" , { type : "danger" } ) ;
let name = locationInputs . name . trim ( ) ;
let location = locationInputs . location . 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 , {
2022-03-14 18:22:45 +01:00
title : "Your own Download Locations" ,
2020-12-15 15:03:09 +01:00
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 , {
2022-03-14 18:22:45 +01:00
title : "Context Menu Settings" ,
2020-12-15 15:03:09 +01:00
collapseStates : collapseStates ,
2022-03-14 18:22:45 +01:00
children : [
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsPanelList , {
title : "Add additional Context Menu Entry for" ,
children : Object . keys ( this . defaults . places ) . map ( key => BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsSaveItem , {
type : "Switch" ,
plugin : this ,
keys : [ "places" , key ] ,
label : this . defaults . places [ key ] . description ,
value : this . settings . places [ key ]
} ) )
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsPanelList , {
title : "Reverse Image Search Engines" ,
children : Object . keys ( this . defaults . engines ) . filter ( key => key != "_all" ) . map ( key => BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsSaveItem , {
type : "Switch" ,
plugin : this ,
keys : [ "engines" , key ] ,
label : this . defaults . engines [ key ] . name ,
value : this . settings . engines [ key ]
} ) )
} )
]
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 ) {
2022-12-16 11:40:29 +01:00
if ( ! this . settings . places . guildIcons || ! e . instance . props . guild ) return ;
2023-03-06 21:34:32 +01:00
if ( BDFDB . DOMUtils . getParent ( BDFDB . dotCNC . guildheader + BDFDB . dotCN . guildchannels , e . instance . props . target ) && ( ! e . instance . props . target . className && e . instance . props . target . parentElement . firstElementChild == e . instance . props . target ) || ( e . instance . props . target . className && e . instance . props . target . className . indexOf ( BDFDB . disCN . guildheaderbanneranimatedhoverlayer ) > - 1 ) ) {
2022-12-16 11:40:29 +01:00
let banner = BDFDB . GuildUtils . getBanner ( e . instance . props . guild . id ) ;
2023-03-31 16:35:45 +02:00
if ( banner ) this . injectItem ( e , [ banner . replace ( /\.webp|\.gif/ , ".png" ) , e . instance . props . guild . banner && BDFDB . LibraryModules . IconUtils . isAnimatedIconHash ( e . instance . props . guild . banner ) && banner . replace ( /\.webp|\.png/ , ".gif" ) ] , { prefix : BDFDB . LanguageUtils . LibraryStrings . guildbanner , id : "banner" } ) ;
2020-09-13 19:22:10 +02:00
}
2023-03-31 16:35:45 +02:00
else if ( ! BDFDB . DOMUtils . getParent ( BDFDB . dotCN . channels , e . instance . props . target ) ) this . injectItem ( e , [ ( e . instance . props . guild . getIconURL ( 4096 ) || "" ) . replace ( /\.webp|\.gif/ , ".png" ) , e . instance . props . guild . icon && BDFDB . LibraryModules . IconUtils . isAnimatedIconHash ( e . instance . props . guild . icon ) && e . instance . props . guild . getIconURL ( 4096 , true ) ] , { prefix : BDFDB . LanguageUtils . LibraryStrings . guildicon , id : "icon" } ) ;
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 ) {
2023-03-31 16:35:45 +02:00
if ( this . settings . places . userAvatars && e . instance . props . user ) {
const guildId = BDFDB . LibraryStores . SelectedGuildStore . getGuildId ( ) ;
const member = BDFDB . LibraryStores . GuildMemberStore . getMember ( guildId , e . instance . props . user . id ) ;
this . injectItem ( e , [ ( e . instance . props . user . getAvatarURL ( null , 4096 ) || "" ) . replace ( /\.webp|\.gif/ , ".png" ) , BDFDB . LibraryModules . IconUtils . isAnimatedIconHash ( e . instance . props . user . avatar ) && e . instance . props . user . getAvatarURL ( null , 4096 , true ) , ( e . instance . props . user . getAvatarURL ( guildId , 4096 ) || "" ) . replace ( /\.webp|\.gif/ , ".png" ) , member && member . avatar && BDFDB . LibraryModules . IconUtils . isAnimatedIconHash ( member . avatar ) && e . instance . props . user . getAvatarURL ( guildId , 4096 , true ) ] ) ;
}
if ( this . settings . places . streamPreviews && e . instance . props . user ) {
let stream = BDFDB . LibraryStores . ApplicationStreamingStore . getAnyStreamForUser ( e . instance . props . user . id ) ;
let previewUrl = stream && BDFDB . LibraryStores . ApplicationStreamPreviewStore . getPreviewURL ( stream . guildId , stream . channelId , stream . ownerId ) ;
if ( previewUrl ) this . injectItem ( e , [ previewUrl ] , { id : "stream" , label : this . labels . context _streamactions } ) ;
}
2020-08-14 14:37:10 +02:00
}
2021-02-25 16:41:14 +01:00
onGroupDMContextMenu ( e ) {
2022-12-16 11:40:29 +01:00
if ( ! this . settings . places . groupIcons || ! e . instance . props . channel || ! e . instance . props . channel . isGroupDM ( ) ) return ;
this . injectItem ( e , [ ( BDFDB . DMUtils . getIcon ( e . instance . props . channel . id ) || "" ) . replace ( /\.webp|\.gif/ , ".png" ) ] ) ;
2022-07-08 17:29:11 +02:00
}
2022-10-13 12:20:55 +02:00
onImageContextMenu ( e ) {
2022-12-16 11:40:29 +01:00
if ( ! e . instance . props . href && ! e . instance . props . src ) return ;
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 ) {
2022-12-16 11:40:29 +01:00
if ( ! e . instance . props . message || ! e . instance . props . channel || ! e . instance . props . target ) return ;
2023-03-20 11:27:46 +01:00
const target = e . instance . props . target . tagName == "A" && BDFDB . DOMUtils . containsClass ( e . instance . props . target , BDFDB . disCN . imageoriginallink ) && e . instance . props . target . parentElement . querySelector ( "img" ) || ( BDFDB . DOMUtils . getParent ( BDFDB . dotCN . messageattachment , e . instance . props . target ) || e . instance . props . target ) . querySelector ( "img, video" ) || e . instance . props . target ;
2023-03-31 16:35:45 +02:00
if ( target . tagName == "A" && e . instance . props . message . embeds && e . instance . props . message . embeds [ 0 ] && ( e . instance . props . message . embeds [ 0 ] . type == "image" || e . instance . props . message . embeds [ 0 ] . type == "video" || e . instance . props . message . embeds [ 0 ] . type == "gifv" ) ) this . injectItem ( e , [ target . href ] , { isNative : true } ) ;
2023-03-08 15:53:48 +01:00
else if ( target . tagName == "IMG" && target . complete && target . naturalHeight ) {
2023-03-31 16:35:45 +02:00
if ( BDFDB . DOMUtils . getParent ( BDFDB . dotCN . imagewrapper , target ) || BDFDB . DOMUtils . containsClass ( target , BDFDB . disCN . imagesticker ) ) this . injectItem ( e , [ { file : target . src , original : this . getTargetLink ( e . instance . props . target ) || this . getTargetLink ( target ) } ] , { isNative : true } ) ;
else if ( BDFDB . DOMUtils . containsClass ( target , BDFDB . disCN . embedauthoricon ) && this . settings . places . userAvatars ) this . injectItem ( e , [ target . src ] , { isNative : true } ) ;
else if ( BDFDB . DOMUtils . containsClass ( target , BDFDB . disCN . emojiold , "emote" , false ) && this . settings . places . emojis ) this . injectItem ( e , [ { file : target . src , alternativeName : target . getAttribute ( "data-name" ) } ] , { isNative : true } ) ;
2023-03-08 15:53:48 +01:00
}
else if ( target . tagName == "VIDEO" ) {
2023-03-31 16:35:45 +02:00
if ( BDFDB . DOMUtils . containsClass ( target , BDFDB . disCN . embedvideo ) || BDFDB . DOMUtils . getParent ( BDFDB . dotCN . attachmentvideo , target ) ) this . injectItem ( e , [ { file : target . src , original : this . getTargetLink ( e . instance . props . target ) || this . getTargetLink ( target ) } ] , { isNative : true } ) ;
2023-03-08 15:53:48 +01:00
}
2022-12-16 11:40:29 +01:00
else {
2023-03-08 15:53:48 +01:00
const reaction = BDFDB . DOMUtils . getParent ( BDFDB . dotCN . messagereaction , target ) ;
if ( reaction && this . settings . places . emojis ) {
const emoji = reaction . querySelector ( BDFDB . dotCN . emojiold ) ;
2023-03-31 16:35:45 +02:00
if ( emoji ) this . injectItem ( e , [ { file : emoji . src , alternativeName : emoji . getAttribute ( "data-name" ) } ] , { isNative : true } ) ;
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
2023-03-31 16:35:45 +02:00
injectItem ( e , urls , config = { } ) {
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 ;
2022-10-29 11:55:42 +02:00
let [ nativeParent , nativeIndex ] = BDFDB . ContextMenuUtils . findItem ( e . returnvalue , { id : "copy-native-link" , group : true } ) ;
if ( nativeIndex > - 1 ) {
2023-03-31 16:35:45 +02:00
if ( validUrls . length == 1 ) config . isNative = true ;
2022-10-29 11:55:42 +02:00
nativeParent . splice ( nativeIndex , 1 ) ;
}
for ( let id of [ "open-native-link" , "copy-image" , "save-image" ] ) {
let [ removeParent , removeIndex ] = BDFDB . ContextMenuUtils . findItem ( e . returnvalue , { id : id , group : true } ) ;
if ( removeIndex > - 1 ) removeParent . splice ( removeIndex , 1 ) ;
2021-02-13 21:16:28 +01:00
}
2021-02-12 11:33:45 +01:00
2022-03-14 18:22:45 +01:00
let subMenu = this . createSubMenus ( {
instance : e . instance ,
urls : validUrls ,
2023-03-31 16:35:45 +02:00
prefix : config . prefix ,
2022-03-14 18:22:45 +01:00
target : e . instance . props . target
} ) ;
2021-02-13 21:16:28 +01:00
2023-03-31 16:35:45 +02:00
let [ children , index ] = config . isNative && nativeIndex > - 1 ? [ nativeParent , nativeIndex ] : BDFDB . ContextMenuUtils . findItem ( e . returnvalue , { id : "devmode-copy-id" , group : true } ) ;
2023-06-23 18:12:09 +02:00
children . splice ( index > - 1 ? index : children . length , 0 , config . isNative && nativeIndex > - 1 ? subMenu : BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuGroup , {
2020-09-19 20:49:33 +02:00
children : BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuItem , {
2023-03-31 16:35:45 +02:00
label : config . label || ( this . isValid ( validUrls [ 0 ] . file , "video" ) ? this . labels . context _videoactions : this . labels . context _imageactions ) ,
id : BDFDB . ContextMenuUtils . createItemId ( this . name , config . id , "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 ) {
2022-03-02 00:10:26 +01:00
let addedUrls = [ ] ;
2021-06-05 21:06:05 +02:00
return urls . filter ( n => this . isValid ( n && n . file || n ) ) . map ( n => {
2023-03-08 15:53:48 +01:00
let srcUrl = ( n . file || n ) . replace ( /^url\(|\)$|"|'/g , "" ) ;
let originalUrl = ( n . original || n . file || n ) . replace ( /^url\(|\)$|"|'/g , "" ) ;
2022-02-25 17:47:56 +01:00
let fileUrl = srcUrl ;
if ( fileUrl . indexOf ( "https://images-ext-1.discordapp.net/external/" ) > - 1 || fileUrl . indexOf ( "https://images-ext-2.discordapp.net/external/" ) > - 1 ) {
if ( fileUrl . split ( "/https/" ) . length > 1 ) fileUrl = "https://" + fileUrl . split ( "/https/" ) . pop ( ) ;
else if ( url . split ( "/http/" ) . length > 1 ) fileUrl = "http://" + fileUrl . split ( "/http/" ) . pop ( ) ;
2021-06-05 21:06:05 +02:00
}
2022-02-25 17:47:56 +01:00
const file = fileUrl && ( BDFDB . LibraryModules . URLParser . parse ( fileUrl ) . pathname || "" ) . toLowerCase ( ) ;
2021-06-05 21:06:05 +02:00
const fileType = file && ( file . split ( "." ) . pop ( ) || "" ) ;
2022-03-02 00:10:26 +01:00
return fileUrl && fileType && ! addedUrls . includes ( srcUrl ) && addedUrls . push ( srcUrl ) && { file : fileUrl , src : srcUrl , original : originalUrl , isGuildSpecific : /^https:\/\/cdn\.discordapp\.com\/guilds\/\d+\/users\/\d+/ . test ( srcUrl ) , fileType , alternativeName : escape ( ( n . alternativeName || "" ) . replace ( /:/g , "" ) ) } ;
2021-06-05 21:06:05 +02:00
} ) . filter ( n => n ) ;
}
2021-05-28 20:17:33 +02:00
isValid ( url , type ) {
if ( ! url ) return false ;
2023-03-31 16:35:45 +02:00
if ( url && url . indexOf ( "data:" ) == 0 && url . indexOf ( "base64" ) > - 1 ) {
const fileType = ( url . split ( "/" ) [ 1 ] || "" ) . split ( ";" ) [ 0 ] ;
return ! type && fileTypes [ fileType ] || type && type != "searchable" && fileTypes [ fileType ] && fileTypes [ fileType ] [ type ] ;
}
else {
const file = url && ( BDFDB . LibraryModules . URLParser . parse ( url ) . pathname || "" ) . split ( "%3A" ) [ 0 ] . toLowerCase ( ) ;
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 == "copyable" || type == "searchable" ) && ( url . indexOf ( "discord.com/streams/guild:" ) > - 1 || url . indexOf ( "discordapp.com/streams/guild:" ) > - 1 || url . indexOf ( "discordapp.net/streams/guild:" ) > - 1 ) ) || 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
}
2022-12-15 14:56:39 +01:00
getPosterUrl ( url ) {
return ( url || "" ) . replace ( "https://cdn.discordapp.com" , "https://media.discordapp.net" ) . split ( "?size=" ) [ 0 ] + "?format=jpeg" ;
}
2022-03-14 18:22:45 +01:00
createSubMenus ( data ) {
return data . urls . length == 1 ? this . createUrlMenu ( data . instance , data . urls [ 0 ] , data . target ) : data . urls . map ( ( urlData , i ) => BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuItem , {
label : [ urlData . isGuildSpecific && BDFDB . LanguageUtils . LanguageStrings . CHANGE _IDENTITY _SERVER _PROFILE , data . prefix , urlData . fileType . toUpperCase ( ) ] . filter ( n => n ) . join ( " " ) ,
2021-06-05 21:06:05 +02:00
id : BDFDB . ContextMenuUtils . createItemId ( this . name , "subitem" , i ) ,
2022-03-14 18:22:45 +01:00
children : this . createUrlMenu ( data . instance , urlData , data . target )
2021-06-05 21:06:05 +02:00
} ) ) ;
}
2022-03-14 18:22:45 +01:00
createUrlMenu ( instance , urlData , target ) {
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 ) ;
2023-03-20 11:27:46 +01:00
2020-12-16 10:58:13 +01:00
let locations = Object . keys ( ownLocations ) . filter ( n => ownLocations [ n ] . enabled ) ;
2023-03-20 11:27:46 +01:00
2021-11-03 15:26:10 +01:00
let isVideo = this . isValid ( urlData . file , "video" ) ;
2021-02-09 14:51:23 +01:00
let type = isVideo ? BDFDB . LanguageUtils . LanguageStrings . VIDEO : BDFDB . LanguageUtils . LanguageStrings . IMAGE ;
2023-03-20 11:27:46 +01:00
2021-02-13 21:16:28 +01:00
return BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuGroup , {
children : [
2023-03-31 16:35:45 +02:00
urlData . original && urlData . original . indexOf ( "data:" ) != 0 && BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuItem , {
2021-02-13 21:16:28 +01:00
label : BDFDB . LanguageUtils . LanguageStrings . COPY _LINK ,
id : BDFDB . ContextMenuUtils . createItemId ( this . name , "copy-link" ) ,
action : _ => {
2023-11-02 11:06:30 +01:00
let url = this . removeSizeInUrl ( urlData . original ) ;
2023-03-20 11:27:46 +01:00
url = url . indexOf ( "discordapp.com/avatars/" ) > 0 || url . indexOf ( "discordapp.com/icons/" ) > 0 ? ` ${ url } ?size=4096 ` : url ;
BDFDB . LibraryModules . WindowUtils . copy ( url ) ;
2021-04-24 22:28:41 +02:00
BDFDB . NotificationUtils . toast ( BDFDB . LanguageUtils . LanguageStrings . LINK _COPIED , { type : "success" } ) ;
}
} ) ,
2021-11-03 15:26:10 +01:00
urlData . file != urlData . 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 : _ => {
2023-11-02 11:06:30 +01:00
let url = this . removeSizeInUrl ( urlData . file ) ;
2023-03-20 11:27:46 +01:00
url = url . indexOf ( "discordapp.com/avatars/" ) > 0 || url . indexOf ( "discordapp.com/icons/" ) > 0 ? ` ${ url } ?size=4096 ` : url ;
BDFDB . LibraryModules . WindowUtils . copy ( url ) ;
2021-02-13 21:16:28 +01:00
BDFDB . NotificationUtils . toast ( BDFDB . LanguageUtils . LanguageStrings . LINK _COPIED , { type : "success" } ) ;
}
} ) ,
2023-03-31 16:35:45 +02:00
urlData . original && urlData . original . indexOf ( "data:" ) != 0 && BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuItem , {
2021-12-22 22:27:22 +01:00
label : BDFDB . LanguageUtils . LanguageStrings . OPEN _LINK ,
id : BDFDB . ContextMenuUtils . createItemId ( this . name , "open-link" ) ,
action : _ => BDFDB . DiscordUtils . openLink ( urlData . original )
} ) ,
! this . isValid ( urlData . file , "copyable" ) ? null : BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuItem , {
label : this . labels . context _copy . replace ( "{{var0}}" , type ) ,
id : BDFDB . ContextMenuUtils . createItemId ( this . name , "copy-file" ) ,
2023-03-30 16:45:02 +02:00
action : _ => this . copyFile ( { url : urlData . original , fallbackUrl : urlData . src } )
2021-12-22 22:27:22 +01:00
} ) ,
2022-03-19 19:01:43 +01:00
! document . querySelector ( BDFDB . dotCN . imagemodal ) && 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 : _ => {
2022-03-19 19:01:43 +01:00
const imageThrowaway = document . createElement ( isVideo ? "video" : "img" ) ;
imageThrowaway . addEventListener ( isVideo ? "loadedmetadata" : "load" , function ( ) {
2023-03-20 11:27:46 +01:00
_this . cacheClickedImage ( target ) ;
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 ,
2023-03-20 11:27:46 +01:00
children : isVideo ? BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . ImageVideoModal , {
src : imageThrowaway . src ,
2023-03-31 06:59:05 +02:00
poster : _this . getPosterUrl ( imageThrowaway . src ) ,
2023-03-20 11:27:46 +01:00
width : this . videoWidth ,
naturalWidth : this . videoWidth ,
height : this . videoHeight ,
naturalHeight : this . videoHeight ,
renderLinkComponent : props => BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Anchor , props )
} ) : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . ImageModal , {
2022-03-19 19:01:43 +01:00
src : imageThrowaway . src ,
2022-02-25 17:47:56 +01:00
original : urlData . original ,
2023-03-20 11:27:46 +01:00
width : this . width ,
height : this . height ,
2021-02-13 21:16:28 +01:00
className : BDFDB . disCN . imagemodalimage ,
2023-03-20 11:27:46 +01:00
renderLinkComponent : props => BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Anchor , props )
2021-02-13 21:16:28 +01:00
} )
} ) , true ) ;
} ) ;
2021-03-06 18:30:44 +01:00
} ) ;
2022-03-19 19:01:43 +01:00
imageThrowaway . src = urlData . src || urlData . 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" ) ,
2023-03-30 16:45:02 +02:00
action : _ => this . downloadFile ( { url : urlData . original , fallbackUrl : urlData . src } , null , urlData . alternativeName ) ,
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 ,
2023-03-31 16:35:45 +02:00
action : _ => this . downloadFile ( { url : urlData . original , fallbackUrl : urlData . src } , ownLocations [ name ] . location , urlData . alternativeName )
2021-02-13 21:16:28 +01:00
} ) )
} )
} ) ,
2022-03-15 22:19:38 +01:00
! this . isValid ( urlData . original , "searchable" ) || ! engineKeys . length ? 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 ) ;
2022-02-25 17:47:56 +01:00
BDFDB . DiscordUtils . openLink ( this . defaults . engines [ engineKeys [ 0 ] ] . url . replace ( imgUrlReplaceString , encodeURIComponent ( urlData . original ) ) , {
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 ) ,
2022-09-30 14:18:20 +02:00
color : key == "_all" ? BDFDB . DiscordConstants . MenuItemColors . DANGER : BDFDB . DiscordConstants . MenuItemColors . DEFAULT ,
2021-02-13 21:16:28 +01:00
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" ) {
2022-02-25 17:47:56 +01:00
for ( let key2 in enginesWithoutAll ) open ( urlData . original , key2 ) ;
2021-02-13 21:16:28 +01:00
}
2022-02-25 17:47:56 +01:00
else open ( urlData . original , key ) ;
2021-02-13 21:16:28 +01:00
}
} ) )
} )
] . filter ( n => n )
} ) ;
2020-09-19 20:49:33 +02:00
}
2022-03-19 19:01:43 +01:00
2023-02-15 19:22:09 +01:00
processModalCarousel ( e ) {
2023-03-20 11:27:46 +01:00
if ( ! this . settings . viewerSettings . galleryMode || ! BDFDB . ReactUtils . findParent ( e . returnvalue , { name : [ "ImageVideoModal" , "ImageModal" ] } ) ) return ;
2023-02-15 19:22:09 +01:00
e . returnvalue . props . className = "" ;
e . returnvalue . props . children [ 0 ] = null ;
e . returnvalue . props . children [ 2 ] = null ;
if ( e . returnvalue . props . children [ 1 ] && switchedImageProps ) {
e . returnvalue . props . children [ 1 ] . props = Object . assign ( e . returnvalue . props . children [ 1 ] . props , switchedImageProps ) ;
switchedImageProps = null ;
}
}
2023-03-20 11:27:46 +01:00
processImageVideoModal ( e ) {
this . processImageModal ( e , true ) ;
}
processImageModal ( e , filterForVideos ) {
2023-01-22 20:08:42 +01:00
if ( ! e . returnvalue ) {
if ( switchedImageProps ) {
e . instance . props = Object . assign ( e . instance . props , switchedImageProps ) ;
switchedImageProps = null ;
2022-08-05 11:13:00 +02:00
}
2022-03-19 19:01:43 +01:00
}
else {
let url = this . getImageSrc ( viewedImage && viewedImage . proxy _url || typeof e . instance . props . children == "function" && e . instance . props . children ( Object . assign ( { } , e . instance . props , { size : e . instance . props } ) ) . props . src || e . instance . props . src ) ;
2020-09-19 20:49:33 +02:00
let [ children , index ] = BDFDB . ReactUtils . findParent ( e . returnvalue , { props : [ [ "className" , BDFDB . disCN . downloadlink ] ] } ) ;
if ( index > - 1 ) {
2023-03-20 12:20:45 +01:00
let type = filterForVideos ? BDFDB . LanguageUtils . LanguageStrings . VIDEO : BDFDB . LanguageUtils . LanguageStrings . IMAGE ;
2022-03-14 18:22:45 +01:00
let openContext = event => BDFDB . ContextMenuUtils . open ( this , event , BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuGroup , {
children : Object . keys ( this . defaults . zoomSettings ) . map ( type => {
let isBoolean = typeof this . defaults . zoomSettings [ type ] . value == "boolean" ;
return BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems [ isBoolean ? "MenuCheckboxItem" : "MenuSliderItem" ] , Object . assign ( {
id : BDFDB . ContextMenuUtils . createItemId ( this . name , type )
} , isBoolean ? {
checked : this . settings . zoomSettings [ type ] ,
action : value => {
this . settings . zoomSettings [ type ] = value ;
BDFDB . DataUtils . save ( this . settings . zoomSettings , this , "zoomSettings" ) ;
}
} : {
2021-04-24 22:28:41 +02:00
value : this . settings . zoomSettings [ type ] ,
2022-02-28 21:05:45 +01:00
renderLabel : ( value , instance ) => BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex , {
align : BDFDB . LibraryComponents . Flex . Align . CENTER ,
children : [
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex . Child , {
children : ` ${ this . labels [ this . defaults . zoomSettings [ type ] . label ] || BDFDB . LanguageUtils . LanguageStrings [ this . defaults . zoomSettings [ type ] . label ] } : `
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TextInput , {
type : "number" ,
size : BDFDB . LibraryComponents . TextInput . Sizes . MINI ,
style : { width : 70 } ,
min : 1 ,
max : this . defaults . zoomSettings [ type ] . maxValue ,
value : this . settings . zoomSettings [ type ] ,
onChange : value => value && value >= this . defaults . zoomSettings [ type ] . minValue && instance . handleValueChange ( BDFDB . NumberUtils . mapRange ( [ this . defaults . zoomSettings [ type ] . minValue , this . defaults . zoomSettings [ type ] . maxValue ] , [ 0 , 100 ] , value ) )
} ) ,
BDFDB . ReactUtils . createElement ( "span" , {
style : { width : 20 } ,
children : this . defaults . zoomSettings [ type ] . unit
} )
]
} ) ,
onValueRender : value => ` ${ value } ${ this . defaults . zoomSettings [ type ] . unit } ` ,
2020-09-19 20:49:33 +02:00
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
}
2022-03-14 18:22:45 +01:00
} , BDFDB . ObjectUtils . extract ( this . defaults . zoomSettings [ type ] , isBoolean ? [ "label" ] : [ "digits" , "minValue" , "maxValue" ] ) ) ) ;
} )
} ) ) ;
2020-09-19 20:49:33 +02:00
children [ index ] = BDFDB . ReactUtils . createElement ( "span" , {
className : BDFDB . disCN . _imageutilitiesoperations ,
children : [
children [ index ] ,
2022-03-14 18:22:45 +01:00
this . settings . viewerSettings . saveImage && [
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 ) ;
2022-12-16 11:40:29 +01:00
this . downloadFile ( { url : 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 ,
2022-12-16 11:40:29 +01:00
action : _ => this . downloadFile ( { url : url } , ownLocations [ name ] . location )
2020-12-15 15:03:09 +01:00
} ) )
} ) ) ;
2020-09-19 20:49:33 +02:00
}
} )
] ,
2022-03-14 18:22:45 +01:00
this . settings . viewerSettings . copyImage && 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 ) ;
2023-03-10 12:16:34 +01:00
this . copyFile ( { url : url } ) ;
2020-09-19 20:49:33 +02:00
}
} )
] ,
2022-09-22 19:41:02 +02:00
this . settings . viewerSettings . galleryMode && viewedImage && this . settings . viewerSettings . jumpTo && [
BDFDB . ReactUtils . createElement ( "span" , {
className : BDFDB . disCN . downloadlink ,
children : "|" ,
style : { margin : "0 5px" }
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Anchor , {
className : BDFDB . disCN . downloadlink ,
children : BDFDB . LanguageUtils . LanguageStrings . JUMP ,
onClick : event => {
let layerContainer = ! event . shiftKey && BDFDB . DOMUtils . getParent ( BDFDB . dotCN . itemlayercontainer , event . currentTarget )
let backdrop = layerContainer && layerContainer . querySelector ( BDFDB . dotCN . backdrop ) ;
if ( backdrop ) backdrop . click ( ) ;
2022-09-27 14:48:10 +02:00
let channel = BDFDB . LibraryStores . ChannelStore . getChannel ( viewedImage . channelId ) ;
2022-09-22 19:41:02 +02:00
if ( channel ) BDFDB . LibraryModules . HistoryUtils . transitionTo ( BDFDB . DiscordConstants . Routes . CHANNEL ( channel . guild _id , channel . id , viewedImage . messageId ) ) ;
}
} )
] ,
2023-03-20 12:25:54 +01:00
this . settings . viewerSettings . zoomMode && ! filterForVideos && ! this . isValid ( e . instance . props . src , "gif" ) && [
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 )
} ) ;
2022-03-19 19:01:43 +01:00
if ( this . settings . viewerSettings . details ) {
e . returnvalue . props . children . push ( BDFDB . ReactUtils . createElement ( "div" , {
className : BDFDB . disCN . _imageutilitiesdetailswrapper ,
children : [
e . instance . props . alt && { label : "Alt" , text : e . instance . props . alt } ,
2023-11-02 11:06:30 +01:00
{ label : "Source" , text : this . removeSizeInUrl ( url ) } ,
2022-03-19 19:01:43 +01:00
{ label : "Size" , text : ` ${ e . instance . props . width } x ${ e . instance . props . height } px ` } ,
2023-03-20 12:23:29 +01:00
cachedImages && cachedImages . amount && cachedImages . amount > 1 && { label : filterForVideos ? "Video" : "Image" , text : ` ${ cachedImages . index + 1 || 1 } of ${ cachedImages . amount } ` }
2022-03-19 19:01:43 +01:00
] . filter ( n => n ) . map ( data => BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TextElement , {
className : BDFDB . disCN . _imageutilitiesdetails ,
children : [
BDFDB . ReactUtils . createElement ( "div" , {
className : BDFDB . disCN . _imageutilitiesdetailslabel ,
children : data . label + ":"
} ) ,
data . text
]
} ) )
} ) ) ;
2020-09-19 20:49:33 +02:00
}
2020-08-14 14:37:10 +02:00
}
2022-03-19 19:01:43 +01:00
if ( this . settings . viewerSettings . galleryMode && viewedImage ) {
2022-03-30 12:32:35 +02:00
if ( ! cachedImages || cachedImages . channelId != viewedImage . channelId || cachedImages . amount && this . getImageIndex ( cachedImages . all , viewedImage ) == - 1 ) {
2022-03-19 19:01:43 +01:00
BDFDB . TimeUtils . clear ( viewedImageTimeout ) ;
2022-09-27 14:48:10 +02:00
let channel = BDFDB . LibraryStores . ChannelStore . getChannel ( viewedImage . channelId ) ;
2022-03-19 19:01:43 +01:00
BDFDB . LibraryModules . APIUtils . get ( {
2022-10-19 11:37:19 +02:00
url : BDFDB . DiscordConstants . Endpoints . MESSAGES ( channel . id ) ,
2022-03-19 19:01:43 +01:00
query : BDFDB . LibraryModules . APIEncodeUtils . stringify ( {
2022-03-30 12:32:35 +02:00
channel _id : channel && channel . guild _id ? ( BDFDB . ChannelUtils . isThread ( channel ) && channel . parent _id || channel . id ) : null ,
2022-03-19 19:01:43 +01:00
has : "image" ,
2022-03-30 12:32:35 +02:00
include _nsfw : true ,
2022-10-19 11:37:19 +02:00
limit : 100 ,
2022-03-19 19:01:43 +01:00
around : viewedImage . messageId
} )
2022-10-19 11:37:19 +02:00
} ) . catch ( err => {
2022-03-19 20:39:01 +01:00
cachedImages = {
2022-03-30 12:32:35 +02:00
channelId : viewedImage . channelId ,
2022-03-19 20:39:01 +01:00
firstReached : null ,
oldestId : null ,
all : [ ] ,
index : - 1 ,
amount : 0 ,
newestId : null ,
lastReached : null
} ;
2023-01-22 20:08:42 +01:00
this . updateImageModal ( ) ;
2022-03-19 19:01:43 +01:00
} ) . then ( result => {
2022-04-06 18:07:40 +02:00
if ( ! viewedImage ) return ;
2022-03-19 20:39:01 +01:00
let messages = [ ] , index = - 1 ;
2022-03-19 19:01:43 +01:00
if ( result ) {
2022-10-19 11:37:19 +02:00
messages = result . body . flat ( 10 ) . reverse ( ) ;
2023-03-20 11:27:46 +01:00
cachedImages = { all : this . filterMessagesForImages ( messages , viewedImage , filterForVideos ) } ;
2022-03-19 20:39:01 +01:00
index = this . getImageIndex ( cachedImages . all , viewedImage ) ;
}
2022-03-30 12:32:35 +02:00
if ( index > - 1 ) cachedImages = Object . assign ( cachedImages , {
channelId : viewedImage . channelId ,
firstReached : index == 0 ,
oldestId : messages [ 0 ] ? messages [ 0 ] . id : null ,
index : index ,
amount : cachedImages . all . length ,
newestId : messages [ messages . length - 1 ] ? messages [ messages . length - 1 ] . id : null ,
lastReached : index == ( cachedImages . all . length - 1 )
} ) ;
2022-03-19 19:01:43 +01:00
else cachedImages = {
2022-03-30 12:32:35 +02:00
channelId : viewedImage . channelId ,
2022-03-19 19:01:43 +01:00
firstReached : null ,
oldestId : null ,
all : [ ] ,
index : - 1 ,
amount : 0 ,
newestId : null ,
lastReached : null
} ;
2023-01-22 20:08:42 +01:00
this . updateImageModal ( ) ;
2022-03-19 19:01:43 +01:00
} ) ;
}
else {
if ( cachedImages . all [ cachedImages . index - 1 ] ) e . returnvalue . props . children . push ( BDFDB . ReactUtils . createElement ( LazyImageSiblingComponent , {
className : BDFDB . disCN . _imageutilitiesprevious ,
url : this . getImageSrc ( cachedImages . all [ cachedImages . index - 1 ] . thumbnail || cachedImages . all [ cachedImages . index - 1 ] ) ,
offset : - 1 ,
svgIcon : BDFDB . LibraryComponents . SvgIcon . Names . LEFT _CARET
} ) ) ;
if ( cachedImages . all [ cachedImages . index + 1 ] ) e . returnvalue . props . children . push ( BDFDB . ReactUtils . createElement ( LazyImageSiblingComponent , {
className : BDFDB . disCN . _imageutilitiesnext ,
url : this . getImageSrc ( cachedImages . all [ cachedImages . index + 1 ] . thumbnail || cachedImages . all [ cachedImages . index + 1 ] ) ,
offset : 1 ,
svgIcon : BDFDB . LibraryComponents . SvgIcon . Names . RIGHT _CARET
} ) ) ;
if ( cachedImages . all [ cachedImages . index - 1 ] || cachedImages . all [ cachedImages . index + 1 ] ) {
this . addListener ( "keydown" , "Gallery" , event => {
if ( ! firedEvents . includes ( "Gallery" ) ) {
firedEvents . push ( "Gallery" ) ;
2023-03-20 11:27:46 +01:00
if ( event . keyCode == 37 ) this . switchImages ( - 1 , filterForVideos ) ;
else if ( event . keyCode == 39 ) this . switchImages ( 1 , filterForVideos ) ;
2022-03-19 19:01:43 +01:00
}
} ) ;
this . addListener ( "keyup" , "Gallery" , _ => BDFDB . ArrayUtils . remove ( firedEvents , "Gallery" , true ) ) ;
}
2020-09-19 20:49:33 +02:00
}
2020-08-14 14:37:10 +02:00
}
}
}
2022-03-02 22:04:22 +01:00
2020-09-19 20:49:33 +02:00
processLazyImage ( e ) {
if ( e . node ) {
2022-06-28 18:03:54 +02:00
if ( e . instance . props . resized ) {
2023-02-08 15:02:11 +01:00
for ( let selector of [ "embedfull" , "embedinlinemedia" , "embedgridcontainer" , "imagemosaicattachmentscontainer" , "imagemosaiconebyonegridsingle" ] ) {
2022-10-17 16:49:54 +02:00
let parent = BDFDB . DOMUtils . getParent ( BDFDB . dotCN [ selector ] , e . node ) ;
if ( parent ) parent . style . setProperty ( "max-width" , "unset" , "important" ) ;
2023-02-08 15:02:11 +01:00
if ( parent ) parent . style . setProperty ( "max-height" , "unset" , "important" ) ;
2022-10-17 16:49:54 +02:00
}
2022-10-14 15:32:14 +02:00
for ( let ele of [ e . node . style . getPropertyValue ( "width" ) && e . node , ... e . node . querySelectorAll ( "[style*='width:']" ) ] . filter ( n => n ) ) {
ele . style . setProperty ( "width" , e . instance . props . width + "px" ) ;
ele . style . setProperty ( "max-width" , e . instance . props . width + "px" ) ;
ele . style . setProperty ( "height" , e . instance . props . height + "px" ) ;
ele . style . setProperty ( "max-height" , e . instance . props . height + "px" ) ;
}
2023-11-02 11:06:30 +01:00
for ( let ele of [ e . node . src && e . node , ... e . node . querySelectorAll ( "[src]" ) ] . filter ( n => n ) ) ele . src = this . removeSizeInUrl ( ele . src ) ;
if ( e . instance . state . readyState != BDFDB . DiscordConstants . ImageReadyStates . READY ) {
e . instance . state . readyState = BDFDB . DiscordConstants . ImageReadyStates . READY ;
BDFDB . ReactUtils . forceUpdate ( e . instance ) ;
}
2022-03-14 18:22:45 +01:00
}
2023-02-04 13:53:54 +01:00
if ( e . methodname == "componentWillUnmount" && BDFDB . DOMUtils . getParent ( BDFDB . dotCNC . imagemodal + BDFDB . dotCN . modalcarouselmodal , e . node ) ) {
BDFDB . TimeUtils . clear ( viewedImageTimeout ) ;
viewedImageTimeout = BDFDB . TimeUtils . timeout ( _ => {
firstViewedImage = null ;
viewedImage = null ;
this . cleanupListeners ( "Gallery" ) ;
} , 1000 ) ;
2023-01-22 20:08:42 +01:00
}
2023-01-24 10:39:40 +01:00
if ( e . methodname == "componentDidMount" && BDFDB . DOMUtils . getParent ( BDFDB . dotCNC . imagemodal + BDFDB . dotCN . modalcarouselmodal , e . node ) ) {
2023-01-22 20:08:42 +01:00
BDFDB . TimeUtils . clear ( viewedImageTimeout ) ;
let modal = BDFDB . DOMUtils . getParent ( BDFDB . dotCN . modal , e . node ) ;
if ( modal ) {
2023-02-25 14:14:37 +01:00
modal . parentElement . className = BDFDB . DOMUtils . formatClassName ( modal . parentElement . className , this . settings . viewerSettings . galleryMode && BDFDB . disCN . _imageutilitiesgallery , this . settings . viewerSettings . details && BDFDB . disCN . _imageutilitiesdetailsadded ) ;
2023-01-22 20:08:42 +01:00
if ( this . settings . viewerSettings . galleryMode ) {
BDFDB . DOMUtils . addClass ( modal , BDFDB . disCN . imagemodal ) ;
BDFDB . DOMUtils . removeClass ( modal , BDFDB . disCN . modalcarouselmodal , BDFDB . disCN . modalcarouselmodalzoomed ) ;
}
}
2023-03-20 12:24:48 +01:00
if ( this . isValid ( e . instance . props . src , "gif" ) ) e . node . style . setProperty ( "pointer-events" , "none" ) ;
2023-03-20 11:27:46 +01:00
if ( this . settings . viewerSettings . zoomMode && typeof e . instance . props . children != "function" && ! BDFDB . DOMUtils . containsClass ( e . node . parentElement , BDFDB . disCN . _imageutilitiessibling ) ) {
2022-08-05 11:13:00 +02:00
e . node . style . setProperty ( "cursor" , "zoom-in" ) ;
2023-06-22 16:33:20 +02:00
e . node . addEventListener ( this . settings . zoomSettings . clickMode ? "click" : "mousedown" , event => {
BDFDB . ListenerUtils . stopEvent ( event ) ;
2022-12-16 14:06:28 +01:00
if ( event . which != 1 || e . node . querySelector ( "video" ) ) return ;
2022-08-12 13:12:53 +02:00
2022-06-28 18:03:54 +02:00
let vanishObserver ;
2023-02-20 09:15:40 +01:00
let zoomLevel = this . settings . zoomSettings . zoomLevel ;
2022-06-28 18:03:54 +02:00
let imgRects = BDFDB . DOMUtils . getRects ( e . node . firstElementChild ) ;
2023-02-20 09:15:40 +01: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=" ${ ! this . isValid ( e . instance . props . src , "video" ) ? e . instance . props . src : this . getPosterUrl ( e . instance . props . src ) } " style="width: ${ imgRects . width * zoomLevel } px; height: ${ imgRects . height * zoomLevel } px; position: fixed !important; ${ this . settings . zoomSettings . pixelMode ? " image-rendering: pixelated !important;" : "" } " ${ e . node . firstElementChild . tagName == "VIDEO" ? " loop autoplay" : "" } ></ ${ e . node . firstElementChild . tagName } ></div></div> ` ) ;
2022-06-28 18:03:54 +02:00
let pane = lens . firstElementChild . firstElementChild ;
2023-06-22 16:33:20 +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: all !important; z-index: 8000 !important;"></div> ` ) ;
2022-06-28 18:03:54 +02:00
let appMount = document . querySelector ( BDFDB . dotCN . appmount ) ;
appMount . appendChild ( lens ) ;
appMount . appendChild ( backdrop ) ;
2022-08-12 13:12:53 +02:00
2022-06-28 18:03:54 +02:00
let lensRects = BDFDB . DOMUtils . getRects ( lens ) ;
let halfW = lensRects . width / 2 , halfH = lensRects . height / 2 ;
let minX = imgRects . left , maxX = minX + imgRects . width ;
let minY = imgRects . top , maxY = minY + imgRects . height ;
lens . update = _ => {
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 ;
lens . style . setProperty ( "left" , x + "px" , "important" ) ;
lens . style . setProperty ( "top" , y + "px" , "important" ) ;
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" ) ;
2023-02-20 09:15:40 +01:00
pane . style . setProperty ( "left" , imgRects . left + ( ( zoomLevel - 1 ) * ( imgRects . left - x - halfW ) ) + "px" , "important" ) ;
pane . style . setProperty ( "top" , imgRects . top + ( ( zoomLevel - 1 ) * ( imgRects . top - y - halfH ) ) + "px" , "important" ) ;
pane . style . setProperty ( "width" , imgRects . width * zoomLevel + "px" , "important" ) ;
pane . style . setProperty ( "height" , imgRects . height * zoomLevel + "px" , "important" ) ;
2022-06-28 18:03:54 +02:00
} ;
2020-11-29 20:18:28 +01:00
lens . update ( ) ;
2022-06-28 18:03:54 +02:00
let dragging = event2 => {
event = event2 ;
lens . update ( ) ;
} ;
2022-08-05 11:13:00 +02:00
let releasing = event2 => {
BDFDB . ListenerUtils . stopEvent ( event2 ) ;
2022-06-28 18:03:54 +02:00
this . cleanupListeners ( "Zoom" ) ;
document . removeEventListener ( "mousemove" , dragging ) ;
document . removeEventListener ( "mouseup" , releasing ) ;
if ( vanishObserver ) vanishObserver . disconnect ( ) ;
BDFDB . DOMUtils . remove ( lens , backdrop ) ;
BDFDB . DataUtils . save ( this . settings . zoomSettings , this , "zoomSettings" ) ;
} ;
document . addEventListener ( "mousemove" , dragging ) ;
document . addEventListener ( "mouseup" , releasing ) ;
2020-09-19 20:49:33 +02:00
this . cleanupListeners ( "Zoom" ) ;
2022-06-28 18:03:54 +02:00
this . addListener ( "wheel" , "Zoom" , event2 => {
if ( ! document . contains ( e . node ) ) this . cleanupListeners ( "Zoom" ) ;
else {
2023-02-20 09:15:40 +01:00
if ( event2 . deltaY < 0 && ( zoomLevel + this . settings . zoomSettings . zoomSpeed * zoomLevel ) <= this . defaults . zoomSettings . zoomLevel . maxValue ) {
zoomLevel += this . settings . zoomSettings . zoomSpeed * zoomLevel ;
2022-06-28 18:03:54 +02:00
lens . update ( ) ;
}
2023-02-20 09:15:40 +01:00
else if ( event2 . deltaY > 0 && ( zoomLevel - this . settings . zoomSettings . zoomSpeed * zoomLevel ) >= this . defaults . zoomSettings . zoomLevel . minValue ) {
zoomLevel -= this . settings . zoomSettings . zoomSpeed * zoomLevel ;
2022-06-28 18:03:54 +02:00
lens . update ( ) ;
}
2020-09-19 20:49:33 +02:00
}
2022-06-28 18:03:54 +02:00
} ) ;
this . addListener ( "keydown" , "Zoom" , event2 => {
if ( ! document . contains ( e . node ) ) this . cleanupListeners ( "Zoom" ) ;
else if ( ! firedEvents . includes ( "Zoom" ) ) {
firedEvents . push ( "Zoom" ) ;
2023-02-20 09:15:40 +01:00
if ( event2 . keyCode == 187 && ( zoomLevel + zoomLevel * 0.5 ) <= this . defaults . zoomSettings . zoomLevel . maxValue ) {
zoomLevel += zoomLevel * 0.5 ;
2022-06-28 18:03:54 +02:00
lens . update ( ) ;
}
2023-02-20 09:15:40 +01:00
else if ( event2 . keyCode == 189 && ( zoomLevel - zoomLevel * 0.5 ) >= this . defaults . zoomSettings . zoomLevel . minValue ) {
zoomLevel -= zoomLevel * 0.5 ;
2022-06-28 18:03:54 +02:00
lens . update ( ) ;
}
2020-09-19 20:49:33 +02:00
}
2022-06-28 18:03:54 +02:00
} ) ;
this . addListener ( "keyup" , "Zoom" , _ => {
BDFDB . ArrayUtils . remove ( firedEvents , "Zoom" , true ) ;
if ( ! document . contains ( e . node ) ) this . cleanupListeners ( "Zoom" ) ;
} ) ;
vanishObserver = new MutationObserver ( changes => { if ( ! document . contains ( e . node ) ) releasing ( ) ; } ) ;
vanishObserver . observe ( appMount , { childList : true , subtree : true } ) ;
2022-03-19 19:01:43 +01:00
} ) ;
2022-06-28 18:03:54 +02:00
}
2020-09-19 20:49:33 +02:00
}
}
2020-10-16 19:47:23 +02:00
else {
2022-06-22 15:34:42 +02:00
let reactInstance = BDFDB . ObjectUtils . get ( e , ` instance. ${ BDFDB . ReactUtils . instanceKey } ` ) ;
2023-02-03 21:36:29 +01:00
if ( this . settings . rescaleSettings . imageViewer != "NONE" && e . instance . props . className && e . instance . props . className . indexOf ( BDFDB . disCN . imagemodalimage ) > - 1 ) {
2020-10-16 19:47:23 +02:00
let aRects = BDFDB . DOMUtils . getRects ( document . querySelector ( BDFDB . dotCN . appmount ) ) ;
2022-03-19 19:01:43 +01:00
let ratio = Math . min ( ( aRects . width * ( this . settings . viewerSettings . galleryMode ? 0.8 : 1 ) - 20 ) / e . instance . props . width , ( aRects . height - ( this . settings . viewerSettings . details ? 280 : 100 ) ) / e . instance . props . height ) ;
2022-06-24 17:25:57 +02:00
ratio = this . settings . rescaleSettings . imageViewer == "ORIGINAL" && ratio > 1 ? 1 : ratio ;
let width = Math . round ( ratio * e . instance . props . width ) ;
let height = Math . round ( ratio * e . instance . props . height ) ;
if ( e . instance . props . width != width || e . instance . props . maxWidth != width || e . instance . props . height != height || e . instance . props . maxHeight != height ) {
2022-03-14 18:22:45 +01:00
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 } ` ) ;
e . instance . props . resized = true ;
}
}
2023-04-09 11:45:04 +02:00
if ( this . settings . rescaleSettings . messages != "NONE" && [ e . instance . props . className , e . instance . props . containerClassName ] . every ( n => [ BDFDB . disCN . embedvideoimagecomponent , BDFDB . disCN . embedthumbnail ] . every ( m => ( n || "" ) . indexOf ( m ) == - 1 ) ) && BDFDB . ReactUtils . findOwner ( reactInstance , { name : "LazyImageZoomable" , up : true } ) && ( e . instance . props . mediaLayoutType != "MOSAIC" || ( BDFDB . ReactUtils . findValue ( reactInstance , "mediaAttachments" , { up : true } ) || [ ] ) . length < 2 ) ) {
2022-06-24 17:25:57 +02:00
let aRects = BDFDB . DOMUtils . getRects ( document . querySelector ( BDFDB . dotCN . appmount ) ) ;
let mRects = BDFDB . DOMUtils . getRects ( document . querySelector ( BDFDB . dotCNC . messageaccessory + BDFDB . dotCN . messagecontents ) ) ;
let mwRects = BDFDB . DOMUtils . getRects ( document . querySelector ( BDFDB . dotCN . messagewrapper ) ) ;
if ( mRects . width || mwRects . width ) {
let embed = BDFDB . ReactUtils . findValue ( reactInstance , "embed" , { up : true } ) ;
let ratio = ( ( mRects . width || ( mwRects . width - 120 ) ) - ( embed && embed . color ? 100 : 0 ) ) / e . instance . props . width ;
ratio = this . settings . rescaleSettings . messages == "ORIGINAL" && ratio > 1 ? 1 : ratio ;
let width = Math . round ( ratio * e . instance . props . width ) ;
let height = Math . round ( ratio * e . instance . props . height ) ;
if ( height > ( aRects . height * 0.66 ) ) {
let newHeight = Math . round ( aRects . height * 0.66 ) ;
width = ( newHeight / height ) * width ;
height = newHeight ;
}
if ( e . instance . props . width != width || e . instance . props . maxWidth != width || e . instance . props . height != height || e . instance . props . maxHeight != 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 } ` ) ;
e . instance . props . resized = true ;
2022-06-22 15:34:42 +02:00
}
}
}
2020-10-16 19:47:23 +02:00
}
2022-03-02 22:04:22 +01:00
}
processLazyImageZoomable ( e ) {
2022-10-13 12:20:55 +02:00
if ( ! e . instance . props . original || e . instance . props . src . indexOf ( "https://media.discordapp.net/attachments" ) != 0 ) return ;
2023-04-04 12:13:34 +02:00
if ( this . settings . detailsSettings . tooltip || this . settings . detailsSettings . footnote && e . instance . props . mediaLayoutType == "MOSAIC" && ( BDFDB . ReactUtils . findValue ( BDFDB . ObjectUtils . get ( e , ` instance. ${ BDFDB . ReactUtils . instanceKey } ` ) , "mediaAttachments" , { up : true } ) || [ ] ) . length > 1 ) {
2022-03-14 18:22:45 +01:00
const attachment = BDFDB . ReactUtils . findValue ( e . instance , "attachment" , { up : true } ) ;
2022-03-02 22:04:22 +01:00
if ( attachment ) {
2022-03-03 18:43:25 +01:00
const onMouseEnter = e . returnvalue . props . onMouseEnter ;
e . returnvalue . props . onMouseEnter = BDFDB . TimeUtils . suppress ( ( ... args ) => {
BDFDB . TooltipUtils . create ( args [ 0 ] . target , [
2022-03-02 22:04:22 +01:00
attachment . filename ,
BDFDB . NumberUtils . formatBytes ( attachment . size ) ,
` ${ attachment . width } x ${ attachment . height } px `
2022-03-03 18:43:25 +01:00
] . map ( l => BDFDB . ReactUtils . createElement ( "div" , { style : { padding : "2px 0" } , children : l } ) ) , {
2022-03-02 22:04:22 +01:00
type : "right" ,
2022-03-14 18:22:45 +01:00
delay : this . settings . detailsSettings . tooltipDelay
2022-03-03 18:43:25 +01:00
} ) ;
return onMouseEnter ( ... args ) ;
2022-06-22 15:34:42 +02:00
} , "Error in onMouseEnter of LazyImageZoomable!" ) ;
}
}
2023-04-09 11:45:04 +02:00
if ( this . settings . detailsSettings . footnote && [ e . instance . props . className , e . instance . props . containerClassName ] . every ( n => [ BDFDB . disCN . embedmedia , BDFDB . disCN . embedthumbnail ] . every ( m => ( n || "" ) . indexOf ( m ) == - 1 ) ) && ( e . instance . props . mediaLayoutType != "MOSAIC" || ( BDFDB . ReactUtils . findValue ( BDFDB . ObjectUtils . get ( e , ` instance. ${ BDFDB . ReactUtils . instanceKey } ` ) , "mediaAttachments" , { up : true } ) || [ ] ) . length < 2 ) ) {
2022-10-13 12:20:55 +02:00
e . returnvalue = BDFDB . ReactUtils . createElement ( "div" , {
children : [
e . returnvalue ,
BDFDB . ReactUtils . createElement ( ImageDetailsComponent , {
original : e . instance . props . original ,
attachment : {
height : 0 ,
width : 0 ,
filename : "unknown.png"
}
2023-04-04 12:13:34 +02:00
} , true )
2022-10-13 12:20:55 +02:00
]
} ) ;
}
2022-06-22 15:34:42 +02:00
}
2022-10-13 12:17:00 +02:00
processMessageAccessories ( e ) {
2022-06-22 15:34:42 +02:00
if ( this . settings . general . nsfwMode && e . instance . props . channel . nsfw ) {
e . instance . props . message = new BDFDB . DiscordObjects . Message ( e . instance . props . message ) ;
e . instance . props . message . attachments = [ ] . concat ( e . instance . props . message . attachments ) ;
for ( let i in e . instance . props . message . attachments ) if ( e . instance . props . message . attachments [ i ] . spoiler != undefined ) {
e . instance . props . message . attachments [ i ] = Object . assign ( { } , e . instance . props . message . attachments [ i ] , { spoiler : true , nsfw : ! e . instance . props . message . attachments [ i ] . spoiler } ) ;
2022-03-02 22:04:22 +01:00
}
}
2020-09-19 20:49:33 +02:00
}
2022-06-22 15:34:42 +02:00
processSpoiler ( e ) {
2022-08-15 13:40:57 +02:00
if ( ! e . returnvalue ) {
2022-08-18 08:43:11 +02:00
if ( this . settings . rescaleSettings . messages != "NONE" && ! e . instance . props . inline && e . instance . props . type == "attachment" && e . instance . props . containerStyles ) e . instance . props . containerStyles . maxWidth = "100%" ;
2022-08-15 13:40:57 +02:00
}
else {
2022-10-13 12:20:55 +02:00
if ( this . settings . general . nsfwMode && typeof e . returnvalue . props . children == "function" ) {
2022-08-15 13:40:57 +02:00
let childrenRender = e . returnvalue . props . children ;
e . returnvalue . props . children = BDFDB . TimeUtils . suppress ( ( ... args ) => {
2022-10-13 12:20:55 +02:00
let returnedChildren = childrenRender ( ... args ) ;
let attachment = BDFDB . ReactUtils . findValue ( returnedChildren , "attachment" ) ;
2022-08-15 13:40:57 +02:00
if ( attachment && attachment . nsfw ) {
2022-10-13 12:20:55 +02:00
let [ children , index ] = BDFDB . ReactUtils . findParent ( returnedChildren , { name : "SpoilerWarning" } ) ;
if ( index > - 1 ) children [ index ] = BDFDB . ReactUtils . createElement ( "div" , {
2022-08-15 13:40:57 +02:00
className : BDFDB . disCN . spoilerwarning ,
children : "NSFW"
} ) ;
}
2022-10-13 12:20:55 +02:00
return returnedChildren ;
2022-08-15 13:40:57 +02:00
} , "Error in Children Render of Spoiler!" ) ;
}
2022-06-22 15:34:42 +02:00
}
}
2020-09-19 20:49:33 +02:00
2022-12-01 20:44:25 +01:00
processUserBanner ( e ) {
2022-10-13 12:20:55 +02:00
if ( ! this . settings . places . userAvatars || ! e . instance . props . displayProfile || ! e . instance . props . displayProfile . banner ) return ;
let div = BDFDB . ReactUtils . findChild ( e . returnvalue , { type : "div" } ) ;
if ( div ) div . props . onContextMenu = event => {
2022-09-04 03:00:45 +02:00
let validUrls = this . filterUrls ( BDFDB . UserUtils . getBanner ( e . instance . props . user . id , null , false ) , BDFDB . LibraryModules . IconUtils . isAnimatedIconHash ( e . instance . props . displayProfile . _userProfile . banner ) && BDFDB . UserUtils . getBanner ( e . instance . props . user . id , null , true ) , e . instance . props . displayProfile . _guildMemberProfile . banner && BDFDB . UserUtils . getBanner ( e . instance . props . user . id , e . instance . props . guildId , false ) , e . instance . props . displayProfile . _guildMemberProfile . banner && BDFDB . LibraryModules . IconUtils . isAnimatedIconHash ( e . instance . props . displayProfile . _guildMemberProfile . banner ) && BDFDB . UserUtils . getBanner ( e . instance . props . user . id , e . instance . props . guildId , true ) ) ;
if ( validUrls . length ) BDFDB . ContextMenuUtils . open ( this , event , BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuGroup , {
children : validUrls . length == 1 ? this . createSubMenus ( {
instance : { } ,
urls : validUrls ,
prefix : BDFDB . LanguageUtils . LanguageStrings . USER _SETTINGS _PROFILE _BANNER
} ) : BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuItem , {
2022-09-11 12:58:27 +02:00
label : this . labels . context _imageactions ,
2022-09-04 03:00:45 +02:00
id : BDFDB . ContextMenuUtils . createItemId ( this . name , "main-subitem" ) ,
children : this . createSubMenus ( {
instance : { } ,
urls : validUrls ,
prefix : BDFDB . LanguageUtils . LanguageStrings . USER _SETTINGS _PROFILE _BANNER
} )
} )
} ) ) ;
} ;
}
2022-03-19 19:01:43 +01:00
cacheClickedImage ( target ) {
2022-03-19 20:39:01 +01:00
if ( ! target ) return ;
2023-03-20 11:27:46 +01:00
const image = ( BDFDB . DOMUtils . getParent ( BDFDB . dotCN . imagewrapper , target ) || target ) . querySelector ( "img, video" ) || target ;
2022-03-19 19:01:43 +01:00
if ( ! image ) return ;
const message = BDFDB . ReactUtils . findValue ( image , "message" , { up : true } ) ;
if ( ! message ) return ;
2023-03-08 15:53:48 +01:00
BDFDB . DOMUtils . hide ( document . querySelectorAll ( BDFDB . dotCN . tooltip ) ) ;
2022-03-19 19:01:43 +01:00
firstViewedImage = { messageId : message . id , channelId : message . channel _id , proxy _url : image . src } ;
viewedImage = firstViewedImage ;
2022-08-05 11:13:00 +02:00
if ( cachedImages ) cachedImages . index = this . getImageIndex ( cachedImages . all , viewedImage ) ;
2022-03-19 19:01:43 +01:00
viewedImageTimeout = BDFDB . TimeUtils . timeout ( _ => {
firstViewedImage = null ;
viewedImage = null ;
} , 1000 ) ;
}
2023-03-10 12:16:34 +01:00
requestFile ( urls , onLoad , onError , config = { } ) {
if ( ! urls || typeof onLoad != "function" ) return typeof onError == "function" && onError ( ) ;
2022-12-16 11:40:29 +01:00
let url = urls . url . startsWith ( "/assets" ) ? ( window . location . origin + urls . url ) : urls . url ;
2023-03-10 12:16:34 +01:00
let isResized = ! config . orignalSizeChecked && ( url . indexOf ( "?width=" ) > - 1 || url . indexOf ( "?height=" ) > - 1 || url . indexOf ( "?size=" ) > - 1 ) ;
2023-11-02 11:06:30 +01:00
url = isResized ? this . removeSizeInUrl ( url ) : url ;
2023-03-30 16:45:02 +02:00
url = url . indexOf ( "discordapp.com/avatars/" ) > 0 || url . indexOf ( "discordapp.com/icons/" ) > 0 ? ` ${ url } ?size=4096 ` : url ;
2023-11-04 10:33:32 +01:00
BDFDB . LibraryRequires . request ( url , { toBuffer : true } , ( error , response , buffer ) => {
2022-12-15 14:56:39 +01:00
if ( error || response . statusCode != 200 || response . headers [ "content-type" ] . indexOf ( "text/html" ) > - 1 ) {
2023-11-04 10:33:32 +01:00
if ( isResized ) this . requestFile ( urls , onLoad , onError , { orignalSizeChecked : true } ) ;
else if ( urls . fallbackUrl && urls . url != urls . fallbackUrl ) this . requestFile ( { url : urls . fallbackUrl } , onLoad , onError ) ;
2023-03-10 12:16:34 +01:00
else if ( typeof onError == "function" ) onError ( ) ;
2022-12-15 14:56:39 +01:00
}
2023-03-10 12:16:34 +01:00
else onLoad ( url , buffer ) ;
} ) ;
}
downloadFile ( urls , path , alternativeName ) {
this . requestFile ( urls , ( url , buffer ) => {
let extension = this . getFileExtension ( new Uint8Array ( buffer ) ) ;
if ( ! extension ) BDFDB . NotificationUtils . toast ( this . labels . toast _save _failed . replace ( "{{var0}}" , BDFDB . LanguageUtils . LanguageStrings . IMAGE ) . replace ( "{{var1}}" , path || "PC" ) , { type : "danger" } ) ;
2022-12-01 20:44:25 +01:00
else {
2023-03-10 12:16:34 +01:00
let type = fileTypes [ extension ] . video ? BDFDB . LanguageUtils . LanguageStrings . VIDEO : BDFDB . LanguageUtils . LanguageStrings . IMAGE ;
2023-10-20 14:25:24 +02:00
if ( path ) BDFDB . LibraryRequires . fs . writeFile ( this . getFileName ( path , ( alternativeName || url . split ( "/" ) . pop ( ) . split ( "." ) . slice ( 0 , - 1 ) . join ( "." ) || "unknown" ) . slice ( 0 , 35 ) , extension , 0 ) , new Uint8Array ( buffer ) , error => {
2023-03-10 12:16:34 +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" } ) ;
} ) ;
2022-12-08 19:15:15 +01:00
else {
2023-03-10 12:16:34 +01:00
let hrefURL = window . URL . createObjectURL ( new Blob ( [ buffer ] , { type : this . getMimeType ( extension ) } ) ) ;
let tempLink = document . createElement ( "a" ) ;
tempLink . href = hrefURL ;
tempLink . download = ` ${ ( alternativeName || url . split ( "/" ) . pop ( ) . split ( "." ) . slice ( 0 , - 1 ) . join ( "." ) || "unknown" ) . slice ( 0 , 35 ) } . ${ extension } ` ;
tempLink . click ( ) ;
window . URL . revokeObjectURL ( hrefURL ) ;
2022-12-08 19:15:15 +01:00
}
2022-12-01 20:44:25 +01:00
}
2023-03-10 12:16:34 +01:00
} , _ => {
BDFDB . NotificationUtils . toast ( this . labels . toast _save _failed . replace ( "{{var0}}" , BDFDB . LanguageUtils . LanguageStrings . IMAGE ) . replace ( "{{var1}}" , path || "PC" ) , { type : "danger" } ) ;
2022-12-01 20:44:25 +01:00
} ) ;
2020-08-14 14:37:10 +02:00
}
2020-09-19 20:49:33 +02:00
2023-03-10 12:16:34 +01:00
copyFile ( urls ) {
2023-11-04 10:33:32 +01:00
this . requestFile ( urls , url => {
2023-03-31 16:35:45 +02:00
let type = this . isValid ( url , "video" ) ? BDFDB . LanguageUtils . LanguageStrings . VIDEO : BDFDB . LanguageUtils . LanguageStrings . IMAGE ;
2023-03-10 12:16:34 +01:00
BDFDB . LibraryModules . WindowUtils . copyImage ( url ) ;
BDFDB . NotificationUtils . toast ( this . labels . toast _copy _success . replace ( "{{var0}}" , type ) , { type : "success" } ) ;
} , _ => {
BDFDB . NotificationUtils . toast ( this . labels . toast _copy _failed . replace ( "{{var0}}" , BDFDB . LanguageUtils . LanguageStrings . IMAGE ) , { type : "danger" } ) ;
} ) ;
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 ) {
2022-02-25 17:47:56 +01:00
fileName = fileName . split ( "?" ) [ 0 ] ;
2020-09-19 20:49:33 +02:00
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 ;
}
2022-02-11 18:57:35 +01:00
2022-12-01 20:44:25 +01:00
getFileExtension ( intArray ) {
for ( let fileType in fileTypes ) if ( fileTypes [ fileType ] . signs . some ( signs => signs . every ( ( hex , i ) => hex === null || hex == intArray [ i ] ) ) ) return fileType ;
return "" ;
}
getMimeType ( fileType ) {
if ( fileTypes [ fileType ] ) return ` ${ fileTypes [ fileType ] . video ? "video" : "image" } / ${ fileType == "svg" ? "svg+xml" : fileType } ` ;
return "" ;
2022-02-11 18:57:35 +01:00
}
2020-08-14 14:37:10 +02:00
2020-09-19 20:49:33 +02:00
getImageSrc ( img ) {
if ( ! img ) return null ;
2023-03-08 15:53:48 +01:00
return ( typeof img == "string" ? img : ( img . proxy _url || img . src || ( typeof img . querySelector == "function" && img . querySelector ( "canvas" ) ? img . querySelector ( "canvas" ) . src : "" ) ) ) ;
2020-09-19 20:49:33 +02:00
}
2022-03-19 19:01:43 +01:00
getImageIndex ( messages , img ) {
2023-03-20 11:27:46 +01:00
return messages . findIndex ( i => i . messageId == img . messageId && ( messages . filter ( n => n . messageId == i . messageId ) . length < 2 || i . url && img . proxy _url && img . proxy _url . indexOf ( i . url ) > - 1 || i . proxy _url && img . proxy _url && img . proxy _url . indexOf ( i . proxy _url ) > - 1 ) ) ;
2022-03-19 19:01:43 +01:00
}
2023-03-20 11:27:46 +01:00
filterMessagesForImages ( messages , img , filterForVideos ) {
2022-12-16 11:40:29 +01:00
return messages . filter ( m => m && m . channel _id == img . channelId && ! BDFDB . LibraryStores . RelationshipStore . isBlocked ( m . author . id ) && ( firstViewedImage && m . id == firstViewedImage . messageId || m . id == img . messageId || m . embeds . filter ( e => e . image || e . thumbnail || e . video ) . length || m . attachments . filter ( a => ! a . filename . startsWith ( "SPOILER_" ) ) . length ) ) . map ( m => [ m . attachments , m . embeds ] . flat ( 10 ) . filter ( n => n ) . map ( i => Object . assign ( { messageId : m . id , channelId : img . channelId } , i , i . image , i . thumbnail , i . video ) ) ) . flat ( 10 ) . filter ( n => {
2022-12-01 20:44:25 +01:00
if ( ! n ) return false ;
2023-03-20 11:27:46 +01:00
let type = ( n . type || n . content _type || "" ) . split ( "/" ) [ 0 ] ;
if ( type && ( filterForVideos && type != "video" || ! filterForVideos && type == "video" ) ) return false ;
2022-12-01 20:44:25 +01:00
if ( ! n . content _type || img . proxy _url == n . proxy _url || img . proxy _url == n . url || img . proxy _url == n . href ) return true ;
let extension = ( n . content _type . split ( "/" ) [ 1 ] || "" ) . split ( "+" ) [ 0 ] || "" ;
2023-03-20 11:27:46 +01:00
if ( extension && ( ! fileTypes [ extension ] || this . settings . galleryFilter [ extension ] === false ) ) return false ;
2022-12-01 20:44:25 +01:00
return true ;
} ) ;
2020-09-19 20:49:33 +02:00
}
2023-03-20 11:27:46 +01:00
switchImages ( offset , filterForVideos ) {
2022-03-19 19:01:43 +01:00
const newIndex = parseInt ( cachedImages . index ) + parseInt ( offset ) ;
if ( newIndex < 0 || newIndex > ( cachedImages . amount - 1 ) ) return ;
cachedImages . index = newIndex ;
const oldImage = viewedImage ;
viewedImage = cachedImages . all [ cachedImages . index ] ;
if ( offset > 0 && ! cachedImages . lastReached && cachedImages . index == ( cachedImages . amount - 1 ) ) {
2022-09-27 14:48:10 +02:00
let channel = BDFDB . LibraryStores . ChannelStore . getChannel ( viewedImage . channelId ) ;
2022-03-19 19:01:43 +01:00
BDFDB . LibraryModules . APIUtils . get ( {
2022-10-19 11:37:19 +02:00
url : BDFDB . DiscordConstants . Endpoints . MESSAGES ( channel . id ) ,
2022-03-19 19:01:43 +01:00
query : BDFDB . LibraryModules . APIEncodeUtils . stringify ( {
2022-03-30 12:32:35 +02:00
channel _id : channel && channel . guild _id ? ( BDFDB . ChannelUtils . isThread ( channel ) && channel . parent _id || channel . id ) : null ,
2022-03-19 19:01:43 +01:00
has : "image" ,
2022-03-30 12:32:35 +02:00
include _nsfw : true ,
2022-10-19 11:37:19 +02:00
limit : 100 ,
after : ( BigInt ( cachedImages . newestId ) - BigInt ( 1 ) ) . toString ( )
2022-03-19 19:01:43 +01:00
} )
} ) . then ( result => {
2022-04-06 18:07:40 +02:00
if ( result && viewedImage ) {
2022-10-19 11:37:19 +02:00
const messages = result . body . flat ( 10 ) . reverse ( ) ;
2023-03-20 11:27:46 +01:00
Object . assign ( cachedImages , { all : this . filterForCopies ( [ ] . concat ( cachedImages . all , this . filterMessagesForImages ( messages , viewedImage , filterForVideos ) ) ) } ) ;
2022-10-19 11:37:19 +02:00
const index = this . getImageIndex ( cachedImages . all , viewedImage ) ;
cachedImages = Object . assign ( cachedImages , {
channelId : viewedImage . channelId ,
index : index ,
amount : cachedImages . all . length ,
newestId : messages [ messages . length - 1 ] ? messages [ messages . length - 1 ] . id : null ,
lastReached : index == ( cachedImages . all . length - 1 )
} ) ;
2023-01-22 20:08:42 +01:00
this . updateImageModal ( ) ;
2022-03-19 19:01:43 +01:00
}
2020-09-19 20:49:33 +02:00
} ) ;
2022-03-19 19:01:43 +01:00
}
if ( offset < 0 && ! cachedImages . firstReached && cachedImages . index == 0 ) {
2022-09-27 14:48:10 +02:00
let channel = BDFDB . LibraryStores . ChannelStore . getChannel ( viewedImage . channelId ) ;
2022-03-19 19:01:43 +01:00
BDFDB . LibraryModules . APIUtils . get ( {
2022-10-19 11:37:19 +02:00
url : BDFDB . DiscordConstants . Endpoints . MESSAGES ( channel . id ) ,
2022-03-19 19:01:43 +01:00
query : BDFDB . LibraryModules . APIEncodeUtils . stringify ( {
2022-03-30 12:32:35 +02:00
channel _id : channel && channel . guild _id ? ( BDFDB . ChannelUtils . isThread ( channel ) && channel . parent _id || channel . id ) : null ,
2022-03-19 19:01:43 +01:00
has : "image" ,
2022-03-30 12:32:35 +02:00
include _nsfw : true ,
2022-10-19 11:37:19 +02:00
limit : 100 ,
before : ( BigInt ( cachedImages . oldestId ) + BigInt ( 1 ) ) . toString ( )
2022-03-19 19:01:43 +01:00
} )
} ) . then ( result => {
2022-04-06 18:07:40 +02:00
if ( result && viewedImage ) {
2022-10-19 11:37:19 +02:00
const messages = result . body . flat ( 10 ) . reverse ( ) ;
2023-03-20 11:27:46 +01:00
Object . assign ( cachedImages , { all : this . filterForCopies ( [ ] . concat ( this . filterMessagesForImages ( messages , viewedImage , filterForVideos ) , cachedImages . all ) ) } ) ;
2022-10-19 11:37:19 +02:00
const index = this . getImageIndex ( cachedImages . all , viewedImage ) ;
cachedImages = Object . assign ( cachedImages , {
channelId : viewedImage . channelId ,
firstReached : index == 0 ,
oldestId : messages [ 0 ] ? messages [ 0 ] . id : null ,
index : index ,
amount : cachedImages . all . length
} ) ;
2023-01-22 20:08:42 +01:00
this . updateImageModal ( ) ;
2022-03-19 19:01:43 +01:00
}
} ) ;
}
let isVideo = this . isValid ( viewedImage . proxy _url , "video" ) ;
2023-01-24 10:39:40 +01:00
let thisViewedImage = viewedImage ;
2023-01-22 20:08:42 +01:00
switchedImageProps = {
animated : ! ! isVideo ,
2023-01-24 10:39:40 +01:00
original : thisViewedImage . proxy _url ,
placeholder : isVideo && ( thisViewedImage . thumbnail && thisViewedImage . thumbnail . proxy _url || thisViewedImage . proxy _url ) ,
src : thisViewedImage . proxy _url ,
width : thisViewedImage . width ,
height : thisViewedImage . height ,
2023-01-22 20:08:42 +01:00
children : ! isVideo ? null : ( videoData => BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Video , {
ignoreMaxSize : true ,
2023-03-20 11:27:46 +01:00
poster : this . getPosterUrl ( thisViewedImage . proxy _url ) ,
2023-01-24 10:39:40 +01:00
src : thisViewedImage . proxy _url ,
2023-01-22 20:08:42 +01:00
width : videoData . size . width ,
height : videoData . size . height ,
2023-01-24 10:39:40 +01:00
naturalWidth : thisViewedImage . width ,
naturalHeight : thisViewedImage . height ,
2023-01-22 20:08:42 +01:00
play : true ,
playOnHover : ! ! BDFDB . LibraryStores . AccessibilityStore . useReducedMotion
} ) )
} ;
this . updateImageModal ( ) ;
}
updateImageModal ( ) {
BDFDB . ReactUtils . forceUpdate ( BDFDB . ReactUtils . findOwner ( document . querySelector ( BDFDB . dotCN . imagemodal ) , { up : true , filter : n => n && n . stateNode && n . stateNode . props && n . stateNode . props . isTopModal && n . stateNode . props . modalKey } ) ) ;
2020-09-19 20:49:33 +02:00
}
2022-12-01 20:44:25 +01:00
filterForCopies ( messages ) {
let filtered = [ ] ;
2023-02-15 19:22:09 +01:00
for ( let message of messages ) if ( ! filtered . find ( n => n . messageId == message . messageId && n . id == message . id ) ) filtered . push ( message ) ;
2022-12-01 20:44:25 +01:00
return filtered ;
}
2023-11-02 11:06:30 +01:00
removeSizeInUrl ( url ) {
return ( url || "" ) . split ( "?width=" ) [ 0 ] . split ( "?height=" ) [ 0 ] . split ( "?size=" ) [ 0 ] . split ( "&width=" ) [ 0 ] . split ( "&height=" ) [ 0 ] . split ( "&size=" ) [ 0 ] ;
}
2022-03-19 19:01:43 +01:00
addListener ( eventType , type , callback ) {
if ( ! type || ! eventType || typeof callback != "function" ) return ;
if ( ! eventTypes [ type ] ) eventTypes [ type ] = [ ] ;
if ( ! eventTypes [ type ] . includes ( eventType ) ) eventTypes [ type ] . push ( eventType ) ;
document . removeEventListener ( eventType , document [ ` ${ eventType } ${ this . name } ${ type } Listener ` ] ) ;
delete document [ ` ${ eventType } ${ this . name } ${ type } Listener ` ] ;
document [ ` ${ eventType } ${ this . name } ${ type } Listener ` ] = callback ;
document . addEventListener ( eventType , document [ ` ${ eventType } ${ this . name } ${ type } Listener ` ] ) ;
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 ) {
2022-03-19 19:01:43 +01:00
if ( ! type || ! eventTypes [ type ] ) return ;
for ( let eventType of eventTypes [ type ] ) {
document . removeEventListener ( eventType , document [ ` ${ eventType } ${ this . name } ${ type } Listener ` ] ) ;
delete document [ ` ${ eventType } ${ this . name } ${ type } Listener ` ] ;
2020-09-19 20:49:33 +02:00
}
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}}" ,
2022-09-11 12:58:27 +02:00
context _imageactions : "Действия с изображения" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "Размер на обектива" ,
2021-02-09 14:51:23 +01:00
context _saveas : "Запазете {{var0}} като ..." ,
context _searchwith : "Търсете {{var0}} с ..." ,
2023-03-31 16:35:45 +02:00
context _streamactions : "Действия за визуализация на потока" ,
2022-09-11 12:58:27 +02:00
context _videoactions : "Видео действия" ,
2021-02-09 14:51:23 +01:00
context _view : "Преглед {{var0}}" ,
2023-03-31 16:35:45 +02:00
context _zoomspeed : "Скорост на мащабиране" ,
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}}" ,
2022-09-11 12:58:27 +02:00
context _imageactions : "Akce s obrázky" ,
2021-07-08 16:59:41 +02:00
context _lenssize : "Velikost lupy" ,
context _saveas : "Uložit {{var0}} jako..." ,
context _searchwith : "Hledat {{var0}} pomocí..." ,
2023-03-31 16:35:45 +02:00
context _streamactions : "Akce náhledu streamu" ,
2022-09-11 12:58:27 +02:00
context _videoactions : "Video akce" ,
2021-07-08 16:59:41 +02:00
context _view : "Zobrazit {{var0}}" ,
2023-03-31 16:35:45 +02:00
context _zoomspeed : "Rychlost zoomu" ,
2021-07-08 16:59:41 +02:00
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}}" ,
2022-09-11 12:58:27 +02:00
context _imageactions : "Billedhandlinger" ,
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 ..." ,
2023-03-31 16:35:45 +02:00
context _streamactions : "Stream forhåndsvisningshandlinger" ,
2022-09-11 12:58:27 +02:00
context _videoactions : "Videohandlinger" ,
2021-02-09 14:51:23 +01:00
context _view : "Se {{var0}}" ,
2023-03-31 16:35:45 +02:00
context _zoomspeed : "Zoomhastighed" ,
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" ,
2022-09-11 12:58:27 +02:00
context _imageactions : "Bildaktionen" ,
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 ..." ,
2023-03-31 16:35:45 +02:00
context _streamactions : "Stream-Vorschau-Aktionen" ,
2022-09-11 12:58:27 +02:00
context _videoactions : "Videoaktionen" ,
2021-02-09 14:51:23 +01:00
context _view : "{{var0}} ansehen" ,
2023-03-31 16:35:45 +02:00
context _zoomspeed : "Zoomgeschwindigkeit" ,
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}}" ,
2022-09-11 12:58:27 +02:00
context _imageactions : "Ενέργειες εικόνας" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "Μέγεθος φακού" ,
2021-02-09 14:51:23 +01:00
context _saveas : "Αποθήκευση {{var0}} ως ..." ,
context _searchwith : "Αναζήτηση {{var0}} με ..." ,
2023-03-31 16:35:45 +02:00
context _streamactions : "Ενέργειες προεπισκόπησης ροής" ,
2022-09-11 12:58:27 +02:00
context _videoactions : "Ενέργειες βίντεο" ,
2021-02-09 14:51:23 +01:00
context _view : "Προβολή {{var0}}" ,
2023-03-31 16:35:45 +02:00
context _zoomspeed : "Ταχύτητα ζουμ" ,
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}}" ,
2022-09-11 12:58:27 +02:00
context _imageactions : "Acciones de imagen" ,
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 ..." ,
2023-03-31 16:35:45 +02:00
context _streamactions : "Acciones de vista previa de transmisión" ,
2022-09-11 12:58:27 +02:00
context _videoactions : "Acciones de vídeo" ,
2021-02-09 14:51:23 +01:00
context _view : "Ver {{var0}}" ,
2023-03-31 16:35:45 +02:00
context _zoomspeed : "Velocidad de zoom" ,
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}}" ,
2022-09-11 12:58:27 +02:00
context _imageactions : "Kuvatoiminnot" ,
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}} ..." ,
2023-03-31 16:35:45 +02:00
context _streamactions : "Streamin esikatselutoiminnot" ,
2022-09-11 12:58:27 +02:00
context _videoactions : "Videotoiminnot" ,
2021-02-09 14:51:23 +01:00
context _view : "Näytä {{var0}}" ,
2023-03-31 16:35:45 +02:00
context _zoomspeed : "Zoomausnopeus" ,
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}}" ,
2022-09-11 12:58:27 +02:00
context _imageactions : "Actions sur les images" ,
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 ..." ,
2023-03-31 16:35:45 +02:00
context _streamactions : "Actions d'aperçu de flux" ,
2022-09-11 12:58:27 +02:00
context _videoactions : "Actions vidéo" ,
2021-02-09 14:51:23 +01:00
context _view : "Afficher {{var0}}" ,
2023-03-31 16:35:45 +02:00
context _zoomspeed : "Vitesse de zoom" ,
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}}" ,
2022-09-11 12:58:27 +02:00
context _imageactions : "छवि क्रियाएँ" ,
2021-07-08 16:59:41 +02:00
context _lenssize : "लेंस का आकार" ,
context _saveas : "{{var0}} को इस रूप में सेव करें..." ,
context _searchwith : "इसके साथ {{var0}} खोजें ..." ,
2023-03-31 16:35:45 +02:00
context _streamactions : "स्ट्रीम पूर्वावलोकन क्रियाएं" ,
2022-09-11 12:58:27 +02:00
context _videoactions : "वीडियो क्रिया" ,
2021-07-08 16:59:41 +02:00
context _view : "देखें {{var0}}" ,
2023-03-31 16:35:45 +02:00
context _zoomspeed : "ज़ूम गति" ,
2021-07-08 16:59:41 +02:00
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}}" ,
2022-09-11 12:58:27 +02:00
context _imageactions : "Radnje slike" ,
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 ..." ,
2023-03-31 16:35:45 +02:00
context _streamactions : "Radnje pregleda streama" ,
2022-09-11 12:58:27 +02:00
context _videoactions : "Video radnje" ,
2021-02-09 14:51:23 +01:00
context _view : "Pogledajte {{var0}}" ,
2023-03-31 16:35:45 +02:00
context _zoomspeed : "Brzina zumiranja" ,
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" ,
2022-09-11 12:58:27 +02:00
context _imageactions : "Képműveletek" ,
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:" ,
2023-03-31 16:35:45 +02:00
context _streamactions : "Stream előnézeti műveletek" ,
2022-09-11 12:58:27 +02:00
context _videoactions : "Videóműveletek" ,
2021-02-09 14:51:23 +01:00
context _view : "Megtekintés: {{var0}}" ,
2023-03-31 16:35:45 +02:00
context _zoomspeed : "Zoom sebesség" ,
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}}" ,
2022-09-11 12:58:27 +02:00
context _imageactions : "Azioni immagine" ,
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 ..." ,
2023-03-31 16:35:45 +02:00
context _streamactions : "Azioni di anteprima del flusso" ,
2022-09-11 12:58:27 +02:00
context _videoactions : "Azioni video" ,
2021-02-09 14:51:23 +01:00
context _view : "Visualizza {{var0}}" ,
2023-03-31 16:35:45 +02:00
context _zoomspeed : "Velocità dello zoom" ,
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}} をコピーします" ,
2022-09-11 12:58:27 +02:00
context _imageactions : "画像アクション" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "レンズサイズ" ,
2021-02-09 14:51:23 +01:00
context _saveas : "{{var0}} を...として保存します" ,
context _searchwith : "{{var0}} を...で検索" ,
2023-03-31 16:35:45 +02:00
context _streamactions : "ストリーム プレビュー アクション" ,
2022-09-11 12:58:27 +02:00
context _videoactions : "ビデオ アクション" ,
2021-02-09 14:51:23 +01:00
context _view : "{{var0}} を表示" ,
2023-03-31 16:35:45 +02:00
context _zoomspeed : "ズーム速度" ,
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}} 복사" ,
2022-09-11 12:58:27 +02:00
context _imageactions : "이미지 작업" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "렌즈 크기" ,
2021-02-09 14:51:23 +01:00
context _saveas : "{{var0}} 을 다른 이름으로 저장 ..." ,
context _searchwith : "{{var0}} 검색 ..." ,
2023-03-31 16:35:45 +02:00
context _streamactions : "스트림 미리보기 작업" ,
2022-09-11 12:58:27 +02:00
context _videoactions : "비디오 작업" ,
2021-02-09 14:51:23 +01:00
context _view : "{{var0}} 보기" ,
2023-03-31 16:35:45 +02:00
context _zoomspeed : "줌 속도" ,
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}}" ,
2022-09-11 12:58:27 +02:00
context _imageactions : "Vaizdo veiksmai" ,
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 ..." ,
2023-03-31 16:35:45 +02:00
context _streamactions : "Srauto peržiūros veiksmai" ,
2022-09-11 12:58:27 +02:00
context _videoactions : "Vaizdo įrašų veiksmai" ,
2021-02-09 14:51:23 +01:00
context _view : "Žiūrėti {{var0}}" ,
2023-03-31 16:35:45 +02:00
context _zoomspeed : "Priartinimo greitis" ,
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}}" ,
2022-09-11 12:58:27 +02:00
context _imageactions : "Afbeeldingsacties" ,
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 ..." ,
2023-03-31 16:35:45 +02:00
context _streamactions : "Stream Preview-acties" ,
2022-09-11 12:58:27 +02:00
context _videoactions : "Video-acties" ,
2021-02-09 14:51:23 +01:00
context _view : "Bekijk {{var0}}" ,
2023-03-31 16:35:45 +02:00
context _zoomspeed : "Zoom snelheid" ,
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}}" ,
2022-09-11 12:58:27 +02:00
context _imageactions : "Bildehandlinger" ,
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 ..." ,
2023-03-31 16:35:45 +02:00
context _streamactions : "Strøm forhåndsvisningshandlinger" ,
2022-09-11 12:58:27 +02:00
context _videoactions : "Videohandlinger" ,
2021-02-09 14:51:23 +01:00
context _view : "Vis {{var0}}" ,
2023-03-31 16:35:45 +02:00
context _zoomspeed : "Zoomhastighet" ,
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}}" ,
2022-09-11 12:58:27 +02:00
context _imageactions : "Działania związane z obrazem" ,
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ą ..." ,
2023-03-31 16:35:45 +02:00
context _streamactions : "Akcje podglądu strumienia" ,
2022-09-11 12:58:27 +02:00
context _videoactions : "Akcje wideo" ,
2021-02-09 14:51:23 +01:00
context _view : "Wyświetl {{var0}}" ,
2023-03-31 16:35:45 +02:00
context _zoomspeed : "Szybkość zoomu" ,
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}}" ,
2022-09-11 12:58:27 +02:00
context _imageactions : "Ações de imagem" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "Tamanho da lente" ,
2022-01-02 16:50:50 +01:00
context _saveas : "Salvar {{var0}} como ..." ,
context _searchwith : "Pesquisar {{var0}} com ..." ,
2023-03-31 16:35:45 +02:00
context _streamactions : "Ações de visualização de fluxo" ,
2022-09-11 12:58:27 +02:00
context _videoactions : "Ações de vídeo" ,
2022-01-02 16:50:50 +01:00
context _view : "Visualizar {{var0}}" ,
2023-03-31 16:35:45 +02:00
context _zoomspeed : "Velocidade do zoom" ,
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}}" ,
2022-09-11 12:58:27 +02:00
context _imageactions : "Acțiuni de imagine" ,
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 ..." ,
2023-03-31 16:35:45 +02:00
context _streamactions : "Acțiuni de previzualizare în flux" ,
2022-09-11 12:58:27 +02:00
context _videoactions : "Acțiuni video" ,
2021-02-09 14:51:23 +01:00
context _view : "Vizualizați {{var0}}" ,
2023-03-31 16:35:45 +02:00
context _zoomspeed : "Viteza de zoom" ,
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}}" ,
2022-09-11 12:58:27 +02:00
context _imageactions : "Действия с изображением" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "Размер линзы" ,
2021-02-09 14:51:23 +01:00
context _saveas : "Сохранить {{var0}} как ..." ,
context _searchwith : "Искать {{var0}} с помощью ..." ,
2023-03-31 16:35:45 +02:00
context _streamactions : "Действия предварительного просмотра трансляции" ,
2022-09-11 12:58:27 +02:00
context _videoactions : "Действия с видео" ,
2021-02-09 14:51:23 +01:00
context _view : "Посмотреть {{var0}}" ,
2023-03-31 16:35:45 +02:00
context _zoomspeed : "Скорость масштабирования" ,
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}}" ,
2022-09-11 12:58:27 +02:00
context _imageactions : "Bildåtgärder" ,
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 ..." ,
2023-03-31 16:35:45 +02:00
context _streamactions : "Streama förhandsgranskningsåtgärder" ,
2022-09-11 12:58:27 +02:00
context _videoactions : "Videoåtgärder" ,
2021-02-09 14:51:23 +01:00
context _view : "Visa {{var0}}" ,
2023-03-31 16:35:45 +02:00
context _zoomspeed : "Zoomhastighet" ,
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}}" ,
2022-09-11 12:58:27 +02:00
context _imageactions : "การทำงานของรูปภาพ" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "ขนาดเลนส์" ,
2021-02-22 20:52:51 +01:00
context _saveas : "บันทึก{{var0}}เป็น ..." ,
context _searchwith : "ค้นหา{{var0}} ้วย ..." ,
2023-03-31 16:35:45 +02:00
context _streamactions : "การดำเนินการแสดงตัวอย่างสตรีม" ,
2022-09-11 12:58:27 +02:00
context _videoactions : "การกระทำของวิดีโอ" ,
2021-02-22 20:52:51 +01:00
context _view : "ดู{{var0}}" ,
2023-03-31 16:35:45 +02:00
context _zoomspeed : "ความเร็วในการซูม" ,
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" ,
2022-09-11 12:58:27 +02:00
context _imageactions : "Görüntü Eylemleri" ,
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 ..." ,
2023-03-31 16:35:45 +02:00
context _streamactions : "Akı ş Önizleme İşlemleri" ,
2022-09-11 12:58:27 +02:00
context _videoactions : "Video Eylemleri" ,
2021-02-09 14:51:23 +01:00
context _view : "{{var0}} görüntüle" ,
2023-03-31 16:35:45 +02:00
context _zoomspeed : "yakı nlaştı rma hı zı " ,
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}}" ,
2022-09-11 12:58:27 +02:00
context _imageactions : "Дії із зображеннями" ,
2020-12-21 19:56:36 +01:00
context _lenssize : "Розмір лінзи" ,
2021-02-09 14:51:23 +01:00
context _saveas : "Збережіть {{var0}} як ..." ,
context _searchwith : "Шукати {{var0}} за допомогою ..." ,
2023-03-31 16:35:45 +02:00
context _streamactions : "Дії попереднього перегляду потоку" ,
2022-09-11 12:58:27 +02:00
context _videoactions : "Відео дії" ,
2021-02-09 14:51:23 +01:00
context _view : "Переглянути {{var0}}" ,
2023-03-31 16:35:45 +02:00
context _zoomspeed : "Швидкість масштабування" ,
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}}" ,
2022-09-11 12:58:27 +02:00
context _imageactions : "Hành động hình ảnh" ,
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 ..." ,
2023-03-31 16:35:45 +02:00
context _streamactions : "Tác vụ xem trước luồng" ,
2022-09-11 12:58:27 +02:00
context _videoactions : "Hành động video" ,
2021-02-09 14:51:23 +01:00
context _view : "Xem {{var0}}" ,
2023-03-31 16:35:45 +02:00
context _zoomspeed : "tốc độ thu phóng" ,
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}}" ,
2022-09-11 12:58:27 +02:00
context _imageactions : "图像动作" ,
2021-12-15 21:44:54 +01:00
context _lenssize : "缩放尺寸" ,
context _saveas : "将 {{var0}} 另存到..." ,
context _searchwith : "搜索 {{var0}} 使用..." ,
2023-03-31 16:35:45 +02:00
context _streamactions : "流预览操作" ,
2022-09-11 12:58:27 +02:00
context _videoactions : "视频动作" ,
2021-02-09 14:51:23 +01:00
context _view : "查看 {{var0}}" ,
2023-03-31 16:35:45 +02:00
context _zoomspeed : "变焦速度" ,
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}} 已复制到剪贴板" ,
2021-12-15 21:44:54 +01:00
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}}" ,
2022-09-11 12:58:27 +02:00
context _imageactions : "圖像動作" ,
2021-12-15 21:44:54 +01:00
context _lenssize : "縮放尺寸" ,
context _saveas : "將 {{var0}} 另存到..." ,
context _searchwith : "搜尋 {{var0}} 使用..." ,
2023-03-31 16:35:45 +02:00
context _streamactions : "流預覽操作" ,
2022-09-11 12:58:27 +02:00
context _videoactions : "視頻動作" ,
2021-12-15 21:44:54 +01:00
context _view : "預覽 {{var0}}" ,
2023-03-31 16:35:45 +02:00
context _zoomspeed : "变焦速度" ,
2021-12-15 21:44:54 +01:00
submenu _disabled : "全部關閉" ,
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}}" ,
2022-09-11 12:58:27 +02:00
context _imageactions : "Image Actions" ,
2022-03-03 18:43:25 +01:00
context _lenssize : "Lens Size" ,
2021-02-09 14:51:23 +01:00
context _saveas : "Save {{var0}} as ..." ,
context _searchwith : "Search {{var0}} with ..." ,
2023-03-31 16:35:45 +02:00
context _streamactions : "Stream Preview Actions" ,
2022-09-11 12:58:27 +02:00
context _videoactions : "Video Actions" ,
2021-02-09 14:51:23 +01:00
context _view : "View {{var0}}" ,
2023-03-31 16:35:45 +02:00
context _zoomspeed : "Zoom speed" ,
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
} ;
}
}
} ;
2022-09-01 14:40:11 +02:00
} ) ( window . BDFDB _Global . PluginUtils . buildPlugin ( changeLog ) ) ;
2023-03-31 06:59:05 +02:00
} ) ( ) ;