mirror of
https://github.com/xuthus83/pigallery2.git
synced 2025-01-14 14:43:17 +08:00
Fixing settings bugs, adding max number of thumbnail rendering thread settings
This commit is contained in:
parent
fd74f761dc
commit
90c04b7f6b
@ -3,13 +3,14 @@ import {ErrorCodes, ErrorDTO} from '../../common/entities/Error';
|
|||||||
import {ObjectManagerRepository} from '../model/ObjectManagerRepository';
|
import {ObjectManagerRepository} from '../model/ObjectManagerRepository';
|
||||||
import {Logger} from '../Logger';
|
import {Logger} from '../Logger';
|
||||||
import {SQLConnection} from '../model/sql/SQLConnection';
|
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 {Config} from '../../common/config/private/Config';
|
||||||
import {ConfigDiagnostics} from '../model/ConfigDiagnostics';
|
import {ConfigDiagnostics} from '../model/ConfigDiagnostics';
|
||||||
import {ClientConfig} from '../../common/config/public/ConfigClass';
|
import {ClientConfig} from '../../common/config/public/ConfigClass';
|
||||||
import {BasicConfigDTO} from '../../common/entities/settings/BasicConfigDTO';
|
import {BasicConfigDTO} from '../../common/entities/settings/BasicConfigDTO';
|
||||||
import {OtherConfigDTO} from '../../common/entities/settings/OtherConfigDTO';
|
import {OtherConfigDTO} from '../../common/entities/settings/OtherConfigDTO';
|
||||||
import {ProjectPath} from '../ProjectPath';
|
import {ProjectPath} from '../ProjectPath';
|
||||||
|
import {PrivateConfigClass} from '../../common/config/private/PrivateConfigClass';
|
||||||
|
|
||||||
|
|
||||||
const LOG_TAG = '[AdminMWs]';
|
const LOG_TAG = '[AdminMWs]';
|
||||||
@ -244,18 +245,21 @@ export class AdminMWs {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const settings: OtherConfigDTO = req.body.settings;
|
const settings: OtherConfigDTO = req.body.settings;
|
||||||
Config.Client.enableCache = settings.enableCache;
|
Config.Client.Other.enableCache = settings.Client.enableCache;
|
||||||
Config.Client.enableOnScrollRendering = settings.enableOnScrollRendering;
|
Config.Client.Other.enableOnScrollRendering = settings.Client.enableOnScrollRendering;
|
||||||
Config.Client.enableOnScrollThumbnailPrioritising = settings.enableOnScrollThumbnailPrioritising;
|
Config.Client.Other.enableOnScrollThumbnailPrioritising = settings.Client.enableOnScrollThumbnailPrioritising;
|
||||||
Config.Client.defaultPhotoSortingMethod = settings.defaultPhotoSortingMethod;
|
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)
|
// only updating explicitly set config (not saving config set by the diagnostics)
|
||||||
const original = Config.original();
|
const original: PrivateConfigClass = Config.original();
|
||||||
original.Client.enableCache = settings.enableCache;
|
original.Client.Other.enableCache = settings.Client.enableCache;
|
||||||
original.Client.enableOnScrollRendering = settings.enableOnScrollRendering;
|
original.Client.Other.enableOnScrollRendering = settings.Client.enableOnScrollRendering;
|
||||||
original.Client.enableOnScrollThumbnailPrioritising = settings.enableOnScrollThumbnailPrioritising;
|
original.Client.Other.enableOnScrollThumbnailPrioritising = settings.Client.enableOnScrollThumbnailPrioritising;
|
||||||
original.Client.defaultPhotoSortingMethod = settings.defaultPhotoSortingMethod;
|
original.Client.Other.defaultPhotoSortingMethod = settings.Client.defaultPhotoSortingMethod;
|
||||||
original.Server.enableThreading = settings.enableThreading;
|
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();
|
original.save();
|
||||||
await ConfigDiagnostics.runDiagnostics();
|
await ConfigDiagnostics.runDiagnostics();
|
||||||
Logger.info(LOG_TAG, 'new config:');
|
Logger.info(LOG_TAG, 'new config:');
|
||||||
|
@ -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.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 {
|
} 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) {
|
Config.Server.thumbnail.processingLibrary === ThumbnailProcessingLib.Jimp) {
|
||||||
this.taskQue = new ThumbnailTH(Config.Client.concurrentThumbnailGenerations);
|
this.taskQue = new ThumbnailTH(Config.Client.Thumbnail.concurrentThumbnailGenerations);
|
||||||
} else {
|
} else {
|
||||||
this.taskQue = new TaskQue(Config.Client.concurrentThumbnailGenerations);
|
this.taskQue = new TaskQue(Config.Client.Thumbnail.concurrentThumbnailGenerations);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.initDone = true;
|
this.initDone = true;
|
||||||
|
@ -11,7 +11,7 @@ export class DiskManager {
|
|||||||
static threadPool: DiskManagerTH = null;
|
static threadPool: DiskManagerTH = null;
|
||||||
|
|
||||||
public static init() {
|
public static init() {
|
||||||
if (Config.Server.enableThreading === true) {
|
if (Config.Server.threading.enable === true) {
|
||||||
DiskManager.threadPool = new DiskManagerTH(1);
|
DiskManager.threadPool = new DiskManagerTH(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -22,7 +22,7 @@ export class DiskManager {
|
|||||||
|
|
||||||
let directory: DirectoryDTO = null;
|
let directory: DirectoryDTO = null;
|
||||||
|
|
||||||
if (Config.Server.enableThreading === true) {
|
if (Config.Server.threading.enable === true) {
|
||||||
directory = await DiskManager.threadPool.execute(relativeDirectoryName);
|
directory = await DiskManager.threadPool.execute(relativeDirectoryName);
|
||||||
} else {
|
} else {
|
||||||
directory = await DiskMangerWorker.scanDirectory(relativeDirectoryName);
|
directory = await DiskMangerWorker.scanDirectory(relativeDirectoryName);
|
||||||
|
@ -29,6 +29,22 @@ export class Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param from
|
||||||
|
* @param to inclusive
|
||||||
|
* @returns {Array}
|
||||||
|
*/
|
||||||
|
static createRange(from: number, to: number): Array<number> {
|
||||||
|
const arr = new Array(to - from + 1);
|
||||||
|
let c = to - from + 1;
|
||||||
|
while (c--) {
|
||||||
|
arr[c] = to--;
|
||||||
|
}
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
static concatUrls(...args: Array<string>) {
|
static concatUrls(...args: Array<string>) {
|
||||||
let url = '';
|
let url = '';
|
||||||
for (let i = 0; i < args.length; i++) {
|
for (let i = 0; i < args.length; i++) {
|
||||||
|
@ -51,12 +51,17 @@ export interface IndexingConfig {
|
|||||||
reIndexingSensitivity: ReIndexingSensitivity;
|
reIndexingSensitivity: ReIndexingSensitivity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ThreadingConfig {
|
||||||
|
enable: boolean;
|
||||||
|
thumbnailThreads: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface ServerConfig {
|
export interface ServerConfig {
|
||||||
port: number;
|
port: number;
|
||||||
imagesFolder: string;
|
imagesFolder: string;
|
||||||
thumbnail: ThumbnailConfig;
|
thumbnail: ThumbnailConfig;
|
||||||
|
threading: ThreadingConfig;
|
||||||
database: DataBaseConfig;
|
database: DataBaseConfig;
|
||||||
enableThreading: boolean;
|
|
||||||
sharing: SharingConfig;
|
sharing: SharingConfig;
|
||||||
sessionTimeout: number;
|
sessionTimeout: number;
|
||||||
indexing: IndexingConfig;
|
indexing: IndexingConfig;
|
||||||
|
@ -33,12 +33,15 @@ export class PrivateConfigClass extends PublicConfigClass implements IPrivateCon
|
|||||||
sharing: {
|
sharing: {
|
||||||
updateTimeout: 1000 * 60 * 5
|
updateTimeout: 1000 * 60 * 5
|
||||||
},
|
},
|
||||||
|
threading: {
|
||||||
|
enable: true,
|
||||||
|
thumbnailThreads: 0
|
||||||
|
},
|
||||||
indexing: {
|
indexing: {
|
||||||
folderPreviewSize: 2,
|
folderPreviewSize: 2,
|
||||||
cachedFolderTimeout: 1000 * 60 * 60,
|
cachedFolderTimeout: 1000 * 60 * 60,
|
||||||
reIndexingSensitivity: ReIndexingSensitivity.medium
|
reIndexingSensitivity: ReIndexingSensitivity.medium
|
||||||
},
|
}
|
||||||
enableThreading: true
|
|
||||||
};
|
};
|
||||||
private ConfigLoader: any;
|
private ConfigLoader: any;
|
||||||
|
|
||||||
|
@ -28,24 +28,33 @@ export module ClientConfig {
|
|||||||
export interface ThumbnailConfig {
|
export interface ThumbnailConfig {
|
||||||
iconSize: number;
|
iconSize: number;
|
||||||
thumbnailSizes: Array<number>;
|
thumbnailSizes: Array<number>;
|
||||||
|
concurrentThumbnailGenerations: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface NavBarConfig {
|
||||||
|
showItemCount: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OtherConfig {
|
||||||
|
enableCache: boolean;
|
||||||
|
enableOnScrollRendering: boolean;
|
||||||
|
defaultPhotoSortingMethod: SortingMethods;
|
||||||
|
enableOnScrollThumbnailPrioritising: boolean;
|
||||||
|
NavBar: NavBarConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Config {
|
export interface Config {
|
||||||
applicationTitle: string;
|
applicationTitle: string;
|
||||||
|
publicUrl: string;
|
||||||
|
urlBase: string;
|
||||||
Thumbnail: ThumbnailConfig;
|
Thumbnail: ThumbnailConfig;
|
||||||
Search: SearchConfig;
|
Search: SearchConfig;
|
||||||
Sharing: SharingConfig;
|
Sharing: SharingConfig;
|
||||||
Map: MapConfig;
|
Map: MapConfig;
|
||||||
RandomPhoto: RandomPhotoConfig;
|
RandomPhoto: RandomPhotoConfig;
|
||||||
concurrentThumbnailGenerations: number;
|
Other: OtherConfig;
|
||||||
enableCache: boolean;
|
|
||||||
enableOnScrollRendering: boolean;
|
|
||||||
enableOnScrollThumbnailPrioritising: boolean;
|
|
||||||
authenticationRequired: boolean;
|
authenticationRequired: boolean;
|
||||||
publicUrl: string;
|
|
||||||
urlBase: string;
|
|
||||||
languages: string[];
|
languages: string[];
|
||||||
defaultPhotoSortingMethod: SortingMethods;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -58,6 +67,7 @@ export class PublicConfigClass {
|
|||||||
public Client: ClientConfig.Config = {
|
public Client: ClientConfig.Config = {
|
||||||
applicationTitle: 'PiGallery 2',
|
applicationTitle: 'PiGallery 2',
|
||||||
Thumbnail: {
|
Thumbnail: {
|
||||||
|
concurrentThumbnailGenerations: 1,
|
||||||
thumbnailSizes: [200, 400, 600],
|
thumbnailSizes: [200, 400, 600],
|
||||||
iconSize: 30
|
iconSize: 30
|
||||||
},
|
},
|
||||||
@ -81,15 +91,19 @@ export class PublicConfigClass {
|
|||||||
RandomPhoto: {
|
RandomPhoto: {
|
||||||
enabled: true
|
enabled: true
|
||||||
},
|
},
|
||||||
concurrentThumbnailGenerations: 1,
|
Other: {
|
||||||
enableCache: true,
|
enableCache: true,
|
||||||
enableOnScrollRendering: true,
|
enableOnScrollRendering: true,
|
||||||
enableOnScrollThumbnailPrioritising: true,
|
enableOnScrollThumbnailPrioritising: true,
|
||||||
|
defaultPhotoSortingMethod: SortingMethods.ascDate,
|
||||||
|
NavBar: {
|
||||||
|
showItemCount: true
|
||||||
|
}
|
||||||
|
},
|
||||||
authenticationRequired: true,
|
authenticationRequired: true,
|
||||||
publicUrl: '',
|
publicUrl: '',
|
||||||
urlBase: '',
|
urlBase: '',
|
||||||
languages: [],
|
languages: []
|
||||||
defaultPhotoSortingMethod: SortingMethods.ascDate
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
import {SortingMethods} from '../SortingMethods';
|
import {ClientConfig} from '../../config/public/ConfigClass';
|
||||||
|
import {ThreadingConfig} from '../../config/private/IPrivateConfig';
|
||||||
|
|
||||||
export interface OtherConfigDTO {
|
export interface OtherConfigDTO {
|
||||||
enableCache: boolean;
|
Server: ThreadingConfig;
|
||||||
enableOnScrollRendering: boolean;
|
Client: ClientConfig.OtherConfig;
|
||||||
enableOnScrollThumbnailPrioritising: boolean;
|
|
||||||
enableThreading: boolean;
|
|
||||||
defaultPhotoSortingMethod: SortingMethods;
|
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ export class GalleryCacheService {
|
|||||||
|
|
||||||
|
|
||||||
public getDirectory(directoryName: string): DirectoryDTO {
|
public getDirectory(directoryName: string): DirectoryDTO {
|
||||||
if (Config.Client.enableCache === false) {
|
if (Config.Client.Other.enableCache === false) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const value = localStorage.getItem(GalleryCacheService.CONTENT_PREFIX + Utils.concatUrls(directoryName));
|
const value = localStorage.getItem(GalleryCacheService.CONTENT_PREFIX + Utils.concatUrls(directoryName));
|
||||||
@ -111,7 +111,7 @@ export class GalleryCacheService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public setDirectory(directory: DirectoryDTO): void {
|
public setDirectory(directory: DirectoryDTO): void {
|
||||||
if (Config.Client.enableCache === false) {
|
if (Config.Client.Other.enableCache === false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,7 +137,7 @@ export class GalleryCacheService {
|
|||||||
*/
|
*/
|
||||||
public photoUpdated(photo: PhotoDTO): void {
|
public photoUpdated(photo: PhotoDTO): void {
|
||||||
|
|
||||||
if (Config.Client.enableCache === false) {
|
if (Config.Client.Other.enableCache === false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ export class GalleryService {
|
|||||||
private _shareService: ShareService,
|
private _shareService: ShareService,
|
||||||
private navigatoinService: NavigationService) {
|
private navigatoinService: NavigationService) {
|
||||||
this.content = new BehaviorSubject<ContentWrapper>(new ContentWrapper());
|
this.content = new BehaviorSubject<ContentWrapper>(new ContentWrapper());
|
||||||
this.sorting = new BehaviorSubject<SortingMethods>(Config.Client.defaultPhotoSortingMethod);
|
this.sorting = new BehaviorSubject<SortingMethods>(Config.Client.Other.defaultPhotoSortingMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
lastRequest: { directory: string } = {
|
lastRequest: { directory: string } = {
|
||||||
|
@ -137,7 +137,7 @@ export class GalleryGridComponent implements OnChanges, OnInit, AfterViewInit, O
|
|||||||
ngAfterViewInit() {
|
ngAfterViewInit() {
|
||||||
this.lightbox.setGridPhotoQL(this.gridPhotoQL);
|
this.lightbox.setGridPhotoQL(this.gridPhotoQL);
|
||||||
|
|
||||||
if (Config.Client.enableOnScrollThumbnailPrioritising === true) {
|
if (Config.Client.Other.enableOnScrollThumbnailPrioritising === true) {
|
||||||
this.gridPhotoQL.changes.subscribe(() => {
|
this.gridPhotoQL.changes.subscribe(() => {
|
||||||
this.scrollListenerPhotos = this.gridPhotoQL.filter(pc => pc.ScrollListener);
|
this.scrollListenerPhotos = this.gridPhotoQL.filter(pc => pc.ScrollListener);
|
||||||
});
|
});
|
||||||
@ -273,7 +273,7 @@ export class GalleryGridComponent implements OnChanges, OnInit, AfterViewInit, O
|
|||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
private shouldRenderMore(offset: number = 0): 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
|
PageHelper.ScrollY >= (document.body.clientHeight + offset - window.innerHeight) * 0.7
|
||||||
|| (document.body.clientHeight + offset) * 0.85 < window.innerHeight;
|
|| (document.body.clientHeight + offset) * 0.85 < window.innerHeight;
|
||||||
|
|
||||||
@ -288,7 +288,7 @@ export class GalleryGridComponent implements OnChanges, OnInit, AfterViewInit, O
|
|||||||
window.requestAnimationFrame(() => {
|
window.requestAnimationFrame(() => {
|
||||||
this.renderPhotos();
|
this.renderPhotos();
|
||||||
|
|
||||||
if (Config.Client.enableOnScrollThumbnailPrioritising === true) {
|
if (Config.Client.Other.enableOnScrollThumbnailPrioritising === true) {
|
||||||
this.scrollListenerPhotos.forEach((pc: GalleryPhotoComponent) => {
|
this.scrollListenerPhotos.forEach((pc: GalleryPhotoComponent) => {
|
||||||
pc.onScroll();
|
pc.onScroll();
|
||||||
});
|
});
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
ol {
|
ol {
|
||||||
padding-right: 130px;
|
padding-right: 150px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-menu {
|
.dropdown-menu {
|
||||||
|
@ -8,10 +8,10 @@
|
|||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<div class="right-side">
|
<div class="right-side">
|
||||||
<div class="photos-count" *ngIf="directory.photos.length > 0">
|
<div class="photos-count" *ngIf="directory.photos.length > 0 && config.Client.Other.NavBar.showItemCount">
|
||||||
{{directory.photos.length}} <span i18n>items</span>
|
{{directory.photos.length}} <span i18n>items</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="divider" *ngIf="directory.photos.length > 0"> </div>
|
<div class="divider" *ngIf="directory.photos.length > 0 && config.Client.Other.NavBar.showItemCount"> </div>
|
||||||
<div class="btn-group" dropdown placement="bottom right">
|
<div class="btn-group" dropdown placement="bottom right">
|
||||||
<button id="button-alignment" dropdownToggle type="button"
|
<button id="button-alignment" dropdownToggle type="button"
|
||||||
class="btn btn-default dropdown-toggle" aria-controls="dropdown-alignment"
|
class="btn btn-default dropdown-toggle" aria-controls="dropdown-alignment"
|
||||||
|
@ -8,6 +8,7 @@ import {QueryService} from '../../model/query.service';
|
|||||||
import {GalleryService} from '../gallery.service';
|
import {GalleryService} from '../gallery.service';
|
||||||
import {Utils} from '../../../../common/Utils';
|
import {Utils} from '../../../../common/Utils';
|
||||||
import {SortingMethods} from '../../../../common/entities/SortingMethods';
|
import {SortingMethods} from '../../../../common/entities/SortingMethods';
|
||||||
|
import {Config} from '../../../../common/config/public/Config';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-gallery-navbar',
|
selector: 'app-gallery-navbar',
|
||||||
@ -21,6 +22,7 @@ export class GalleryNavigatorComponent implements OnChanges {
|
|||||||
routes: Array<NavigatorPath> = [];
|
routes: Array<NavigatorPath> = [];
|
||||||
SortingMethods = SortingMethods;
|
SortingMethods = SortingMethods;
|
||||||
sortingMethodsType: { key: number; value: string }[] = [];
|
sortingMethodsType: { key: number; value: string }[] = [];
|
||||||
|
config = Config;
|
||||||
|
|
||||||
constructor(private _authService: AuthenticationService,
|
constructor(private _authService: AuthenticationService,
|
||||||
public queryService: QueryService,
|
public queryService: QueryService,
|
||||||
|
@ -19,7 +19,7 @@ export class ThumbnailLoaderService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
run = () => {
|
run = () => {
|
||||||
if (this.que.length === 0 || this.runningRequests >= Config.Client.concurrentThumbnailGenerations) {
|
if (this.que.length === 0 || this.runningRequests >= Config.Client.Thumbnail.concurrentThumbnailGenerations) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const task = this.getNextTask();
|
const task = this.getNextTask();
|
||||||
|
@ -19,7 +19,7 @@ export abstract class SettingsComponent<T, S extends AbstractSettingsService<T>
|
|||||||
@ViewChild('settingsForm')
|
@ViewChild('settingsForm')
|
||||||
form: HTMLFormElement;
|
form: HTMLFormElement;
|
||||||
|
|
||||||
@Output('hasAvailableSettings')
|
@Output()
|
||||||
hasAvailableSettings = true;
|
hasAvailableSettings = true;
|
||||||
|
|
||||||
public inProgress = false;
|
public inProgress = false;
|
||||||
@ -61,6 +61,31 @@ export abstract class SettingsComponent<T, S extends AbstractSettingsService<T>
|
|||||||
this.ngOnChanges();
|
this.ngOnChanges();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
settingsSame(newSettings: T, original: T): boolean {
|
||||||
|
if (typeof original !== 'object' || original == null) {
|
||||||
|
return newSettings === original;
|
||||||
|
}
|
||||||
|
if (!newSettings) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const keys = Object.keys(newSettings);
|
||||||
|
for (let i = 0; i < keys.length; i++) {
|
||||||
|
const key = keys[i];
|
||||||
|
if (typeof original[key] === 'undefined') {
|
||||||
|
throw new Error('unknown settings: ' + key);
|
||||||
|
}
|
||||||
|
if (typeof original[key] === 'object') {
|
||||||
|
if (this.settingsSame(newSettings[key], original[key]) === false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (newSettings[key] !== original[key]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
if (!this._authService.isAuthenticated() ||
|
if (!this._authService.isAuthenticated() ||
|
||||||
this._authService.user.value.role < UserRoles.Admin) {
|
this._authService.user.value.role < UserRoles.Admin) {
|
||||||
@ -69,11 +94,11 @@ export abstract class SettingsComponent<T, S extends AbstractSettingsService<T>
|
|||||||
}
|
}
|
||||||
this.getSettings();
|
this.getSettings();
|
||||||
|
|
||||||
this._subscription = this.form.valueChanges.subscribe((data) => {
|
// TODO: fix after this issue is fixed: https://github.com/angular/angular/issues/24818
|
||||||
if (!data) {
|
this._subscription = this.form.valueChanges.subscribe(() => {
|
||||||
return;
|
setTimeout(() => {
|
||||||
}
|
this.changed = !this.settingsSame(this.settings, this.original);
|
||||||
this.changed = !Utils.equalsFilter(data, this.original);
|
}, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -31,12 +31,12 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<label class="col-md-2 control-label" for="folder" i18n>Images folder</label>
|
<label class="col-md-2 control-label" for="imagesFolder" i18n>Images folder</label>
|
||||||
<div class="col-md-10">
|
<div class="col-md-10">
|
||||||
<input type="text" class="form-control" placeholder="path"
|
<input type="text" class="form-control" placeholder="path"
|
||||||
id="folder"
|
id="imagesFolder"
|
||||||
[(ngModel)]="settings.imagesFolder"
|
[(ngModel)]="settings.imagesFolder"
|
||||||
name="folder" required>
|
name="imagesFolder" required>
|
||||||
<small class="form-text text-muted" i18n>Images are loaded from this folder (read permission required)</small>
|
<small class="form-text text-muted" i18n>Images are loaded from this folder (read permission required)</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<form #settingsForm="ngForm" class="form-horizontal">
|
<form #settingsForm="ngForm" class="form-horizontal" >
|
||||||
<div class="card mb-4">
|
<div class="card mb-4">
|
||||||
<h5 class="card-header" i18n>
|
<h5 class="card-header" i18n>
|
||||||
Other settings
|
Other settings
|
||||||
@ -7,20 +7,21 @@
|
|||||||
<div [hidden]="!error" class="alert alert-danger" role="alert"><strong i18n>Error: </strong>{{error}}</div>
|
<div [hidden]="!error" class="alert alert-danger" role="alert"><strong i18n>Error: </strong>{{error}}</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="form-group row">
|
<p class="title" i18n>Threads:</p>
|
||||||
|
<div class="form-group row" >
|
||||||
<label class="col-md-2 control-label" for="enableThreading" i18n>Threading</label>
|
<label class="col-md-2 control-label" for="enableThreading" i18n>Threading</label>
|
||||||
<div class="col-md-10">
|
<div class="col-md-10">
|
||||||
<bSwitch
|
<bSwitch
|
||||||
id="enableThreading"
|
id="enableThreading"
|
||||||
class="switch"
|
class="switch"
|
||||||
name="enableThreading"
|
name="enable"
|
||||||
[switch-on-color]="'primary'"
|
[switch-on-color]="'primary'"
|
||||||
[switch-inverse]="'inverse'"
|
[switch-inverse]="'inverse'"
|
||||||
[switch-off-text]="text.Disabled"
|
[switch-off-text]="text.Disabled"
|
||||||
[switch-on-text]="text.Enabled"
|
[switch-on-text]="text.Enabled"
|
||||||
[switch-handle-width]="'100'"
|
[switch-handle-width]="'100'"
|
||||||
[switch-label-width]="'20'"
|
[switch-label-width]="'20'"
|
||||||
[(ngModel)]="settings.enableThreading">
|
[(ngModel)]="settings.Server.enable">
|
||||||
</bSwitch>
|
</bSwitch>
|
||||||
<small class="form-text text-muted" i18n>Runs directory scanning and thumbnail generation (only for Jimp) in a
|
<small class="form-text text-muted" i18n>Runs directory scanning and thumbnail generation (only for Jimp) in a
|
||||||
different thread
|
different thread
|
||||||
@ -28,6 +29,20 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group row" [hidden]="simplifiedMode || settings.Server.enable == false">
|
||||||
|
<label class="col-md-2 control-label" for="thumbnailThreads" i18n>Thumbnail threads</label>
|
||||||
|
<div class="col-md-10">
|
||||||
|
<select id="thumbnailThreads" class="form-control" [(ngModel)]="settings.Server.thumbnailThreads"
|
||||||
|
name="Server[thumbnailThreads]" required>
|
||||||
|
<option [ngValue]="0">auto</option>
|
||||||
|
<option *ngFor="let i of threads" [ngValue]="i">{{i}}</option>
|
||||||
|
</select>
|
||||||
|
<small class="form-text text-muted" i18n>Number of threads that are used to generate thumbnails. If auto, number of CPU cores -1 threads will be used.</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<p class="title" i18n>Misc:</p>
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<label class="col-md-2 control-label" for="enableOnScrollThumbnailPrioritising" i18n>Scroll based thumbnail
|
<label class="col-md-2 control-label" for="enableOnScrollThumbnailPrioritising" i18n>Scroll based thumbnail
|
||||||
generation</label>
|
generation</label>
|
||||||
@ -42,7 +57,7 @@
|
|||||||
[switch-on-text]="text.Enabled"
|
[switch-on-text]="text.Enabled"
|
||||||
[switch-handle-width]="'100'"
|
[switch-handle-width]="'100'"
|
||||||
[switch-label-width]="'20'"
|
[switch-label-width]="'20'"
|
||||||
[(ngModel)]="settings.enableOnScrollThumbnailPrioritising">
|
[(ngModel)]="settings.Client.enableOnScrollThumbnailPrioritising">
|
||||||
</bSwitch>
|
</bSwitch>
|
||||||
<small class="form-text text-muted" i18n>Those thumbnails get higher priority that are visible on the screen
|
<small class="form-text text-muted" i18n>Those thumbnails get higher priority that are visible on the screen
|
||||||
</small>
|
</small>
|
||||||
@ -62,7 +77,7 @@
|
|||||||
[switch-on-text]="text.Enabled"
|
[switch-on-text]="text.Enabled"
|
||||||
[switch-handle-width]="'100'"
|
[switch-handle-width]="'100'"
|
||||||
[switch-label-width]="'20'"
|
[switch-label-width]="'20'"
|
||||||
[(ngModel)]="settings.enableOnScrollRendering">
|
[(ngModel)]="settings.Client.enableOnScrollRendering">
|
||||||
</bSwitch>
|
</bSwitch>
|
||||||
<small class="form-text text-muted" i18n>Shows only the required amount of photos at once. Renders more if
|
<small class="form-text text-muted" i18n>Shows only the required amount of photos at once. Renders more if
|
||||||
page bottom is reached
|
page bottom is reached
|
||||||
@ -84,7 +99,7 @@
|
|||||||
[switch-on-text]="text.Enabled"
|
[switch-on-text]="text.Enabled"
|
||||||
[switch-handle-width]="'100'"
|
[switch-handle-width]="'100'"
|
||||||
[switch-label-width]="'20'"
|
[switch-label-width]="'20'"
|
||||||
[(ngModel)]="settings.enableCache">
|
[(ngModel)]="settings.Client.enableCache">
|
||||||
</bSwitch>
|
</bSwitch>
|
||||||
<small class="form-text text-muted" i18n>Caches directory contents and search results for better performance
|
<small class="form-text text-muted" i18n>Caches directory contents and search results for better performance
|
||||||
</small>
|
</small>
|
||||||
@ -92,10 +107,33 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<p class="title" i18n>Navigation bar:</p>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label class="col-md-2 control-label" for="showItemCount" [hidden]="simplifiedMode" i18n>Show item count</label>
|
||||||
|
<div class="col-md-10">
|
||||||
|
<bSwitch
|
||||||
|
id="showItemCount"
|
||||||
|
class="switch"
|
||||||
|
name="enableCache"
|
||||||
|
[switch-on-color]="'primary'"
|
||||||
|
[switch-inverse]="'inverse'"
|
||||||
|
[switch-off-text]="text.Disabled"
|
||||||
|
[switch-on-text]="text.Enabled"
|
||||||
|
[switch-handle-width]="'100'"
|
||||||
|
[switch-label-width]="'20'"
|
||||||
|
[(ngModel)]="settings.Client.NavBar.showItemCount">
|
||||||
|
</bSwitch>
|
||||||
|
<small class="form-text text-muted" i18n>Show hte number of items (photos) in the folder
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="form-group row" [hidden]="simplifiedMode">
|
<div class="form-group row" [hidden]="simplifiedMode">
|
||||||
<label class="col-md-2 control-label" for="defaultPhotoSortingMethod" i18n>Default photo sorting method</label>
|
<label class="col-md-2 control-label" for="defaultPhotoSortingMethod" i18n>Default photo sorting method</label>
|
||||||
<div class="col-md-10">
|
<div class="col-md-10">
|
||||||
<select id="defaultPhotoSortingMethod" class="form-control" [(ngModel)]="settings.defaultPhotoSortingMethod"
|
<select id="defaultPhotoSortingMethod" class="form-control" [(ngModel)]="settings.Client.defaultPhotoSortingMethod"
|
||||||
name="defaultPhotoSortingMethod" required>
|
name="defaultPhotoSortingMethod" required>
|
||||||
<option *ngFor="let type of types" [ngValue]="type.key">{{type.key | stringifySorting}}
|
<option *ngFor="let type of types" [ngValue]="type.key">{{type.key | stringifySorting}}
|
||||||
</option>
|
</option>
|
||||||
|
@ -6,7 +6,6 @@ import {NotificationService} from '../../model/notification.service';
|
|||||||
import {OtherSettingsService} from './other.settings.service';
|
import {OtherSettingsService} from './other.settings.service';
|
||||||
import {OtherConfigDTO} from '../../../../common/entities/settings/OtherConfigDTO';
|
import {OtherConfigDTO} from '../../../../common/entities/settings/OtherConfigDTO';
|
||||||
import {I18n} from '@ngx-translate/i18n-polyfill';
|
import {I18n} from '@ngx-translate/i18n-polyfill';
|
||||||
import {ReIndexingSensitivity} from '../../../../common/config/private/IPrivateConfig';
|
|
||||||
import {Utils} from '../../../../common/Utils';
|
import {Utils} from '../../../../common/Utils';
|
||||||
import {SortingMethods} from '../../../../common/entities/SortingMethods';
|
import {SortingMethods} from '../../../../common/entities/SortingMethods';
|
||||||
|
|
||||||
@ -21,6 +20,7 @@ export class OtherSettingsComponent extends SettingsComponent<OtherConfigDTO> im
|
|||||||
|
|
||||||
|
|
||||||
types: { key: number; value: string }[] = [];
|
types: { key: number; value: string }[] = [];
|
||||||
|
threads: number[] = Utils.createRange(1, 100);
|
||||||
|
|
||||||
constructor(_authService: AuthenticationService,
|
constructor(_authService: AuthenticationService,
|
||||||
_navigation: NavigationService,
|
_navigation: NavigationService,
|
||||||
@ -28,11 +28,8 @@ export class OtherSettingsComponent extends SettingsComponent<OtherConfigDTO> im
|
|||||||
notification: NotificationService,
|
notification: NotificationService,
|
||||||
i18n: I18n) {
|
i18n: I18n) {
|
||||||
super(i18n('Other'), _authService, _navigation, _settingsService, notification, i18n, s => ({
|
super(i18n('Other'), _authService, _navigation, _settingsService, notification, i18n, s => ({
|
||||||
enableThreading: s.Server.enableThreading,
|
Server: s.Server.threading,
|
||||||
enableOnScrollThumbnailPrioritising: s.Client.enableOnScrollThumbnailPrioritising,
|
Client: s.Client.Other
|
||||||
enableOnScrollRendering: s.Client.enableOnScrollRendering,
|
|
||||||
enableCache: s.Client.enableCache,
|
|
||||||
defaultPhotoSortingMethod: s.Client.defaultPhotoSortingMethod
|
|
||||||
}));
|
}));
|
||||||
this.types = Utils.enumToArray(SortingMethods);
|
this.types = Utils.enumToArray(SortingMethods);
|
||||||
this.hasAvailableSettings = !this.simplifiedMode;
|
this.hasAvailableSettings = !this.simplifiedMode;
|
||||||
|
@ -20,8 +20,8 @@ export class SettingsService {
|
|||||||
instantSearchCacheTimeout: 1000 * 60 * 60,
|
instantSearchCacheTimeout: 1000 * 60 * 60,
|
||||||
autocompleteCacheTimeout: 1000 * 60 * 60
|
autocompleteCacheTimeout: 1000 * 60 * 60
|
||||||
},
|
},
|
||||||
concurrentThumbnailGenerations: null,
|
|
||||||
Thumbnail: {
|
Thumbnail: {
|
||||||
|
concurrentThumbnailGenerations: null,
|
||||||
iconSize: 30,
|
iconSize: 30,
|
||||||
thumbnailSizes: []
|
thumbnailSizes: []
|
||||||
},
|
},
|
||||||
@ -36,15 +36,20 @@ export class SettingsService {
|
|||||||
RandomPhoto: {
|
RandomPhoto: {
|
||||||
enabled: true
|
enabled: true
|
||||||
},
|
},
|
||||||
|
Other: {
|
||||||
|
enableCache: true,
|
||||||
|
enableOnScrollRendering: true,
|
||||||
|
enableOnScrollThumbnailPrioritising: true,
|
||||||
|
defaultPhotoSortingMethod: SortingMethods.ascDate,
|
||||||
|
NavBar: {
|
||||||
|
showItemCount: true
|
||||||
|
}
|
||||||
|
},
|
||||||
urlBase: '',
|
urlBase: '',
|
||||||
publicUrl: '',
|
publicUrl: '',
|
||||||
applicationTitle: '',
|
applicationTitle: '',
|
||||||
enableCache: true,
|
|
||||||
enableOnScrollRendering: true,
|
|
||||||
enableOnScrollThumbnailPrioritising: true,
|
|
||||||
authenticationRequired: true,
|
authenticationRequired: true,
|
||||||
languages: [],
|
languages: []
|
||||||
defaultPhotoSortingMethod: SortingMethods.ascDate
|
|
||||||
},
|
},
|
||||||
Server: {
|
Server: {
|
||||||
database: {
|
database: {
|
||||||
@ -54,13 +59,16 @@ export class SettingsService {
|
|||||||
updateTimeout: 2000
|
updateTimeout: 2000
|
||||||
},
|
},
|
||||||
imagesFolder: '',
|
imagesFolder: '',
|
||||||
enableThreading: true,
|
|
||||||
port: 80,
|
port: 80,
|
||||||
thumbnail: {
|
thumbnail: {
|
||||||
folder: '',
|
folder: '',
|
||||||
qualityPriority: true,
|
qualityPriority: true,
|
||||||
processingLibrary: ThumbnailProcessingLib.sharp
|
processingLibrary: ThumbnailProcessingLib.sharp
|
||||||
},
|
},
|
||||||
|
threading: {
|
||||||
|
enable: true,
|
||||||
|
thumbnailThreads: 0
|
||||||
|
},
|
||||||
sessionTimeout: 0,
|
sessionTimeout: 0,
|
||||||
indexing: {
|
indexing: {
|
||||||
cachedFolderTimeout: 0,
|
cachedFolderTimeout: 0,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user