diff --git a/backend/middlewares/AdminMWs.ts b/backend/middlewares/AdminMWs.ts index 9ddf9c85..d955dd9b 100644 --- a/backend/middlewares/AdminMWs.ts +++ b/backend/middlewares/AdminMWs.ts @@ -3,13 +3,14 @@ import {ErrorCodes, ErrorDTO} from '../../common/entities/Error'; import {ObjectManagerRepository} from '../model/ObjectManagerRepository'; import {Logger} from '../Logger'; import {SQLConnection} from '../model/sql/SQLConnection'; -import {DataBaseConfig, DatabaseType, IndexingConfig, ThumbnailConfig} from '../../common/config/private/IPrivateConfig'; +import {DataBaseConfig, DatabaseType, IndexingConfig, IPrivateConfig, ThumbnailConfig} from '../../common/config/private/IPrivateConfig'; import {Config} from '../../common/config/private/Config'; import {ConfigDiagnostics} from '../model/ConfigDiagnostics'; import {ClientConfig} from '../../common/config/public/ConfigClass'; import {BasicConfigDTO} from '../../common/entities/settings/BasicConfigDTO'; import {OtherConfigDTO} from '../../common/entities/settings/OtherConfigDTO'; import {ProjectPath} from '../ProjectPath'; +import {PrivateConfigClass} from '../../common/config/private/PrivateConfigClass'; const LOG_TAG = '[AdminMWs]'; @@ -244,18 +245,21 @@ export class AdminMWs { try { const settings: OtherConfigDTO = req.body.settings; - Config.Client.enableCache = settings.enableCache; - Config.Client.enableOnScrollRendering = settings.enableOnScrollRendering; - Config.Client.enableOnScrollThumbnailPrioritising = settings.enableOnScrollThumbnailPrioritising; - Config.Client.defaultPhotoSortingMethod = settings.defaultPhotoSortingMethod; + Config.Client.Other.enableCache = settings.Client.enableCache; + Config.Client.Other.enableOnScrollRendering = settings.Client.enableOnScrollRendering; + Config.Client.Other.enableOnScrollThumbnailPrioritising = settings.Client.enableOnScrollThumbnailPrioritising; + Config.Client.Other.defaultPhotoSortingMethod = settings.Client.defaultPhotoSortingMethod; + Config.Client.Other.NavBar.showItemCount = settings.Client.NavBar.showItemCount; // only updating explicitly set config (not saving config set by the diagnostics) - const original = Config.original(); - original.Client.enableCache = settings.enableCache; - original.Client.enableOnScrollRendering = settings.enableOnScrollRendering; - original.Client.enableOnScrollThumbnailPrioritising = settings.enableOnScrollThumbnailPrioritising; - original.Client.defaultPhotoSortingMethod = settings.defaultPhotoSortingMethod; - original.Server.enableThreading = settings.enableThreading; + const original: PrivateConfigClass = Config.original(); + original.Client.Other.enableCache = settings.Client.enableCache; + original.Client.Other.enableOnScrollRendering = settings.Client.enableOnScrollRendering; + original.Client.Other.enableOnScrollThumbnailPrioritising = settings.Client.enableOnScrollThumbnailPrioritising; + original.Client.Other.defaultPhotoSortingMethod = settings.Client.defaultPhotoSortingMethod; + original.Client.Other.NavBar.showItemCount = settings.Client.NavBar.showItemCount; + original.Server.threading.enable = settings.Server.enable; + original.Server.threading.thumbnailThreads = settings.Server.thumbnailThreads; original.save(); await ConfigDiagnostics.runDiagnostics(); Logger.info(LOG_TAG, 'new config:'); diff --git a/backend/middlewares/thumbnail/ThumbnailGeneratorMWs.ts b/backend/middlewares/thumbnail/ThumbnailGeneratorMWs.ts index 937a1b2e..1b6ae226 100644 --- a/backend/middlewares/thumbnail/ThumbnailGeneratorMWs.ts +++ b/backend/middlewares/thumbnail/ThumbnailGeneratorMWs.ts @@ -26,18 +26,22 @@ export class ThumbnailGeneratorMWs { } - if (Config.Server.enableThreading === true || + if (Config.Server.threading.enable === true || Config.Server.thumbnail.processingLibrary !== ThumbnailProcessingLib.Jimp) { - Config.Client.concurrentThumbnailGenerations = Math.max(1, os.cpus().length - 1); + if (Config.Server.threading.thumbnailThreads > 0) { + Config.Client.Thumbnail.concurrentThumbnailGenerations = Config.Server.threading.thumbnailThreads; + } else { + Config.Client.Thumbnail.concurrentThumbnailGenerations = Math.max(1, os.cpus().length - 1); + } } else { - Config.Client.concurrentThumbnailGenerations = 1; + Config.Client.Thumbnail.concurrentThumbnailGenerations = 1; } - if (Config.Server.enableThreading === true && + if (Config.Server.threading.enable === true && Config.Server.thumbnail.processingLibrary === ThumbnailProcessingLib.Jimp) { - this.taskQue = new ThumbnailTH(Config.Client.concurrentThumbnailGenerations); + this.taskQue = new ThumbnailTH(Config.Client.Thumbnail.concurrentThumbnailGenerations); } else { - this.taskQue = new TaskQue(Config.Client.concurrentThumbnailGenerations); + this.taskQue = new TaskQue(Config.Client.Thumbnail.concurrentThumbnailGenerations); } this.initDone = true; diff --git a/backend/model/DiskManger.ts b/backend/model/DiskManger.ts index a753291b..f5914630 100644 --- a/backend/model/DiskManger.ts +++ b/backend/model/DiskManger.ts @@ -11,7 +11,7 @@ export class DiskManager { static threadPool: DiskManagerTH = null; public static init() { - if (Config.Server.enableThreading === true) { + if (Config.Server.threading.enable === true) { DiskManager.threadPool = new DiskManagerTH(1); } } @@ -22,7 +22,7 @@ export class DiskManager { let directory: DirectoryDTO = null; - if (Config.Server.enableThreading === true) { + if (Config.Server.threading.enable === true) { directory = await DiskManager.threadPool.execute(relativeDirectoryName); } else { directory = await DiskMangerWorker.scanDirectory(relativeDirectoryName); diff --git a/common/Utils.ts b/common/Utils.ts index 17bc5031..fc79c936 100644 --- a/common/Utils.ts +++ b/common/Utils.ts @@ -29,6 +29,22 @@ export class Utils { } + + /** + * + * @param from + * @param to inclusive + * @returns {Array} + */ + static createRange(from: number, to: number): Array { + const arr = new Array(to - from + 1); + let c = to - from + 1; + while (c--) { + arr[c] = to--; + } + return arr; + } + static concatUrls(...args: Array) { let url = ''; for (let i = 0; i < args.length; i++) { diff --git a/common/config/private/IPrivateConfig.ts b/common/config/private/IPrivateConfig.ts index a1f2e0d3..c19f441f 100644 --- a/common/config/private/IPrivateConfig.ts +++ b/common/config/private/IPrivateConfig.ts @@ -51,12 +51,17 @@ export interface IndexingConfig { reIndexingSensitivity: ReIndexingSensitivity; } +export interface ThreadingConfig { + enable: boolean; + thumbnailThreads: number; +} + export interface ServerConfig { port: number; imagesFolder: string; thumbnail: ThumbnailConfig; + threading: ThreadingConfig; database: DataBaseConfig; - enableThreading: boolean; sharing: SharingConfig; sessionTimeout: number; indexing: IndexingConfig; diff --git a/common/config/private/PrivateConfigClass.ts b/common/config/private/PrivateConfigClass.ts index 9847a4b0..f3120771 100644 --- a/common/config/private/PrivateConfigClass.ts +++ b/common/config/private/PrivateConfigClass.ts @@ -33,12 +33,15 @@ export class PrivateConfigClass extends PublicConfigClass implements IPrivateCon sharing: { updateTimeout: 1000 * 60 * 5 }, + threading: { + enable: true, + thumbnailThreads: 0 + }, indexing: { folderPreviewSize: 2, cachedFolderTimeout: 1000 * 60 * 60, reIndexingSensitivity: ReIndexingSensitivity.medium - }, - enableThreading: true + } }; private ConfigLoader: any; diff --git a/common/config/public/ConfigClass.ts b/common/config/public/ConfigClass.ts index ce1d5c53..495ad86b 100644 --- a/common/config/public/ConfigClass.ts +++ b/common/config/public/ConfigClass.ts @@ -28,24 +28,33 @@ export module ClientConfig { export interface ThumbnailConfig { iconSize: number; thumbnailSizes: Array; + concurrentThumbnailGenerations: number; + } + + export interface NavBarConfig { + showItemCount: boolean; + } + + export interface OtherConfig { + enableCache: boolean; + enableOnScrollRendering: boolean; + defaultPhotoSortingMethod: SortingMethods; + enableOnScrollThumbnailPrioritising: boolean; + NavBar: NavBarConfig; } export interface Config { applicationTitle: string; + publicUrl: string; + urlBase: string; Thumbnail: ThumbnailConfig; Search: SearchConfig; Sharing: SharingConfig; Map: MapConfig; RandomPhoto: RandomPhotoConfig; - concurrentThumbnailGenerations: number; - enableCache: boolean; - enableOnScrollRendering: boolean; - enableOnScrollThumbnailPrioritising: boolean; + Other: OtherConfig; authenticationRequired: boolean; - publicUrl: string; - urlBase: string; languages: string[]; - defaultPhotoSortingMethod: SortingMethods; } } @@ -58,6 +67,7 @@ export class PublicConfigClass { public Client: ClientConfig.Config = { applicationTitle: 'PiGallery 2', Thumbnail: { + concurrentThumbnailGenerations: 1, thumbnailSizes: [200, 400, 600], iconSize: 30 }, @@ -81,15 +91,19 @@ export class PublicConfigClass { RandomPhoto: { enabled: true }, - concurrentThumbnailGenerations: 1, - enableCache: true, - enableOnScrollRendering: true, - enableOnScrollThumbnailPrioritising: true, + Other: { + enableCache: true, + enableOnScrollRendering: true, + enableOnScrollThumbnailPrioritising: true, + defaultPhotoSortingMethod: SortingMethods.ascDate, + NavBar: { + showItemCount: true + } + }, authenticationRequired: true, publicUrl: '', urlBase: '', - languages: [], - defaultPhotoSortingMethod: SortingMethods.ascDate + languages: [] }; } diff --git a/common/entities/settings/OtherConfigDTO.ts b/common/entities/settings/OtherConfigDTO.ts index de51fdd1..1e112fdc 100644 --- a/common/entities/settings/OtherConfigDTO.ts +++ b/common/entities/settings/OtherConfigDTO.ts @@ -1,9 +1,7 @@ -import {SortingMethods} from '../SortingMethods'; +import {ClientConfig} from '../../config/public/ConfigClass'; +import {ThreadingConfig} from '../../config/private/IPrivateConfig'; export interface OtherConfigDTO { - enableCache: boolean; - enableOnScrollRendering: boolean; - enableOnScrollThumbnailPrioritising: boolean; - enableThreading: boolean; - defaultPhotoSortingMethod: SortingMethods; + Server: ThreadingConfig; + Client: ClientConfig.OtherConfig; } diff --git a/frontend/app/gallery/cache.gallery.service.ts b/frontend/app/gallery/cache.gallery.service.ts index bac71040..4808590c 100644 --- a/frontend/app/gallery/cache.gallery.service.ts +++ b/frontend/app/gallery/cache.gallery.service.ts @@ -97,7 +97,7 @@ export class GalleryCacheService { public getDirectory(directoryName: string): DirectoryDTO { - if (Config.Client.enableCache === false) { + if (Config.Client.Other.enableCache === false) { return null; } const value = localStorage.getItem(GalleryCacheService.CONTENT_PREFIX + Utils.concatUrls(directoryName)); @@ -111,7 +111,7 @@ export class GalleryCacheService { } public setDirectory(directory: DirectoryDTO): void { - if (Config.Client.enableCache === false) { + if (Config.Client.Other.enableCache === false) { return; } @@ -137,7 +137,7 @@ export class GalleryCacheService { */ public photoUpdated(photo: PhotoDTO): void { - if (Config.Client.enableCache === false) { + if (Config.Client.Other.enableCache === false) { return; } diff --git a/frontend/app/gallery/gallery.service.ts b/frontend/app/gallery/gallery.service.ts index 7c8ad8f3..def4d1a7 100644 --- a/frontend/app/gallery/gallery.service.ts +++ b/frontend/app/gallery/gallery.service.ts @@ -26,7 +26,7 @@ export class GalleryService { private _shareService: ShareService, private navigatoinService: NavigationService) { this.content = new BehaviorSubject(new ContentWrapper()); - this.sorting = new BehaviorSubject(Config.Client.defaultPhotoSortingMethod); + this.sorting = new BehaviorSubject(Config.Client.Other.defaultPhotoSortingMethod); } lastRequest: { directory: string } = { diff --git a/frontend/app/gallery/grid/grid.gallery.component.ts b/frontend/app/gallery/grid/grid.gallery.component.ts index e8bdda97..59eb8531 100644 --- a/frontend/app/gallery/grid/grid.gallery.component.ts +++ b/frontend/app/gallery/grid/grid.gallery.component.ts @@ -137,7 +137,7 @@ export class GalleryGridComponent implements OnChanges, OnInit, AfterViewInit, O ngAfterViewInit() { this.lightbox.setGridPhotoQL(this.gridPhotoQL); - if (Config.Client.enableOnScrollThumbnailPrioritising === true) { + if (Config.Client.Other.enableOnScrollThumbnailPrioritising === true) { this.gridPhotoQL.changes.subscribe(() => { this.scrollListenerPhotos = this.gridPhotoQL.filter(pc => pc.ScrollListener); }); @@ -273,7 +273,7 @@ export class GalleryGridComponent implements OnChanges, OnInit, AfterViewInit, O * @returns {boolean} */ private shouldRenderMore(offset: number = 0): boolean { - return Config.Client.enableOnScrollRendering === false || + return Config.Client.Other.enableOnScrollRendering === false || PageHelper.ScrollY >= (document.body.clientHeight + offset - window.innerHeight) * 0.7 || (document.body.clientHeight + offset) * 0.85 < window.innerHeight; @@ -288,7 +288,7 @@ export class GalleryGridComponent implements OnChanges, OnInit, AfterViewInit, O window.requestAnimationFrame(() => { this.renderPhotos(); - if (Config.Client.enableOnScrollThumbnailPrioritising === true) { + if (Config.Client.Other.enableOnScrollThumbnailPrioritising === true) { this.scrollListenerPhotos.forEach((pc: GalleryPhotoComponent) => { pc.onScroll(); }); diff --git a/frontend/app/gallery/navigator/navigator.gallery.component.css b/frontend/app/gallery/navigator/navigator.gallery.component.css index 4d432c88..532c78dc 100644 --- a/frontend/app/gallery/navigator/navigator.gallery.component.css +++ b/frontend/app/gallery/navigator/navigator.gallery.component.css @@ -20,7 +20,7 @@ } ol { - padding-right: 130px; + padding-right: 150px; } .dropdown-menu { diff --git a/frontend/app/gallery/navigator/navigator.gallery.component.html b/frontend/app/gallery/navigator/navigator.gallery.component.html index 91c9a2ec..33818ca3 100644 --- a/frontend/app/gallery/navigator/navigator.gallery.component.html +++ b/frontend/app/gallery/navigator/navigator.gallery.component.html @@ -8,10 +8,10 @@
-
+
{{directory.photos.length}} items
-
 
+
 
- +
+ name="imagesFolder" required> Images are loaded from this folder (read permission required)
diff --git a/frontend/app/settings/other/other.settings.component.html b/frontend/app/settings/other/other.settings.component.html index d2b4aa8c..2dea3dfa 100644 --- a/frontend/app/settings/other/other.settings.component.html +++ b/frontend/app/settings/other/other.settings.component.html @@ -1,4 +1,4 @@ -
+
Other settings @@ -7,20 +7,21 @@ -
+

Threads:

+
+ [(ngModel)]="settings.Server.enable"> Runs directory scanning and thumbnail generation (only for Jimp) in a different thread @@ -28,6 +29,20 @@
+
+ +
+ + Number of threads that are used to generate thumbnails. If auto, number of CPU cores -1 threads will be used. +
+
+ + +

Misc:

@@ -42,7 +57,7 @@ [switch-on-text]="text.Enabled" [switch-handle-width]="'100'" [switch-label-width]="'20'" - [(ngModel)]="settings.enableOnScrollThumbnailPrioritising"> + [(ngModel)]="settings.Client.enableOnScrollThumbnailPrioritising"> Those thumbnails get higher priority that are visible on the screen @@ -62,7 +77,7 @@ [switch-on-text]="text.Enabled" [switch-handle-width]="'100'" [switch-label-width]="'20'" - [(ngModel)]="settings.enableOnScrollRendering"> + [(ngModel)]="settings.Client.enableOnScrollRendering"> Shows only the required amount of photos at once. Renders more if page bottom is reached @@ -84,7 +99,7 @@ [switch-on-text]="text.Enabled" [switch-handle-width]="'100'" [switch-label-width]="'20'" - [(ngModel)]="settings.enableCache"> + [(ngModel)]="settings.Client.enableCache"> Caches directory contents and search results for better performance @@ -92,10 +107,33 @@
+

Navigation bar:

+
+ +
+ + + Show hte number of items (photos) in the folder + +
+
+ + +
-