Update ImageUtilities.plugin.js

This commit is contained in:
Mirco Wittrien 2020-12-15 15:03:09 +01:00
parent b2c97f92db
commit 9c0bb44b6f
1 changed files with 217 additions and 119 deletions

View File

@ -14,12 +14,15 @@ module.exports = (_ => {
"info": {
"name": "ImageUtilities",
"author": "DevilBro",
"version": "4.2.1",
"version": "4.2.2",
"description": "Add a handful of options for images/emotes/avatars (direct download, reverse image search, zoom, copy image link, copy image to clipboard, gallery mode)"
},
"changeLog": {
"improved": {
"Download locations": "Merged 'save' and 'save as' entry, clicking it opens the save as modal, and hovering over it opens a submenu for preset paths, you can add your own download locations in the plugin settings"
},
"fixed": {
"New React Structure": "Fixed for new internal react structure"
"Slow modal transitions": "Fixed issue where the css of the plugin would cause render slow downds for modals"
}
}
};
@ -65,7 +68,7 @@ module.exports = (_ => {
} : (([Plugin, BDFDB]) => {
const imgUrlReplaceString = "DEVILBRO_BD_REVERSEIMAGESEARCH_REPLACE_IMAGEURL";
var firedEvents = [], clickedImage;
var settings = {}, inputs = {}, amounts = {}, zoomSettings = {}, engines = {}, enabledEngines = {};
var settings = {}, amounts = {}, zoomSettings = {}, engines = {}, enabledEngines = {}, ownLocations = {}, downloadsFolder;
const ImageDetails = class ImageDetails extends BdApi.React.Component {
componentDidMount() {
@ -130,27 +133,24 @@ module.exports = (_ => {
addEmojiEntry: {value: true, inner: true, description: "Custom Emojis/Emotes"}
},
amounts: {
hoverDelay: {value: 0, min: 0, description: "Image Tooltip delay (in millisec)"}
},
inputs: {
downloadLocation: {value: "", childProps: {type: "file", searchFolders: true}, description: "Download Location"},
hoverDelay: {value: 0, min: 0, description: "Image Tooltip delay (in millisec)"}
},
zoomSettings: {
zoomlevel: {value: 2, digits: 1, minValue: 1, maxValue: 20, unit: "x", label: "ACCESSIBILITY_ZOOM_LEVEL_LABEL"},
lensesize: {value: 200, digits: 0, minValue: 50, maxValue: 5000, unit: "px", label: "context_lenssize_text"}
lensesize: {value: 200, digits: 0, minValue: 50, maxValue: 5000, unit: "px", label: "context_lenssize_text"}
},
engines: {
_all: {value: true, name: BDFDB.LanguageUtils.LanguageStrings.FORM_LABEL_ALL, url: null},
Baidu: {value: true, name: "Baidu", url: "http://image.baidu.com/pcdutu?queryImageUrl=" + imgUrlReplaceString},
Bing: {value: true, name: "Bing", url: "https://www.bing.com/images/search?q=imgurl: " + imgUrlReplaceString + "&view=detailv2&iss=sbi&FORM=IRSBIQ"},
Google: {value: true, name: "Google", url: "https://images.google.com/searchbyimage?image_url=" + imgUrlReplaceString},
Google: {value: true, name: "Google", url: "https://images.google.com/searchbyimage?image_url=" + imgUrlReplaceString},
IQDB: {value: true, name: "IQDB", url: "https://iqdb.org/?url=" + imgUrlReplaceString},
Reddit: {value: true, name: "Reddit", url: "http://karmadecay.com/search?q=" + 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},
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"}
Yandex: {value: true, name: "Yandex", url: "https://yandex.com/images/search?url=" + imgUrlReplaceString + "&rpt=imageview"}
}
};
@ -172,11 +172,8 @@ module.exports = (_ => {
visibility: hidden;
max-width: 1px;
}
${BDFDB.dotCN.imagemodal}[style*="opacity: 0;"] > * {
display: none !important;
}
${BDFDB.dotCN._imageutilitiesgallery}:not([style*="opacity: 0;"]),
${BDFDB.dotCN._imageutilitiesdetailsadded}:not([style*="opacity: 0;"]) {
${BDFDB.dotCN._imageutilitiesgallery},
${BDFDB.dotCN._imageutilitiesdetailsadded} {
transform: unset !important;
}
${BDFDB.dotCN._imageutilitiessibling} {
@ -268,65 +265,169 @@ module.exports = (_ => {
}
getSettingsPanel (collapseStates = {}) {
let settingsPanel, settingsItems = [];
let settingsPanel;
settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.CollapseContainer, {
title: "Settings",
return settingsPanel = BDFDB.PluginUtils.createSettingsPanel(this, {
collapseStates: collapseStates,
children: Object.keys(settings).map(key => !this.defaults.settings[key].inner && BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsSaveItem, {
type: "Switch",
plugin: this,
keys: ["settings", key],
label: this.defaults.settings[key].description,
value: settings[key]
})).concat(Object.keys(amounts).map(key => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsSaveItem, {
type: "TextInput",
plugin: this,
keys: ["amounts", key],
label: this.defaults.amounts[key].description,
basis: "50%",
childProps: {type: "number"},
min: this.defaults.amounts[key].min,
max: this.defaults.amounts[key].max,
value: amounts[key]
}))).concat(Object.keys(inputs).map(key => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsSaveItem, {
type: "TextInput",
plugin: this,
keys: ["inputs", key],
label: this.defaults.inputs[key].description,
basis: "70%",
childProps: this.defaults.inputs[key].childProps,
value: key == "downloadLocation" ? this.getDownloadLocation() : inputs[key]
}))).filter(n => n)
}));
settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.CollapseContainer, {
title: "Context Menu Entries",
collapseStates: collapseStates,
children: [BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormComponents.FormTitle, {
className: BDFDB.disCN.marginbottom4,
tag: BDFDB.LibraryComponents.FormComponents.FormTitle.Tags.H3,
children: "Add additional Context Menu Entry for: "
})].concat(Object.keys(settings).map(key => this.defaults.settings[key].inner && BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsSaveItem, {
type: "Switch",
plugin: this,
keys: ["settings", key],
label: this.defaults.settings[key].description,
value: settings[key]
})))
}));
settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.CollapseContainer, {
title: "Search Engines",
collapseStates: collapseStates,
children: Object.keys(engines).filter(n => n && n != "_all").map(key => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsSaveItem, {
type: "Switch",
plugin: this,
keys: ["engines", key],
label: this.defaults.engines[key].name,
value: engines[key]
}))
}));
return settingsPanel = BDFDB.PluginUtils.createSettingsPanel(this, settingsItems);
children: _ => {
let settingsItems = [];
settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.CollapseContainer, {
title: "Settings",
collapseStates: collapseStates,
children: Object.keys(settings).map(key => !this.defaults.settings[key].inner && BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsSaveItem, {
type: "Switch",
plugin: this,
keys: ["settings", key],
label: this.defaults.settings[key].description,
value: settings[key]
})).concat(Object.keys(amounts).map(key => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsSaveItem, {
type: "TextInput",
plugin: this,
keys: ["amounts", key],
label: this.defaults.amounts[key].description,
basis: "50%",
childProps: {type: "number"},
min: this.defaults.amounts[key].min,
max: this.defaults.amounts[key].max,
value: amounts[key]
}))).filter(n => n)
}));
settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.CollapseContainer, {
title: "Download Locations",
collapseStates: collapseStates,
children: [
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormComponents.FormTitle, {
className: BDFDB.disCN.marginbottom4,
tag: BDFDB.LibraryComponents.FormComponents.FormTitle.Tags.H3,
children: "Add additional Download Locations: "
}),
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex, {
className: BDFDB.disCN.marginbottom8,
align: BDFDB.LibraryComponents.Flex.Align.END,
children: [
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex.Child, {
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormComponents.FormItem, {
title: "Name:",
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TextInput, {
className: "input-newlocation input-name",
value: "",
placeholder: "Name"
})
})
}),
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex.Child, {
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormComponents.FormItem, {
title: "Location:",
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TextInput, {
className: "input-newlocation input-location",
value: "",
placeholder: "Location"
})
})
}),
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Button, {
style: {marginBottom: 1},
onClick: _ => {
for (let input of settingsPanel.props._node.querySelectorAll(".input-newlocation " + BDFDB.dotCN.input)) if (!input.value || input.value.length == 0 || input.value.trim().length == 0) return BDFDB.NotificationUtils.toast("Fill out all fields to add a new location.", {type: "danger"});
let name = settingsPanel.props._node.querySelector(".input-name " + BDFDB.dotCN.input).value.trim();
let location = settingsPanel.props._node.querySelector(".input-location " + BDFDB.dotCN.input).value.trim();
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"});
else {
ownLocations[name] = location;
BDFDB.DataUtils.save(ownLocations, this, "ownLocations");
BDFDB.PluginUtils.refreshSettingsPanel(this, settingsPanel, collapseStates);
}
},
children: BDFDB.LanguageUtils.LanguageStrings.ADD
})
]
})
].concat(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsPanelList, {
title: "Your own Download Locations:",
dividerTop: true,
children: Object.keys(ownLocations).map(name => {
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, {
value: name,
placeholder: name,
size: BDFDB.LibraryComponents.TextInput.Sizes.MINI,
maxLength: 100000000000000000000,
style: {marginRight: 6},
disabled: !editable,
onChange: !editable ? null : value => {
ownLocations[value] = ownLocations[name];
delete ownLocations[name];
BDFDB.DataUtils.save(ownLocations, this, "ownLocations");
}
})
}),
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex.Child, {
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TextInput, {
value: ownLocations[name],
placeholder: ownLocations[name],
size: BDFDB.LibraryComponents.TextInput.Sizes.MINI,
maxLength: 100000000000000000000,
disabled: !editable,
onChange: !editable ? null : value => {
ownLocations[name] = value;
BDFDB.DataUtils.save(ownLocations, this, "ownLocations");
}
})
})
],
noRemove: !editable,
onRemove: !editable ? null : _ => {
delete ownLocations[name];
BDFDB.DataUtils.save(ownLocations, this, "ownLocations");
BDFDB.PluginUtils.refreshSettingsPanel(this, settingsPanel);
}
});
})
})).filter(n => n)
}));
settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.CollapseContainer, {
title: "Context Menu Entries",
collapseStates: collapseStates,
children: [BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormComponents.FormTitle, {
className: BDFDB.disCN.marginbottom4,
tag: BDFDB.LibraryComponents.FormComponents.FormTitle.Tags.H3,
children: "Add additional Context Menu Entry for: "
})].concat(Object.keys(settings).map(key => this.defaults.settings[key].inner && BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsSaveItem, {
type: "Switch",
plugin: this,
keys: ["settings", key],
label: this.defaults.settings[key].description,
value: settings[key]
})))
}));
settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.CollapseContainer, {
title: "Search Engines",
collapseStates: collapseStates,
children: Object.keys(engines).filter(n => n && n != "_all").map(key => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsSaveItem, {
type: "Switch",
plugin: this,
keys: ["engines", key],
label: this.defaults.engines[key].name,
value: engines[key]
}))
}));
return settingsItems;
}
});
}
onSettingsClosed () {
@ -339,10 +440,10 @@ module.exports = (_ => {
forceUpdateAll () {
settings = BDFDB.DataUtils.get(this, "settings");
amounts = BDFDB.DataUtils.get(this, "amounts");
inputs = BDFDB.DataUtils.get(this, "inputs");
zoomSettings = BDFDB.DataUtils.get(this, "zoomSettings");
engines = BDFDB.DataUtils.get(this, "engines");
enabledEngines = BDFDB.ObjectUtils.filter(engines, n => n);
ownLocations = Object.assign({"Downloads": this.getDownloadLocation()}, BDFDB.DataUtils.load(this, "ownLocations"));
BDFDB.PatchUtils.forceAllUpdates(this);
BDFDB.MessageUtils.rerenderAll();
@ -442,28 +543,21 @@ module.exports = (_ => {
img.src = url;
}
}),
BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuItem, {
label: this.labels.context_saveimage_text,
id: BDFDB.ContextMenuUtils.createItemId(this.name, "download-image"),
action: _ => {
BDFDB.LibraryRequires.request(url, {encoding: null}, (error, response, body) => {
let path = this.getDownloadLocation();
if (error) BDFDB.NotificationUtils.toast(this.labels.toast_saveimage_failed.replace("{{path}}", path), {type: "error"});
else {
BDFDB.LibraryRequires.fs.writeFile(this.getFileName(path, url.split("/").pop().split(".").slice(0, -1).join("."), response.headers["content-type"].split("/").pop().split("+")[0], 0), body, error => {
if (error) BDFDB.NotificationUtils.toast(this.labels.toast_saveimage_failed.replace("{{path}}", path), {type: "error"});
else BDFDB.NotificationUtils.toast(this.labels.toast_saveimage_success.replace("{{path}}", path), {type: "success"});
});
}
});
}
}),
BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuItem, {
label: this.labels.context_saveimageas_text,
id: BDFDB.ContextMenuUtils.createItemId(this.name, "download-image-as"),
action: _ => {
this.downloadImage(url);
}
this.downloadImageAs(url);
},
children: BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuGroup, {
children: Object.keys(ownLocations).map((name, i) => BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuItem, {
id: BDFDB.ContextMenuUtils.createItemId(this.name, "download", name, i),
label: name,
action: _ => {
this.downloadImage(url, ownLocations[name]);
}
}))
})
}),
!this.isCopyable(url) ? null : BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuItem, {
label: this.labels.context_copyimage_text,
@ -557,7 +651,18 @@ module.exports = (_ => {
children: this.labels.context_saveimageas_text,
onClick: event => {
BDFDB.ListenerUtils.stopEvent(event);
this.downloadImage(url);
this.downloadImageAs(url);
},
onContextMenu: event => {
BDFDB.ContextMenuUtils.open(this, event, BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuGroup, {
children: Object.keys(ownLocations).map((name, i) => BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuItem, {
id: BDFDB.ContextMenuUtils.createItemId(this.name, "download", name, i),
label: name,
action: _ => {
this.downloadImage(url, ownLocations[name]);
}
}))
}));
}
})
],
@ -823,7 +928,21 @@ module.exports = (_ => {
return file && (url.startsWith("https://images-ext-2.discordapp.net/") || file.endsWith(".jpg") || file.endsWith(".jpeg") || file.endsWith(".png") || file.endsWith(".gif") || file.endsWith(".apng") || file.endsWith(".webp"));
}
downloadImage (url) {
downloadImage (url, path) {
url = url.startsWith("/assets") ? (window.location.origin + url) : url;
BDFDB.LibraryRequires.request(url, {encoding: null}, (error, response, body) => {
if (error) BDFDB.NotificationUtils.toast(this.labels.toast_saveimage_failed.replace("{{path}}", path), {type: "error"});
else {
BDFDB.LibraryRequires.fs.writeFile(this.getFileName(path, url.split("/").pop().split(".").slice(0, -1).join("."), response.headers["content-type"].split("/").pop().split("+")[0], 0), body, error => {
if (error) BDFDB.NotificationUtils.toast(this.labels.toast_saveimage_failed.replace("{{path}}", path), {type: "error"});
else BDFDB.NotificationUtils.toast(this.labels.toast_saveimage_success.replace("{{path}}", path), {type: "success"});
});
}
});
}
downloadImageAs (url) {
url = url.startsWith("/assets") ? (window.location.origin + url) : url;
BDFDB.LibraryRequires.request(url, {encoding: null}, (error, response, body) => {
let hrefURL = window.URL.createObjectURL(new Blob([body]));
let tempLink = document.createElement("a");
@ -853,11 +972,11 @@ module.exports = (_ => {
}
getDownloadLocation () {
if (BDFDB.LibraryRequires.fs.existsSync(inputs.downloadLocation)) return inputs.downloadLocation;
if (downloadsFolder && BDFDB.LibraryRequires.fs.existsSync(downloadsFolder)) return downloadsFolder;
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 downloadPath;
return BDFDB.BDUtils.getPluginsFolder();
if (downloadPath && BDFDB.LibraryRequires.fs.existsSync(downloadPath)) return downloadsFolder = downloadPath;
return downloadsFolder = BDFDB.BDUtils.getPluginsFolder();
}
getFileName (path, fileName, extension, i) {
@ -979,7 +1098,6 @@ module.exports = (_ => {
toast_saveimage_success: "Slika je spremljena u '{{path}}'",
toast_saveimage_failed: "Spremanje slike na '{{path}}' nije uspjelo",
context_viewimage_text: "Pogledati sliku",
context_saveimage_text: "Spremiti sliku",
context_saveimageas_text: "Spremi sliku kao ...",
context_copyimage_text: "Kopiraj sliku",
context_copyimagelink_text: "Kopirajte vezu slike",
@ -995,7 +1113,6 @@ module.exports = (_ => {
toast_saveimage_success: "Billedet er gemt i '{{path}}'",
toast_saveimage_failed: "Kunne ikke gemme billedet i '{{path}}'",
context_viewimage_text: "Se billede",
context_saveimage_text: "Gem billede",
context_saveimageas_text: "Gem billede som ...",
context_copyimage_text: "Kopier billede",
context_copyimagelink_text: "Kopier billedlink",
@ -1011,7 +1128,6 @@ module.exports = (_ => {
toast_saveimage_success: "Bild wurde in '{{path}}' gespeichert",
toast_saveimage_failed: "Bild konnte nicht in '{{path}}' gespeichert werden",
context_viewimage_text: "Bild ansehen",
context_saveimage_text: "Bild speichern",
context_saveimageas_text: "Bild speichern unter ...",
context_copyimage_text: "Bild kopieren",
context_copyimagelink_text: "Bildadresse kopieren",
@ -1027,7 +1143,6 @@ module.exports = (_ => {
toast_saveimage_success: "Imagen guardada en '{{path}}'",
toast_saveimage_failed: "No se pudo guardar la imagen en '{{path}}'",
context_viewimage_text: "Ver imagen",
context_saveimage_text: "Guardar imagen",
context_saveimageas_text: "Guardar imagen como ...",
context_copyimage_text: "Copiar imagen",
context_copyimagelink_text: "Copiar enlace de imagen",
@ -1043,7 +1158,6 @@ module.exports = (_ => {
toast_saveimage_success: "Image enregistrée dans '{{path}}'",
toast_saveimage_failed: "Échec de l'enregistrement de l'image dans '{{path}}'",
context_viewimage_text: "Voir l'image",
context_saveimage_text: "Enregistrer l'image",
context_saveimageas_text: "Enregistrer l'image sous ...",
context_copyimage_text: "Copier l'image",
context_copyimagelink_text: "Copier le lien de l'image",
@ -1059,7 +1173,6 @@ module.exports = (_ => {
toast_saveimage_success: "Immagine salvata in '{{path}}'",
toast_saveimage_failed: "Impossibile salvare l'immagine in '{{path}}'",
context_viewimage_text: "Guarda l'immagine",
context_saveimage_text: "Salva immagine",
context_saveimageas_text: "Salva l'immagine come ...",
context_copyimage_text: "Copia l'immagine",
context_copyimagelink_text: "Copia link immagine",
@ -1075,7 +1188,6 @@ module.exports = (_ => {
toast_saveimage_success: "Afbeelding opgeslagen in '{{path}}'",
toast_saveimage_failed: "Kan afbeelding niet opslaan in '{{path}}'",
context_viewimage_text: "Bekijk afbeelding",
context_saveimage_text: "Sla afbeelding op",
context_saveimageas_text: "Sla afbeelding op als ...",
context_copyimage_text: "Kopieer afbeelding",
context_copyimagelink_text: "Kopieer afbeeldingslink",
@ -1091,7 +1203,6 @@ module.exports = (_ => {
toast_saveimage_success: "Bilde lagret i '{{path}}'",
toast_saveimage_failed: "Kunne ikke lagre bildet i '{{path}}'",
context_viewimage_text: "Vis bilde",
context_saveimage_text: "Lagre bildet",
context_saveimageas_text: "Lagre bildet som ...",
context_copyimage_text: "Kopier bilde",
context_copyimagelink_text: "Kopier bildelink",
@ -1107,7 +1218,6 @@ module.exports = (_ => {
toast_saveimage_success: "Obraz zapisany w '{{path}}'",
toast_saveimage_failed: "Nie udało się zapisać obrazu w '{{path}}'",
context_viewimage_text: "Zobacz obraz",
context_saveimage_text: "Zapisać obraz",
context_saveimageas_text: "Zapisz obraz jako ...",
context_copyimage_text: "Skopiuj obraz",
context_copyimagelink_text: "Kopiuj łącze do obrazu",
@ -1123,7 +1233,6 @@ module.exports = (_ => {
toast_saveimage_success: "Imagem salva em '{{path}}'",
toast_saveimage_failed: "Falha ao salvar imagem em '{{path}}'",
context_viewimage_text: "Ver imagem",
context_saveimage_text: "Salvar imagem",
context_saveimageas_text: "Salvar imagem como ...",
context_copyimage_text: "Copiar imagem",
context_copyimagelink_text: "Copiar link da imagem",
@ -1139,7 +1248,6 @@ module.exports = (_ => {
toast_saveimage_success: "Kuva tallennettu '{{path}}'",
toast_saveimage_failed: "Kuvan tallentaminen epäonnistui '{{path}}'",
context_viewimage_text: "Näytä kuva",
context_saveimage_text: "Tallenna kuva",
context_saveimageas_text: "Tallenna kuva nimellä ...",
context_copyimage_text: "Kopioi kuva",
context_copyimagelink_text: "Kopioi kuvan linkki",
@ -1155,7 +1263,6 @@ module.exports = (_ => {
toast_saveimage_success: "Bild sparad i '{{path}}'",
toast_saveimage_failed: "Det gick inte att spara bilden i '{{path}}'",
context_viewimage_text: "Se bild",
context_saveimage_text: "Spara bild",
context_saveimageas_text: "Spara bild som ...",
context_copyimage_text: "Kopiera bild",
context_copyimagelink_text: "Kopiera bildlänk",
@ -1171,7 +1278,6 @@ module.exports = (_ => {
toast_saveimage_success: "Resim '{{path}}' konumuna kaydedildi",
toast_saveimage_failed: "'{{path}}' konumuna resim kaydedilemedi",
context_viewimage_text: "Resmi görüntüle",
context_saveimage_text: "Resmi kaydet",
context_saveimageas_text: "Resmi farklı kaydet ...",
context_copyimage_text: "Resmi kopyala",
context_copyimagelink_text: "Görüntü Bağlantısını kopyala",
@ -1187,7 +1293,6 @@ module.exports = (_ => {
toast_saveimage_success: "Obrázek uložený v '{{path}}'",
toast_saveimage_failed: "Nepodařilo se uložit obrázek do '{{path}}'",
context_viewimage_text: "Zobrazit obrázek",
context_saveimage_text: "Uložit obrázek",
context_saveimageas_text: "Uložit obrázek jako ...",
context_copyimage_text: "Kopírovat obrázek",
context_copyimagelink_text: "Kopírovat odkaz na obrázek",
@ -1203,7 +1308,6 @@ module.exports = (_ => {
toast_saveimage_success: "Изображението е запазено в '{{path}}'",
toast_saveimage_failed: "Неуспешно запазване на изображението в '{{path}}'",
context_viewimage_text: "Вижте изображението",
context_saveimage_text: "Запазването на изображението",
context_saveimageas_text: "Запази изображението като ...",
context_copyimage_text: "Копирай изображение",
context_copyimagelink_text: "Копиране на изображението",
@ -1219,7 +1323,6 @@ module.exports = (_ => {
toast_saveimage_success: "Изображение сохранено в '{{path}}'",
toast_saveimage_failed: "Не удалось сохранить изображение в '{{path}}'",
context_viewimage_text: "Просмотр изображения",
context_saveimage_text: "Сохранить изображение",
context_saveimageas_text: "Сохранить изображение как ...",
context_copyimage_text: "Копировать изображение",
context_copyimagelink_text: "Копировать ссылку на изображение",
@ -1235,7 +1338,6 @@ module.exports = (_ => {
toast_saveimage_success: "Зображення збережено на '{{path}}'",
toast_saveimage_failed: "Не вдалося зберегти зображення на '{{path}}'",
context_viewimage_text: "Переглянути зображення",
context_saveimage_text: "Зберегти зображення",
context_saveimageas_text: "Зберегти зображення як ...",
context_copyimage_text: "Скопіювати зображення",
context_copyimagelink_text: "Скопіюйте посилання на зображення",
@ -1251,7 +1353,6 @@ module.exports = (_ => {
toast_saveimage_success: "画像は'{{path}}'に保存されました",
toast_saveimage_failed: "画像を'{{path}}'に保存できませんでした",
context_viewimage_text: "画像を見る",
context_saveimage_text: "画像を保存",
context_saveimageas_text: "画像を保存します ...",
context_copyimage_text: "画像をコピー",
context_copyimagelink_text: "画像リンクをコピー",
@ -1267,7 +1368,6 @@ module.exports = (_ => {
toast_saveimage_success: "圖片保存在'{{path}}'中",
toast_saveimage_failed: "無法將圖像保存到'{{path}}'中",
context_viewimage_text: "看圖片",
context_saveimage_text: "保存圖片",
context_saveimageas_text: "將圖像另存為...",
context_copyimage_text: "複製圖片",
context_copyimagelink_text: "複製圖像鏈接",
@ -1283,7 +1383,6 @@ module.exports = (_ => {
toast_saveimage_success: "'{{path}}'에 저장된 이미지",
toast_saveimage_failed: "'{{path}}'에 이미지를 저장하지 못했습니다",
context_viewimage_text: "이미지보기",
context_saveimage_text: "이미지를 저장",
context_saveimageas_text: "다른 이름으로 이미지 저장 ...",
context_copyimage_text: "복사 이미지",
context_copyimagelink_text: "이미지 링크 복사",
@ -1299,7 +1398,6 @@ module.exports = (_ => {
toast_saveimage_success: "Saved image in '{{path}}'",
toast_saveimage_failed: "Failed to save image in '{{path}}'",
context_viewimage_text: "View Image",
context_saveimage_text: "Save Image",
context_saveimageas_text: "Save Image as ...",
context_copyimage_text: "Copy Image",
context_copyimagelink_text: "Copy Image Link",