diff --git a/CHANGELOG.md b/CHANGELOG.md index ee9c4810a..20b5c9cb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,13 +9,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### 馃殌 New Features - Open file location in context menu [`339bcc0`](https://github.com/ollm/OpenComic/commit/339bcc0b21eab52228b7762c92c993d06489aa48) +- Option in the context menu to add and remove posters using local artwork assets ### 馃悰 Bug Fixes - Gamepad icons not showing in distribution version [`249640d`](https://github.com/ollm/OpenComic/commit/249640d57f3d5768661b63c0ddf8525a02e44d25) - Go back in gamepad menus [`b2719e5`](https://github.com/ollm/OpenComic/commit/b2719e5e782659f249ce7a6ba6c8b94fe40a3407) - Wrong detection of folder images in some cases [`425a137`](https://github.com/ollm/OpenComic/commit/425a137333114739cb4f0b1e92e4606f2c9da87c) -- Ignore first gamepad and keyboard event in browsing +- Ignore first gamepad and keyboard event in browsing [`9347fbe`](https://github.com/ollm/OpenComic/commit/9347fbe628143e688f956ed0950510a2265c02e2) ## [v1.0.0-beta.2](https://github.com/ollm/OpenComic/releases/tag/v1.0.0-beta.2) (03-09-2023) diff --git a/languages/ca.json b/languages/ca.json index b9605894a..6e3305f15 100644 --- a/languages/ca.json +++ b/languages/ca.json @@ -4,6 +4,8 @@ "and": "i", "comics": "C貌mics", "collection": "Col路lecci贸", + "library": "Biblioteca", + "images": "Imatges", "sort": { "main": "Ordenar", "name": "Nom", @@ -22,6 +24,11 @@ "contextMenu": { "remove": "Retirar", "openFileLocation": "Obre la ubicaci贸 del fitxer", + "addPoster": "Afegeix p貌ster", + "changePoster": "Canviar el p貌ster", + "deletePoster": "Esborrar p貌ster", + "cannotAddPoster": "No es pot afegir el p貌ster si la carpeta 茅s dins d'un fitxer comprimit, haur脿 d'editar el fitxer mitjan莽ant 7-zip, unrar, etc", + "cannotDeletePoster": "No es pot esborrar el p貌ster si est脿 dins d'un fitxer comprimit, haur脿 d'editar el fitxer mitjan莽ant 7-zip, unrar, etc", "closeApp": "Tancar OpenComic" }, "back": "Enrere", diff --git a/languages/en.json b/languages/en.json index 13d33a665..070257b90 100644 --- a/languages/en.json +++ b/languages/en.json @@ -4,6 +4,8 @@ "and": "and", "comics": "Comics", "collection": "Collection", + "library": "Library", + "images": "Images", "sort": { "main": "Sort", "name": "Name", @@ -22,6 +24,11 @@ "contextMenu": { "remove": "Remove", "openFileLocation": "Open file location", + "addPoster": "Add poster", + "changePoster": "Change poster", + "deletePoster": "Delete poster", + "cannotAddPoster": "It is not possible to add the poster if the folder is inside a compressed file, you will have to edit the file using 7-zip, unrar, etc", + "cannotDeletePoster": "It is not possible to delete the poster if is inside a compressed file, you will have to edit the file using 7-zip, unrar, etc", "closeApp": "Close OpenComic" }, "back": "Back", diff --git a/languages/es.json b/languages/es.json index eb961fd46..c2ee5f8d1 100644 --- a/languages/es.json +++ b/languages/es.json @@ -4,6 +4,8 @@ "and": "y", "comics": "C贸mics", "collection": "Colecci贸n", + "library": "Biblioteca", + "images": "Im谩genes", "sort": { "main": "Ordenar", "name": "Nombre", @@ -22,6 +24,11 @@ "contextMenu": { "remove": "Retirar", "openFileLocation": "Abrir localizaci贸n de archivo", + "addPoster": "A帽adir p贸ster", + "changePoster": "Cambiar p贸ster", + "deletePoster": "Eliminar p贸ster", + "cannotAddPoster": "No es posible a帽adir el p贸ster si la carpeta est谩 dentro de un archivo comprimido, tendr谩 que editar el archivo mediante 7-zip, unrar, etc", + "cannotDeletePoster": "No es posible eliminar el p贸ster si est谩 dentro de un archivo comprimido, tendr谩 que editar el archivo mediante 7-zip, unrar, etc", "closeApp": "Cerrar OpenComic" }, "back": "Atr谩s", diff --git a/package-lock.json b/package-lock.json index 6f56ef9d0..86be4e520 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,7 @@ "jquery": "^3.7.0", "jquery-bez": "^1.0.11", "mime": "^3.0.0", + "mv": "^2.1.1", "node-7z": "^3.0.0", "pdfjs-dist": "^3.8.162", "sha1": "^1.1.1", @@ -1470,50 +1471,6 @@ "node": ">= 10.0.0" } }, - "node_modules/@mapbox/node-pre-gyp": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", - "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", - "optional": true, - "dependencies": { - "detect-libc": "^2.0.0", - "https-proxy-agent": "^5.0.0", - "make-dir": "^3.1.0", - "node-fetch": "^2.6.7", - "nopt": "^5.0.0", - "npmlog": "^5.0.1", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.11" - }, - "bin": { - "node-pre-gyp": "bin/node-pre-gyp" - } - }, - "node_modules/@mapbox/node-pre-gyp/node_modules/detect-libc": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", - "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@mapbox/node-pre-gyp/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "optional": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -1666,13 +1623,13 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "devOptional": true + "dev": true }, "node_modules/agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "devOptional": true, + "dev": true, "dependencies": { "debug": "4" }, @@ -1684,7 +1641,7 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "devOptional": true, + "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -1775,7 +1732,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "devOptional": true, + "dev": true, "engines": { "node": ">=8" } @@ -1973,20 +1930,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "devOptional": true - }, - "node_modules/are-we-there-yet": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", - "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", - "optional": true, - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">=10" - } + "dev": true }, "node_modules/array-parallel": { "version": "0.1.3", @@ -2613,7 +2557,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "devOptional": true, + "dev": true, "bin": { "color-support": "bin.js" } @@ -2664,7 +2608,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "devOptional": true + "dev": true }, "node_modules/core-util-is": { "version": "1.0.2", @@ -2786,7 +2730,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "devOptional": true + "dev": true }, "node_modules/depd": { "version": "1.1.2", @@ -3141,7 +3085,7 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "devOptional": true + "dev": true }, "node_modules/encoding": { "version": "0.1.13", @@ -3451,7 +3395,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "devOptional": true, + "dev": true, "dependencies": { "minipass": "^3.0.0" }, @@ -3498,26 +3442,6 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "optional": true }, - "node_modules/gauge": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", - "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", - "optional": true, - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.2", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.1", - "object-assign": "^4.1.1", - "signal-exit": "^3.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.2" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -3766,7 +3690,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "devOptional": true + "dev": true }, "node_modules/hosted-git-info": { "version": "4.1.0", @@ -3850,7 +3774,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "devOptional": true, + "dev": true, "dependencies": { "agent-base": "6", "debug": "4" @@ -3863,7 +3787,7 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "devOptional": true, + "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -4043,7 +3967,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "devOptional": true, + "dev": true, "engines": { "node": ">=8" } @@ -4361,30 +4285,6 @@ "yallist": "^2.1.2" } }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "optional": true, - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "optional": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/matcher": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", @@ -4474,7 +4374,7 @@ "version": "3.1.6", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", - "devOptional": true, + "dev": true, "dependencies": { "yallist": "^4.0.0" }, @@ -4534,13 +4434,13 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "devOptional": true + "dev": true }, "node_modules/minizlib": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "devOptional": true, + "dev": true, "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" @@ -4553,7 +4453,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "devOptional": true + "dev": true }, "node_modules/mkdirp": { "version": "0.5.5", @@ -4576,17 +4476,58 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, - "node_modules/nan": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", - "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", - "optional": true + "node_modules/mv": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", + "integrity": "sha512-at/ZndSy3xEGJ8i0ygALh8ru9qy7gWW1cmkaqBN29JmMlIvM//MEO9y1sk/avxuwnPcfhkejkLsuPxH81BrkSg==", + "dependencies": { + "mkdirp": "~0.5.1", + "ncp": "~2.0.0", + "rimraf": "~2.4.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/mv/node_modules/glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==", + "dependencies": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mv/node_modules/rimraf": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", + "integrity": "sha512-J5xnxTyqaiw06JjMftq7L9ouA448dw/E7dKghkP9WpKNuwmARNNg+Gk8/u5ryb9N/Yo2+z3MCwuqFK/+qPOPfQ==", + "dependencies": { + "glob": "^6.0.1" + }, + "bin": { + "rimraf": "bin.js" + } }, "node_modules/napi-build-utils": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" }, + "node_modules/ncp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", + "integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==", + "bin": { + "ncp": "bin/ncp" + } + }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -4731,21 +4672,6 @@ "node": ">=4" } }, - "node_modules/nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "optional": true, - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -4765,27 +4691,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/npmlog": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", - "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", - "optional": true, - "dependencies": { - "are-we-there-yet": "^2.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^3.0.0", - "set-blocking": "^2.0.0" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", @@ -5444,7 +5349,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "devOptional": true + "dev": true }, "node_modules/setimmediate": { "version": "1.0.5", @@ -5685,7 +5590,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "devOptional": true, + "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -5714,7 +5619,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "devOptional": true, + "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -5802,7 +5707,7 @@ "version": "6.1.15", "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz", "integrity": "sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==", - "devOptional": true, + "dev": true, "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", @@ -5839,7 +5744,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "devOptional": true, + "dev": true, "engines": { "node": ">=10" } @@ -5848,7 +5753,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "devOptional": true, + "dev": true, "engines": { "node": ">=8" } @@ -5857,7 +5762,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "devOptional": true, + "dev": true, "bin": { "mkdirp": "bin/cmd.js" }, @@ -5869,7 +5774,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "devOptional": true + "dev": true }, "node_modules/temp-file": { "version": "3.4.0", @@ -6234,7 +6139,7 @@ "version": "1.1.5", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "devOptional": true, + "dev": true, "dependencies": { "string-width": "^1.0.2 || 2 || 3 || 4" } diff --git a/package.json b/package.json index c6f4581a3..8ce74a6f9 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "jquery": "^3.7.0", "jquery-bez": "^1.0.11", "mime": "^3.0.0", + "mv": "^2.1.1", "node-7z": "^3.0.0", "pdfjs-dist": "^3.8.162", "sha1": "^1.1.1", diff --git a/scripts/cache.js b/scripts/cache.js index a91886351..051999818 100644 --- a/scripts/cache.js +++ b/scripts/cache.js @@ -8,142 +8,54 @@ if(!fs.existsSync(cacheFolder)) fs.mkdirSync(cacheFolder); function processTheImageQueue() { - if(sharp === false) sharp = require('sharp'); - let img = queuedImages[0]; let sha = img.sha; let realPath = fileManager.realPath(img.file); + let toImage = p.join(cacheFolder, sha+'.jpg'); - sharp(realPath).jpeg({quality: 95}).resize({width: img.size, background: 'white'}).toFile(p.join(cacheFolder, sha+'.jpg'), function(error) { - - if(error) - { - - if(!imageLibrary) imageLibrary = require('gm').subClass({imageMagick: true}); - - imageLibrary(realPath).resize(img.size, null).quality(95).noProfile().write(p.join(cacheFolder, sha+'.jpg'), function(error){ - - if(error) - { - if(imageUse !== 'gm') - { - imageLibrary = require('gm').subClass({imageMagick: false}); - imageUse = 'gm'; - - process.nextTick(function() { - processTheImageQueue(); - }); - } - else - { - imageLibrary = require('gm').subClass({imageMagick: true}); - imageUse = 'im'; - - if(jimp === false) jimp = require('jimp'); - - jimp.read(realPath, function(error, lenna) { - - if(error) - { - img.callback({cache: true, path: escapeBackSlash(realPath), sha: sha}, img.vars); - - queuedImages.splice(0, 1); - - if(queuedImages.length > 0) - { - process.nextTick(function() { - processTheImageQueue(); - }); - } - else - { - processingTheImageQueue = false; - - storage.set('cache', data); - } - } - else - { - lenna.resize(img.size, jimp.AUTO).quality(95).background(0xFFFFFFFF).write(p.join(cacheFolder, sha+'.jpg'), function(){ + image.resize(realPath, toImage, {width: img.size, quality: 95}).then(function(){ - if(typeof data[sha] == 'undefined') data[sha] = {lastAccess: time()}; + if(typeof data[sha] == 'undefined') data[sha] = {lastAccess: time()}; - data[sha].size = img.size; + data[sha].size = img.size; - img.callback({cache: true, path: escapeBackSlash(p.join(cacheFolder, sha+'.jpg?size='+img.size)), sha: sha}, img.vars); + img.callback({cache: true, path: escapeBackSlash(addCacheVars(toImage, img.size, img.sha)), sha: sha}, img.vars); - queuedImages.splice(0, 1); + queuedImages.splice(0, 1); - if(queuedImages.length > 0) - { - process.nextTick(function() { - processTheImageQueue(); - }); - } - else - { - processingTheImageQueue = false; - - storage.set('cache', data); - } - - }); - } - - }); - - } - - } - else - { - if(typeof data[sha] == 'undefined') data[sha] = {lastAccess: time()}; + if(queuedImages.length > 0) + { + process.nextTick(function() { + processTheImageQueue(); + }); + } + else + { + processingTheImageQueue = false; - data[sha].size = img.size; + storage.set('cache', data); + } - img.callback({cache: true, path: escapeBackSlash(p.join(cacheFolder, sha+'.jpg?size='+img.size)), sha: sha}, img.vars); + }).catch(function(){ - queuedImages.splice(0, 1); + img.callback({cache: true, path: escapeBackSlash(realPath), sha: sha}, img.vars); - if(queuedImages.length > 0) - { - process.nextTick(function() { - processTheImageQueue(); - }); - } - else - { - processingTheImageQueue = false; + queuedImages.splice(0, 1); - storage.set('cache', data); - } - } + if(queuedImages.length > 0) + { + process.nextTick(function() { + processTheImageQueue(); }); } else { - if(typeof data[sha] == 'undefined') data[sha] = {lastAccess: time()}; - - data[sha].size = img.size; + processingTheImageQueue = false; - img.callback({cache: true, path: escapeBackSlash(p.join(cacheFolder, sha+'.jpg?size='+img.size)), sha: sha}, img.vars); - - queuedImages.splice(0, 1); - - if(queuedImages.length > 0) - { - process.nextTick(function() { - processTheImageQueue(); - }); - } - else - { - processingTheImageQueue = false; - - storage.set('cache', data); - } + storage.set('cache', data); } + }); } @@ -193,7 +105,7 @@ function returnThumbnailsImages(images, callback, file = false) let sha = image.sha || sha1(image.path); let imgCache = data[sha]; - let path = p.join(cacheFolder, sha+'.jpg?size='+size); + let path = addCacheVars(p.join(cacheFolder, sha+'.jpg'), size, sha); if(typeof imgCache == 'undefined' || !fs.existsSync(p.join(cacheFolder, sha+'.jpg'))) { @@ -248,12 +160,40 @@ function readFile(name) return false; } +function addCacheVars(path, size, sha) +{ + return path+'?size='+size+(cacheImagesDeleted[sha] ? '&a='+cacheImagesDeleted[sha] : ''); +} + +var cacheImagesDeleted = []; + +async function deleteInCache(path) +{ + let sha = sha1(path); + let cachePath = p.join(cacheFolder, sha+'.jpg'); + + if(data[sha]) + delete data[sha]; + + if(fs.existsSync(cachePath)) + { + fs.unlinkSync(cachePath); + + let size = Math.round(window.devicePixelRatio * 150); + } + + cacheImagesDeleted[sha] = cacheImagesDeleted[sha] ? cacheImagesDeleted[sha] + 1 : 1; + + return; +} + module.exports = { folder: cacheFolder, returnThumbnailsImages: returnThumbnailsImages, cleanQueue: cleanQueue, writeFile: writeFile, readFile: readFile, + deleteInCache: deleteInCache, queuedImages: function(){return queuedImages}, processingTheImageQueue: function(){return processingTheImageQueue}, }; diff --git a/scripts/dom.js b/scripts/dom.js index 366a18dca..28b864d8f 100644 --- a/scripts/dom.js +++ b/scripts/dom.js @@ -1,283 +1,5 @@ -var _dom = function(_this, string = false, querySelectorAll = false) { - - this._this = _this; - - if(string) - { - if(querySelectorAll) - { - this._this = document.querySelectorAll(this._this); - } - else - { - let __this = document.querySelector(this._this); - - if(__this) - this._this = [__this]; - else - this._this = []; - } - } - else - { - if(!this._this) - this._this = []; - else if(this._this.length === undefined) - this._this = [this._this]; - } - - this.each = function(callback){ - - for(let i = 0, len = this._this.length; i < len; i++) - { - callback.call(this._this[i]); - } - - return this; - } - - this.remove = function() { - - for(let i = 0, len = this._this.length; i < len; i++) - { - this._this[i].remove(); - } - - delete this._this; - delete this; - } - - this.find = function(query, all = false) { - - let newThis = []; - - for(let i = 0, len = this._this.length; i < len; i++) - { - if(all) - { - newThis = [...newThis, ...this._this[i].querySelectorAll(query)]; - } - else - { - let _this = this._this[i].querySelector(query); - - if(_this) - newThis.push(_this); - } - } - - this._this = newThis; - - return this; - } - - this.getParents = function(element) { - - let result = []; - - for(let parent = element && element.parentElement; parent; parent = parent.parentElement) - { - result.push(parent); - } - - return result; - } - - this.parents = function(query, all = false) - { - let newThis = []; - - for(let i = 0, len = this._this.length; i < len; i++) - { - let parents = this.getParents(this._this[i]); - - for(let i2 = 0, len2 = parents.length; i2 < len2; i2++) - { - if(parents[i2].matches(query)) - { - newThis.push(parents[i2]); - - if(!all) - break; - } - } - } - - this._this = newThis; - - return this; - } - - this.siblings = function(query = false, all = false) { - - let newThis = []; - - for(let i = 0, len = this._this.length; i < len; i++) - { - let parentChildren = this._this[i].parentElement.children; - - for(let i2 = 0, len2 = parentChildren.length; i2 < len2; i2++) - { - if((query === false || parentChildren[i2].matches(query)) && parentChildren[i2] !== this._this[i]) - { - newThis.push(parentChildren[i2]); - - if(!all) - break; - } - } - } - - this._this = newThis; - - return this; - - } - - this.addClass = function() { - - for(let i = 0, len = this._this.length; i < len; i++) - { - this._this[i].classList.add(...arguments); - } - - return this; - } - - this.removeClass = function() { - - for(let i = 0, len = this._this.length; i < len; i++) - { - this._this[i].classList.remove(...arguments); - } - - return this; - } - - this.class = function(active) { - - let _arguments = Array.from(arguments); - _arguments.shift(); - - if(active) - this.addClass(..._arguments); - else - this.removeClass(..._arguments); - } - - this.setAttribute = function(name, value) { - - for(let i = 0, len = this._this.length; i < len; i++) - { - this._this[i].setAttribute(name, value); - } - - return this; - } - - this.getAttribute = function(attribute) { - - for(let i = 0, len = this._this.length; i < len; i++) - { - let value = this._this[i].getAttribute(attribute); - if(value) return value; - } - - return ''; - } - - this.scrollTop = function(scrollTop = false) { - - if(scrollTop !== false) - { - for(let i = 0, len = this._this.length; i < len; i++) - { - this._this[i].scrollTop = scrollTop; - } - - return this; - } - else - { - if(this._this.length > 0) - return this._this[0].scrollTop; - - return 0; - } - - } - - this.css = function(css) { - - for(let key in css) - { - let value = css[key]; - - for(let i = 0, len = this._this.length; i < len; i++) - { - this._this[i].style[key] = value; - } - } - - return this; - } - - this.html = function(html) { - - for(let i = 0, len = this._this.length; i < len; i++) - { - this._this[i].innerHTML = html; - } - - return this; - } - - this.append = function(html) { - - for(let i = 0, len = this._this.length; i < len; i++) - { - this._this[i].insertAdjacentHTML('beforeend', html); - } - - return this; - } - - this.text = function(html) { - - for(let i = 0, len = this._this.length; i < len; i++) - { - this._this[i].innerHTML = playmax.text(html); - } - - return this; - } - - this.get = function(index) { - - return this._this[index]; - - } - - this.this = function() { - - return this._this; - - } - - this.delete = function() { - - delete this._this; - delete this; - - } - - this.destroy = function() { - - delete this._this; - delete this; - - } -} +const domPoster = require(p.join(appDir, 'scripts/dom/poster.js')), + domManager = require(p.join(appDir, 'scripts/dom/dom.js')); /*Page - Index*/ @@ -1365,7 +1087,7 @@ function nightMode() } // Show the comic contet menu -function comicContextMenu(path, fromIndex = true, gamepad = false) +async function comicContextMenu(path, fromIndex = true, folder = false, gamepad = false) { // Remove let remove = document.querySelector('#index-context-menu .context-menu-remove'); @@ -1385,6 +1107,48 @@ function comicContextMenu(path, fromIndex = true, gamepad = false) events.activeMenu('#index-context-menu', false, 'gamepad'); else events.activeContextMenu('#index-context-menu'); + + // Add poster and delete + let addPoster = document.querySelector('#index-context-menu .context-menu-add-poster'); + let deletePoster = document.querySelector('#index-context-menu .context-menu-delete-poster'); + + if(folder) + { + addPoster.style.display = 'block'; + + let file = fileManager.file(path); + let images = await file.images(2, false, true); + + poster = !Array.isArray(images) ? images.path : false; + + addPoster.setAttribute('onclick', 'dom.addPoster('+(fromIndex ? 'true' : 'false')+', \''+escapeQuotes(escapeBackSlash(path), 'simples')+'\', '+(poster ? '\''+escapeQuotes(escapeBackSlash(poster), 'simples')+'\'' : 'false')+');'); + addPoster.querySelector('span').innerHTML = poster ? language.global.contextMenu.changePoster : language.global.contextMenu.addPoster; + + if(poster) + { + deletePoster.style.display = 'block'; + deletePoster.setAttribute('onclick', 'dom.deletePoster(\''+escapeQuotes(escapeBackSlash(poster), 'simples')+'\');'); + } + else + { + deletePoster.style.display = 'none'; + } + } + else + { + addPoster.style.display = 'none'; + deletePoster.style.display = 'none'; + } +} + +function addPoster(fromIndex = false, path = false, currentPoster = false) +{ + domPoster.add(fromIndex, path, currentPoster); +} + +function deletePoster(currentPoster = false) +{ + domPoster.delete(currentPoster); } // Remove the comic from OpenComic @@ -1587,16 +1351,12 @@ module.exports = { compressedError: compressedError, addImageToDom: addImageToDom, addSepToEnd: addSepToEnd, + addPoster: addPoster, + deletePoster: deletePoster, indexPathControlUpdateLastComic: indexPathControlUpdateLastComic, indexMainPathA: function(){return indexMainPathA}, currentPathScrollTop: function(){return currentPathScrollTop}, - this: function(_this, string = false, querySelectorAll = false) { - return new _dom(_this, string, querySelectorAll); - }, - query: function(_this) { - return new _dom(_this, true, false); - }, - queryAll: function(_this) { - return new _dom(_this, true, true); - }, + this: domManager.this, + query: domManager.query, + queryAll: domManager.queryAll, }; diff --git a/scripts/dom/dom.js b/scripts/dom/dom.js new file mode 100644 index 000000000..898a19845 --- /dev/null +++ b/scripts/dom/dom.js @@ -0,0 +1,292 @@ +var _dom = function(_this, string = false, querySelectorAll = false) { + + this._this = _this; + + if(string) + { + if(querySelectorAll) + { + this._this = document.querySelectorAll(this._this); + } + else + { + let __this = document.querySelector(this._this); + + if(__this) + this._this = [__this]; + else + this._this = []; + } + } + else + { + if(!this._this) + this._this = []; + else if(this._this.length === undefined) + this._this = [this._this]; + } + + this.each = function(callback){ + + for(let i = 0, len = this._this.length; i < len; i++) + { + callback.call(this._this[i]); + } + + return this; + } + + this.remove = function() { + + for(let i = 0, len = this._this.length; i < len; i++) + { + this._this[i].remove(); + } + + delete this._this; + delete this; + } + + this.find = function(query, all = false) { + + let newThis = []; + + for(let i = 0, len = this._this.length; i < len; i++) + { + if(all) + { + newThis = [...newThis, ...this._this[i].querySelectorAll(query)]; + } + else + { + let _this = this._this[i].querySelector(query); + + if(_this) + newThis.push(_this); + } + } + + this._this = newThis; + + return this; + } + + this.getParents = function(element) { + + let result = []; + + for(let parent = element && element.parentElement; parent; parent = parent.parentElement) + { + result.push(parent); + } + + return result; + } + + this.parents = function(query, all = false) + { + let newThis = []; + + for(let i = 0, len = this._this.length; i < len; i++) + { + let parents = this.getParents(this._this[i]); + + for(let i2 = 0, len2 = parents.length; i2 < len2; i2++) + { + if(parents[i2].matches(query)) + { + newThis.push(parents[i2]); + + if(!all) + break; + } + } + } + + this._this = newThis; + + return this; + } + + this.siblings = function(query = false, all = false) { + + let newThis = []; + + for(let i = 0, len = this._this.length; i < len; i++) + { + let parentChildren = this._this[i].parentElement.children; + + for(let i2 = 0, len2 = parentChildren.length; i2 < len2; i2++) + { + if((query === false || parentChildren[i2].matches(query)) && parentChildren[i2] !== this._this[i]) + { + newThis.push(parentChildren[i2]); + + if(!all) + break; + } + } + } + + this._this = newThis; + + return this; + + } + + this.addClass = function() { + + for(let i = 0, len = this._this.length; i < len; i++) + { + this._this[i].classList.add(...arguments); + } + + return this; + } + + this.removeClass = function() { + + for(let i = 0, len = this._this.length; i < len; i++) + { + this._this[i].classList.remove(...arguments); + } + + return this; + } + + this.class = function(active) { + + let _arguments = Array.from(arguments); + _arguments.shift(); + + if(active) + this.addClass(..._arguments); + else + this.removeClass(..._arguments); + } + + this.setAttribute = function(name, value) { + + for(let i = 0, len = this._this.length; i < len; i++) + { + this._this[i].setAttribute(name, value); + } + + return this; + } + + this.getAttribute = function(attribute) { + + for(let i = 0, len = this._this.length; i < len; i++) + { + let value = this._this[i].getAttribute(attribute); + if(value) return value; + } + + return ''; + } + + this.scrollTop = function(scrollTop = false) { + + if(scrollTop !== false) + { + for(let i = 0, len = this._this.length; i < len; i++) + { + this._this[i].scrollTop = scrollTop; + } + + return this; + } + else + { + if(this._this.length > 0) + return this._this[0].scrollTop; + + return 0; + } + + } + + this.css = function(css) { + + for(let key in css) + { + let value = css[key]; + + for(let i = 0, len = this._this.length; i < len; i++) + { + this._this[i].style[key] = value; + } + } + + return this; + } + + this.html = function(html) { + + for(let i = 0, len = this._this.length; i < len; i++) + { + this._this[i].innerHTML = html; + } + + return this; + } + + this.append = function(html) { + + for(let i = 0, len = this._this.length; i < len; i++) + { + this._this[i].insertAdjacentHTML('beforeend', html); + } + + return this; + } + + this.text = function(html) { + + for(let i = 0, len = this._this.length; i < len; i++) + { + this._this[i].innerHTML = playmax.text(html); + } + + return this; + } + + this.get = function(index) { + + return this._this[index]; + + } + + this.this = function() { + + return this._this; + + } + + this.delete = function() { + + delete this._this; + delete this; + + } + + this.destroy = function() { + + delete this._this; + delete this; + + } +} + +module.exports = { + this: function(_this, string = false, querySelectorAll = false) { + return new _dom(_this, string, querySelectorAll); + }, + query: function(_this) { + return new _dom(_this, true, false); + }, + queryAll: function(_this) { + return new _dom(_this, true, true); + }, +}; \ No newline at end of file diff --git a/scripts/dom/poster.js b/scripts/dom/poster.js new file mode 100644 index 000000000..50526ebc0 --- /dev/null +++ b/scripts/dom/poster.js @@ -0,0 +1,174 @@ +const mv = require('mv'); + +function canAddPosterInside(path = false) +{ + if(fileManager.containsCompressed(path)) + return false; + else + return true; +} + +function canAddPosterOutside(path = false) +{ + if(fileManager.containsCompressed(p.dirname(path))) + return false; + else + return true; +} + +var currentPath = '', addPosterInside = false; + +function add(fromIndex = false, path = false, currentPoster = false) +{ + currentPath = path; + addPosterInside = false; + + let canAddPoster = false; + /*let currentPosterIsInside = false; + + if(currentPoster) + { + if(p.normalize(path) === p.normalize(p.dirname(currentPoster))) + currentPosterIsInside = true; + }*/ + + if((fromIndex/* || currentPosterIsInside*/) && canAddPosterInside(path)) + addPosterInside = true; + + if(addPosterInside || canAddPosterOutside(path)) + canAddPoster = true; + + console.log(fromIndex, path, currentPoster); + console.log('addPosterInside', addPosterInside); + console.log('canAddPoster', canAddPoster); + + if(canAddPoster) + { + openDialog(path); + } + else + { + events.snackbar({ + key: 'cannotAddPoster', + text: language.global.contextMenu.cannotAddPoster, + duration: 14, + update: true, + buttons: [ + { + text: language.buttons.dismiss, + function: 'events.closeSnackbar();', + }, + ], + }); + } +} + +function openDialog(path) +{ + let dialog = electronRemote.dialog; + + dialog.showOpenDialog({properties: ['openFile'], defaultPath: fileManager.containsCompressed(path) ? p.dirname(path) : path, filters: [{name: language.global.comics, extensions: [...compatibleImageExtensions, ...compatibleSpecialExtensions]}]}).then(function (files) { + + if(files.filePaths && files.filePaths[0]) + setNewPoster(files.filePaths[0]); + + }); +} + +function setNewPoster(path) +{ + console.log(path, currentPath); + + let sha = sha1(path); + let tmp = p.join(tempFolder, sha+'.jpg'); + + let name = p.parse(currentPath).name; + + // /home/llopart/Im谩genes/Pepper & Carrot.zip + + let posterPath = p.join(addPosterInside ? currentPath : p.dirname(currentPath), name+'.tbn'); + + image.resize(path, tmp, {width: 1200, quality: 80}).then(function(image){ + + if(fs.existsSync(posterPath)) + fs.unlinkSync(posterPath); + + mv(tmp, posterPath, async function(error) { + + if(!error) + { + await cache.deleteInCache(posterPath); + + dom.reloadIndex(); + } + else + { + console.log(error); + + events.snackbar({ + key: 'setNewPoster', + text: 'Error', + duration: 6, + update: true, + buttons: [ + { + text: language.buttons.dismiss, + function: 'events.closeSnackbar();', + }, + ], + }); + } + + }); + + }).catch(function(){ + + events.snackbar({ + key: 'setNewPoster', + text: 'Error', + duration: 6, + update: true, + buttons: [ + { + text: language.buttons.dismiss, + function: 'events.closeSnackbar();', + }, + ], + }); + + }); + +} + +async function _delete(currentPoster = false) +{ + if(!fileManager.containsCompressed(currentPoster)) + { + if(fs.existsSync(currentPoster)) + fs.unlinkSync(currentPoster); + + await cache.deleteInCache(currentPoster); + + dom.reloadIndex(); + } + else + { + events.snackbar({ + key: 'cannotDeletePoster', + text: language.global.contextMenu.cannotDeletePoster, + duration: 14, + update: true, + buttons: [ + { + text: language.buttons.dismiss, + function: 'events.closeSnackbar();', + }, + ], + }); + } +} + +module.exports = { + add: add, + delete: _delete, +}; \ No newline at end of file diff --git a/scripts/file-manager.js b/scripts/file-manager.js index e7b645b50..749a8dcbf 100644 --- a/scripts/file-manager.js +++ b/scripts/file-manager.js @@ -370,12 +370,20 @@ var file = function(path) { { let file = files[i]; - if(!file.folder && !file.compressed && regex.test(file.name) && (inArray(mime.getType(file.path), compatibleMime) || inArray(app.extname(file.path), compatibleSpecialExtensions))) + if(!file.folder && !file.compressed && regex.test(file.name)) { - file.sha = sha1(file.path); - poster = file; + if(!poster && inArray(mime.getType(file.path), compatibleMime)) + { + file.sha = sha1(file.path); + poster = file; + } + else if(inArray(app.extname(file.path), compatibleSpecialExtensions)) // prioritize tbn poster + { + file.sha = sha1(file.path); + poster = file; - break; + break; + } } } diff --git a/scripts/image.js b/scripts/image.js new file mode 100644 index 000000000..677508042 --- /dev/null +++ b/scripts/image.js @@ -0,0 +1,73 @@ +var sharp = false, jimp = false, imageMagick = false, graphicsMagick = false; + +async function resize(fromImage, toImage, config = {}) +{ + config = {...{ + width: 200, + quality: 95, + }, ...config}; + + if(sharp === false) sharp = require('sharp'); + + return new Promise(function(resolve, reject) { + + sharp(fromImage).jpeg({quality: config.quality}).resize({width: config.width, background: 'white'}).toFile(toImage, function(error) { + + if(error) + { + if(!imageMagick) imageMagick = require('gm').subClass({imageMagick: true}); + + imageMagick(fromImage).resize(config.width, null).quality(config.quality).noProfile().write(toImage, function(error){ + + if(error) + { + if(!graphicsMagick) graphicsMagick = require('gm').subClass({imageMagick: false}); + + graphicsMagick(fromImage).resize(config.width, null).quality(config.quality).noProfile().write(toImage, function(error){ + + if(error) + { + if(jimp === false) jimp = require('jimp'); + + jimp.read(fromImage, function(error, lenna) { + + if(error) + { + reject(); + } + else + { + lenna.resize(config.width, jimp.AUTO).quality(config.quality).background(0xFFFFFFFF).write(toImage, function(){ + + resolve(toImage); + + }); + } + + }); + } + else + { + resolve(toImage); + } + }); + + } + else + { + resolve(toImage); + } + }); + } + else + { + resolve(toImage); + } + }); + + }); +} + +module.exports = { + resize: resize, +}; \ No newline at end of file diff --git a/scripts/opencomic.js b/scripts/opencomic.js index f47191904..2a2eeccac 100644 --- a/scripts/opencomic.js +++ b/scripts/opencomic.js @@ -190,7 +190,7 @@ var compressedExtensions = { ], }; -var compatibleExtensions = [ +var compatibleImageExtensions = [ /*jpeg*/'jpg', 'jpeg', 'jif', 'jfi', 'jfif', 'jfif-tbnl', 'jpe', /*png*/'png', 'x-png', 'apng', /*svg*/'svg', 'svgz', @@ -199,9 +199,17 @@ var compatibleExtensions = [ /*ico*/'ico', /*webp*/'webp', /*avif*/'avif', 'avifs', +]; + +var compatibleCompressedExtensions = [ /*compressed*/'zip', 'cbz', 'rar', 'cbr', '7z', 'cb7', 'tar', 'cbt', 'pdf', ]; +var compatibleExtensions = [ + ...compatibleImageExtensions, + ...compatibleCompressedExtensions, +]; + var compatibleSpecialExtensions = [ 'tbn', ]; @@ -210,6 +218,7 @@ var compatibleSpecialExtensions = [ const app = require(p.join(appDir, 'scripts/app.js')), storage = require(p.join(appDir, 'scripts/storage.js')), + image = require(p.join(appDir, 'scripts/image.js')), cache = require(p.join(appDir, 'scripts/cache.js')), queue = require(p.join(appDir, 'scripts/queue.js')), templates = require(p.join(appDir, 'scripts/builded/templates.js')), diff --git a/templates/index.content.right.list.html b/templates/index.content.right.list.html index 18cf82921..5573d1fc7 100644 --- a/templates/index.content.right.list.html +++ b/templates/index.content.right.list.html @@ -8,7 +8,7 @@ {{/if}}
{{#each comics}} -
+
{{#if folder}}folder{{/if}}
{{name}}
diff --git a/templates/index.content.right.module.html b/templates/index.content.right.module.html index ba8409c82..bdeb764af 100644 --- a/templates/index.content.right.module.html +++ b/templates/index.content.right.module.html @@ -8,7 +8,7 @@ {{/if}}
{{#each comics}} -
+
{{#if folder}}
{{#if poster}} diff --git a/templates/index.elements.menus.html b/templates/index.elements.menus.html index 36c10c1e6..e95d1a632 100644 --- a/templates/index.elements.menus.html +++ b/templates/index.elements.menus.html @@ -42,6 +42,16 @@