mirror of
https://github.com/xuthus83/pigallery2.git
synced 2025-01-14 14:43:17 +08:00
Download zip folder
This commit is contained in:
parent
6249d942c0
commit
6af288e77a
193
package-lock.json
generated
193
package-lock.json
generated
@ -4167,6 +4167,74 @@
|
||||
"resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
|
||||
"integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw=="
|
||||
},
|
||||
"archiver": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.0.tgz",
|
||||
"integrity": "sha512-iUw+oDwK0fgNpvveEsdQ0Ase6IIKztBJU2U0E9MzszMfmVVUyv1QJhS2ITW9ZCqx8dktAxVAjWWkKehuZE8OPg==",
|
||||
"requires": {
|
||||
"archiver-utils": "^2.1.0",
|
||||
"async": "^3.2.0",
|
||||
"buffer-crc32": "^0.2.1",
|
||||
"readable-stream": "^3.6.0",
|
||||
"readdir-glob": "^1.0.0",
|
||||
"tar-stream": "^2.2.0",
|
||||
"zip-stream": "^4.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"async": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz",
|
||||
"integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw=="
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
|
||||
"requires": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"archiver-utils": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz",
|
||||
"integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==",
|
||||
"requires": {
|
||||
"glob": "^7.1.4",
|
||||
"graceful-fs": "^4.2.0",
|
||||
"lazystream": "^1.0.0",
|
||||
"lodash.defaults": "^4.2.0",
|
||||
"lodash.difference": "^4.5.0",
|
||||
"lodash.flatten": "^4.4.0",
|
||||
"lodash.isplainobject": "^4.0.6",
|
||||
"lodash.union": "^4.6.0",
|
||||
"normalize-path": "^3.0.0",
|
||||
"readable-stream": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"glob": {
|
||||
"version": "7.1.6",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
|
||||
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "4.2.6",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
|
||||
"integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"archy": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
|
||||
@ -5030,8 +5098,7 @@
|
||||
"buffer-crc32": {
|
||||
"version": "0.2.13",
|
||||
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
|
||||
"integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
|
||||
"dev": true
|
||||
"integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI="
|
||||
},
|
||||
"buffer-equal": {
|
||||
"version": "0.0.1",
|
||||
@ -5992,6 +6059,29 @@
|
||||
"arity-n": "^1.0.4"
|
||||
}
|
||||
},
|
||||
"compress-commons": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.0.tgz",
|
||||
"integrity": "sha512-ofaaLqfraD1YRTkrRKPCrGJ1pFeDG/MVCkVVV2FNGeWquSlqw5wOrwOfPQ1xF2u+blpeWASie5EubHz+vsNIgA==",
|
||||
"requires": {
|
||||
"buffer-crc32": "^0.2.13",
|
||||
"crc32-stream": "^4.0.1",
|
||||
"normalize-path": "^3.0.0",
|
||||
"readable-stream": "^3.6.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
|
||||
"requires": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"compressible": {
|
||||
"version": "2.0.18",
|
||||
"resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
|
||||
@ -6498,6 +6588,36 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"crc-32": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.0.tgz",
|
||||
"integrity": "sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==",
|
||||
"requires": {
|
||||
"exit-on-epipe": "~1.0.1",
|
||||
"printj": "~1.1.0"
|
||||
}
|
||||
},
|
||||
"crc32-stream": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.2.tgz",
|
||||
"integrity": "sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w==",
|
||||
"requires": {
|
||||
"crc-32": "^1.2.0",
|
||||
"readable-stream": "^3.4.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
|
||||
"requires": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"create-ecdh": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz",
|
||||
@ -8503,6 +8623,11 @@
|
||||
"integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
|
||||
"dev": true
|
||||
},
|
||||
"exit-on-epipe": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz",
|
||||
"integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw=="
|
||||
},
|
||||
"expand-brackets": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
|
||||
@ -12071,7 +12196,6 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz",
|
||||
"integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"readable-stream": "^2.0.5"
|
||||
}
|
||||
@ -12386,6 +12510,16 @@
|
||||
"integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=",
|
||||
"dev": true
|
||||
},
|
||||
"lodash.defaults": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
|
||||
"integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw="
|
||||
},
|
||||
"lodash.difference": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz",
|
||||
"integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw="
|
||||
},
|
||||
"lodash.escape": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz",
|
||||
@ -12395,6 +12529,11 @@
|
||||
"lodash._root": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"lodash.flatten": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz",
|
||||
"integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8="
|
||||
},
|
||||
"lodash.flattendeep": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz",
|
||||
@ -12413,6 +12552,11 @@
|
||||
"integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=",
|
||||
"dev": true
|
||||
},
|
||||
"lodash.isplainobject": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
|
||||
"integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs="
|
||||
},
|
||||
"lodash.keys": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz",
|
||||
@ -12469,6 +12613,11 @@
|
||||
"lodash.escape": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"lodash.union": {
|
||||
"version": "4.6.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz",
|
||||
"integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg="
|
||||
},
|
||||
"lodash.uniq": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
|
||||
@ -14085,8 +14234,7 @@
|
||||
"normalize-path": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
|
||||
},
|
||||
"normalize-range": {
|
||||
"version": "0.1.2",
|
||||
@ -17932,6 +18080,11 @@
|
||||
"integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=",
|
||||
"dev": true
|
||||
},
|
||||
"printj": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz",
|
||||
"integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ=="
|
||||
},
|
||||
"process": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz",
|
||||
@ -18603,6 +18756,14 @@
|
||||
"util-deprecate": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"readdir-glob": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.1.tgz",
|
||||
"integrity": "sha512-91/k1EzZwDx6HbERR+zucygRFfiPl2zkIYZtv3Jjr6Mn7SkKcVct8aVO+sSRiGMc6fLf72du3d92/uY63YPdEA==",
|
||||
"requires": {
|
||||
"minimatch": "^3.0.4"
|
||||
}
|
||||
},
|
||||
"readdirp": {
|
||||
"version": "3.5.0",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz",
|
||||
@ -23987,6 +24148,28 @@
|
||||
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
|
||||
"dev": true
|
||||
},
|
||||
"zip-stream": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.0.tgz",
|
||||
"integrity": "sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==",
|
||||
"requires": {
|
||||
"archiver-utils": "^2.1.0",
|
||||
"compress-commons": "^4.1.0",
|
||||
"readable-stream": "^3.6.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
|
||||
"requires": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"zone.js": {
|
||||
"version": "0.11.4",
|
||||
"resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.11.4.tgz",
|
||||
|
@ -33,6 +33,7 @@
|
||||
"url": "https://github.com/bpatrik/PiGallery2/issues"
|
||||
},
|
||||
"dependencies": {
|
||||
"archiver": "^5.3.0",
|
||||
"bcrypt": "5.0.1",
|
||||
"body-parser": "1.19.0",
|
||||
"cookie-parser": "1.4.5",
|
||||
|
@ -16,6 +16,7 @@ import {QueryParams} from '../../common/QueryParams';
|
||||
import {VideoProcessing} from '../model/fileprocessing/VideoProcessing';
|
||||
import {SearchQueryDTO, SearchQueryTypes} from '../../common/entities/SearchQueryDTO';
|
||||
import {LocationLookupException} from '../exceptions/LocationLookupException';
|
||||
import {SupportedFormats} from '../../common/SupportedFormats';
|
||||
|
||||
|
||||
export class GalleryMWs {
|
||||
@ -56,6 +57,75 @@ export class GalleryMWs {
|
||||
}
|
||||
}
|
||||
|
||||
public static async zipDirectory(req: Request, res: Response, next: NextFunction): Promise<any> {
|
||||
if (Config.Client.Other.enableDownloadZip === false) {
|
||||
return next();
|
||||
}
|
||||
const directoryName = req.params.directory || '/';
|
||||
const absoluteDirectoryName = path.join(ProjectPath.ImageFolder, directoryName);
|
||||
try {
|
||||
if ((await fsp.stat(absoluteDirectoryName)).isDirectory() === false) {
|
||||
return next();
|
||||
}
|
||||
} catch (e) {
|
||||
return next();
|
||||
}
|
||||
|
||||
try {
|
||||
const directory = await ObjectManagers.getInstance()
|
||||
.GalleryManager.listDirectory(directoryName,
|
||||
parseInt(req.query[QueryParams.gallery.knownLastModified] as string, 10),
|
||||
parseInt(req.query[QueryParams.gallery.knownLastScanned] as string, 10));
|
||||
|
||||
if (directory == null) {
|
||||
req.resultPipe = new ContentWrapper(null, null, true);
|
||||
return next();
|
||||
}
|
||||
if (req.session.user.permissions &&
|
||||
req.session.user.permissions.length > 0 &&
|
||||
req.session.user.permissions[0] !== '/*') {
|
||||
(directory as DirectoryDTO).directories = (directory as DirectoryDTO).directories.filter((d): boolean =>
|
||||
UserDTOUtils.isDirectoryAvailable(d, req.session.user.permissions));
|
||||
}
|
||||
|
||||
res.set('Content-Type', 'application/zip');
|
||||
res.set('Content-Disposition', 'attachment; filename=Gallery.zip');
|
||||
|
||||
const fs = require('fs');
|
||||
const archiver = require('archiver');
|
||||
const archive = archiver('zip');
|
||||
|
||||
res.on('close', function() {
|
||||
console.log('zip ' + archive.pointer() + ' bytes');
|
||||
});
|
||||
|
||||
archive.on('error', function(err: any) {
|
||||
throw err;
|
||||
});
|
||||
|
||||
archive.pipe(res);
|
||||
|
||||
// append photos in selected directory
|
||||
for (const ext of SupportedFormats.WithDots.Photos) {
|
||||
archive.glob(`*${ext}`, {cwd:absoluteDirectoryName, nocase:true});
|
||||
}
|
||||
// append videos in selected directory
|
||||
for (const ext of SupportedFormats.WithDots.Videos) {
|
||||
archive.glob(`*${ext}`, {cwd:absoluteDirectoryName, nocase:true});
|
||||
}
|
||||
|
||||
await archive.finalize(function(err: any) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
req.resultPipe = true;
|
||||
});
|
||||
return next();
|
||||
|
||||
} catch (err) {
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, 'Error creating zip', err));
|
||||
}
|
||||
}
|
||||
|
||||
public static cleanUpGalleryResults(req: Request, res: Response, next: NextFunction): any {
|
||||
if (!req.resultPipe) {
|
||||
|
@ -71,6 +71,13 @@ export class RenderingMWs {
|
||||
return res.sendFile(req.resultPipe, {maxAge: 31536000, dotfiles: 'allow'});
|
||||
}
|
||||
|
||||
public static renderZipStream(req: Request, res: Response, next: NextFunction): any {
|
||||
if (!req.resultPipe) {
|
||||
return next();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public static renderOK(req: Request, res: Response, next: NextFunction): void {
|
||||
const message = new Message<string>(null, 'ok');
|
||||
res.json(message);
|
||||
|
@ -23,6 +23,7 @@ export class GalleryRouter {
|
||||
this.addGetMetaFile(app);
|
||||
this.addRandom(app);
|
||||
this.addDirectoryList(app);
|
||||
this.addDirectoryZip(app);
|
||||
|
||||
this.addSearch(app);
|
||||
this.addAutoComplete(app);
|
||||
@ -44,6 +45,18 @@ export class GalleryRouter {
|
||||
);
|
||||
}
|
||||
|
||||
protected static addDirectoryZip(app: Express): void {
|
||||
app.get(['/api/gallery/zip/:directory(*)'],
|
||||
// common part
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.normalizePathParam('directory'),
|
||||
AuthenticationMWs.authorisePath('directory', true),
|
||||
|
||||
// specific part
|
||||
GalleryMWs.zipDirectory,
|
||||
RenderingMWs.renderZipStream
|
||||
);
|
||||
}
|
||||
|
||||
protected static addGetImage(app: Express): void {
|
||||
app.get(['/api/gallery/content/:mediaPath(*\.(' + SupportedFormats.Photos.join('|') + '))'],
|
||||
|
@ -105,6 +105,8 @@ export class ClientOtherConfig {
|
||||
NavBar: NavBarConfig = new NavBarConfig();
|
||||
@ConfigProperty()
|
||||
captionFirstNaming: boolean = false; // shows the caption instead of the filename in the photo grid
|
||||
@ConfigProperty()
|
||||
enableDownloadZip: boolean = false;
|
||||
}
|
||||
|
||||
@SubConfigClass()
|
||||
|
@ -15,6 +15,9 @@
|
||||
</ol>
|
||||
|
||||
<div class="right-side">
|
||||
<a *ngIf="config.Client.Other.enableDownloadZip && directory && ItemCount > 0" [href]="'/api/gallery/zip/' + getDirectoryPath()"
|
||||
[queryParams]="queryService.getParams()">Download</a>
|
||||
<div class="divider" *ngIf="directory && ItemCount > 0"> </div>
|
||||
<div class="photos-count" *ngIf="ItemCount > 0 && config.Client.Other.NavBar.showItemCount">
|
||||
{{ItemCount}} <span i18n>items</span>
|
||||
</div>
|
||||
|
@ -93,6 +93,10 @@ export class GalleryNavigatorComponent implements OnChanges {
|
||||
this.galleryService.setSorting(sorting);
|
||||
}
|
||||
|
||||
getDirectoryPath(): string {
|
||||
return Utils.concatUrls(this.directory.path, this.directory.name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
interface NavigatorPath {
|
||||
|
@ -60,6 +60,13 @@
|
||||
[ngModel]="states.Client.captionFirstNaming">
|
||||
</app-settings-entry>
|
||||
|
||||
<app-settings-entry
|
||||
name="Download Zip"
|
||||
description="Enable download zip of a directory contents"
|
||||
i18n-description i18n-name
|
||||
[ngModel]="states.Client.enableDownloadZip">
|
||||
</app-settings-entry>
|
||||
|
||||
|
||||
|
||||
<hr/>
|
||||
|
Loading…
x
Reference in New Issue
Block a user