1
0
mirror of https://github.com/bpatrik/pigallery2.git synced 2025-02-09 13:46:56 +02:00

code improvement

This commit is contained in:
Patrik J. Braun 2018-05-03 19:17:08 -04:00
parent 3f10c670f5
commit b6b0902392
42 changed files with 209 additions and 219 deletions

View File

@ -35,23 +35,24 @@
[switch-on-text]="text.Simplified" [switch-on-text]="text.Simplified"
[switch-handle-width]="'100'" [switch-handle-width]="'100'"
[switch-label-width]="'20'" [switch-label-width]="'20'"
i18n-
[(ngModel)]="simplifiedMode"> [(ngModel)]="simplifiedMode">
</bSwitch> </bSwitch>
</div> </div>
</div> </div>
</div> </div>
<settings-basic [simplifiedMode]="simplifiedMode"></settings-basic> <app-settings-basic [simplifiedMode]="simplifiedMode"></app-settings-basic>
<settings-usermanager></settings-usermanager> <app-settings-usermanager></app-settings-usermanager>
<settings-database [simplifiedMode]="simplifiedMode"></settings-database> <app-settings-database [simplifiedMode]="simplifiedMode"></app-settings-database>
<settings-thumbnail #thumbnail [hidden]="!thumbnail.hasAvailableSettings" <app-settings-thumbnail #thumbnail [hidden]="!thumbnail.hasAvailableSettings"
[simplifiedMode]="simplifiedMode"></settings-thumbnail> [simplifiedMode]="simplifiedMode"></app-settings-thumbnail>
<settings-search #search [hidden]="!search.hasAvailableSettings" <app-settings-search #search [hidden]="!search.hasAvailableSettings"
[simplifiedMode]="simplifiedMode"></settings-search> [simplifiedMode]="simplifiedMode"></app-settings-search>
<settings-share #share [hidden]="!share.hasAvailableSettings" [simplifiedMode]="simplifiedMode"></settings-share> <app-settings-share #share [hidden]="!share.hasAvailableSettings"
<settings-map #map [hidden]="!map.hasAvailableSettings" [simplifiedMode]="simplifiedMode"></settings-map> [simplifiedMode]="simplifiedMode"></app-settings-share>
<settings-other #other [hidden]="!other.hasAvailableSettings" [simplifiedMode]="simplifiedMode"></settings-other> <app-settings-map #map [hidden]="!map.hasAvailableSettings" [simplifiedMode]="simplifiedMode"></app-settings-map>
<settings-indexing #other [hidden]="!other.hasAvailableSettings" <app-settings-other #other [hidden]="!other.hasAvailableSettings"
[simplifiedMode]="simplifiedMode"></settings-indexing> [simplifiedMode]="simplifiedMode"></app-settings-other>
<app-settings-indexing #other [hidden]="!other.hasAvailableSettings"
[simplifiedMode]="simplifiedMode"></app-settings-indexing>
</div> </div>
</app-frame> </app-frame>

View File

@ -7,7 +7,7 @@ import {NavigationService} from '../model/navigation.service';
import {I18n} from '@ngx-translate/i18n-polyfill'; import {I18n} from '@ngx-translate/i18n-polyfill';
@Component({ @Component({
selector: 'admin', selector: 'app-admin',
templateUrl: './admin.component.html', templateUrl: './admin.component.html',
styleUrls: ['./admin.component.css'] styleUrls: ['./admin.component.css']
}) })

View File

@ -59,7 +59,7 @@ ng2-slim-loading-bar {
background-color: transparent; background-color: transparent;
} }
language { app-language {
display: block; display: block;
margin-right: 10px; margin-right: 10px;
} }

View File

@ -36,7 +36,7 @@
</a> </a>
</li> </li>
<li> <li>
<language class="navbar-btn" isDark="true"></language> <app-language class="navbar-btn" isDark="true"></app-language>
</li> </li>
<li *ngIf="authenticationRequired"> <li *ngIf="authenticationRequired">
<button class="btn btn-default navbar-btn" <button class="btn btn-default navbar-btn"

View File

@ -8,7 +8,7 @@ import {Thumbnail, ThumbnailManagerService} from '../thumnailManager.service';
import {ShareService} from '../share.service'; import {ShareService} from '../share.service';
@Component({ @Component({
selector: 'gallery-directory', selector: 'app-gallery-directory',
templateUrl: './directory.gallery.component.html', templateUrl: './directory.gallery.component.html',
styleUrls: ['./directory.gallery.component.css'], styleUrls: ['./directory.gallery.component.css'],
providers: [RouterLink], providers: [RouterLink],

View File

@ -1,4 +1,4 @@
gallery-map { app-gallery-map {
margin-right: 0; margin-right: 0;
margin-left: auto; margin-left: auto;
display: block; display: block;
@ -11,7 +11,7 @@ gallery-map {
margin-left: 2px; margin-left: 2px;
} }
gallery-directory { app-gallery-directory {
margin: 2px; margin: 2px;
display: inline-block; display: inline-block;
} }

View File

@ -13,24 +13,25 @@
</p> </p>
</li> </li>
<li *ngIf="showSearchBar"> <li *ngIf="showSearchBar">
<gallery-search #search></gallery-search> <app-gallery-search #search></app-gallery-search>
</li> </li>
<li *ngIf="showShare"> <li *ngIf="showShare">
<gallery-share></gallery-share> <app-gallery-share></app-gallery-share>
</li> </li>
</ng-container> </ng-container>
<div body class="container" style="width: 100%; padding:0" *ngIf="_galleryService.content.value.directory"> <div body class="container" style="width: 100%; padding:0" *ngIf="_galleryService.content.value.directory">
<gallery-navbar [directory]="_galleryService.content.value.directory"></gallery-navbar> <app-gallery-navbar [directory]="_galleryService.content.value.directory"></app-gallery-navbar>
<div class="directories"> <div class="directories">
<gallery-directory *ngFor="let directory of directories" <app-gallery-directory *ngFor="let directory of directories"
[directory]="directory"></gallery-directory> [directory]="directory"></app-gallery-directory>
</div> </div>
<gallery-map *ngIf="isPhotoWithLocation && mapEnabled" <app-gallery-map *ngIf="isPhotoWithLocation && mapEnabled"
[photos]="_galleryService.content.value.directory.photos"></gallery-map> [photos]="_galleryService.content.value.directory.photos"></app-gallery-map>
<gallery-grid [photos]="_galleryService.content.value.directory.photos" [lightbox]="lightbox"></gallery-grid> <app-gallery-grid [photos]="_galleryService.content.value.directory.photos"
[lightbox]="lightbox"></app-gallery-grid>
</div> </div>
<div body class="container" style="width: 100%; padding:0" *ngIf="_galleryService.content.value.searchResult"> <div body class="container" style="width: 100%; padding:0" *ngIf="_galleryService.content.value.searchResult">
@ -51,14 +52,15 @@
</li> </li>
</ol> </ol>
<gallery-map *ngIf="isPhotoWithLocation && mapEnabled" <app-gallery-map *ngIf="isPhotoWithLocation && mapEnabled"
[photos]="_galleryService.content.value.searchResult.photos"></gallery-map> [photos]="_galleryService.content.value.searchResult.photos"></app-gallery-map>
<div class="directories"> <div class="directories">
<gallery-directory *ngFor="let directory of directories" <app-gallery-directory *ngFor="let directory of directories"
[directory]="directory"></gallery-directory> [directory]="directory"></app-gallery-directory>
</div> </div>
<gallery-grid [photos]="_galleryService.content.value.searchResult.photos" [lightbox]="lightbox"></gallery-grid> <app-gallery-grid [photos]="_galleryService.content.value.searchResult.photos"
[lightbox]="lightbox"></app-gallery-grid>
</div> </div>
<div body class="container" <div body class="container"

View File

@ -4,7 +4,7 @@ export class GridRowBuilder {
private photoRow: Array<PhotoDTO> = []; private photoRow: Array<PhotoDTO> = [];
private photoIndex: number = 0; //index of the last pushed photo to the photoRow private photoIndex = 0; // index of the last pushed photo to the photoRow
constructor(private photos: Array<PhotoDTO>, constructor(private photos: Array<PhotoDTO>,
@ -43,13 +43,13 @@ export class GridRowBuilder {
} }
public adjustRowHeightBetween(minHeight: number, maxHeight: number) { public adjustRowHeightBetween(minHeight: number, maxHeight: number) {
while (this.calcRowHeight() > maxHeight && this.addPhoto() === true) { //row too high -> add more images while (this.calcRowHeight() > maxHeight && this.addPhoto() === true) { // row too high -> add more images
} }
while (this.calcRowHeight() < minHeight && this.removePhoto() === true) { //roo too small -> remove images while (this.calcRowHeight() < minHeight && this.removePhoto() === true) { // roo too small -> remove images
} }
//keep at least one photo int thr row // keep at least one photo int thr row
if (this.photoRow.length <= 0) { if (this.photoRow.length <= 0) {
this.addPhoto(); this.addPhoto();
} }
@ -58,9 +58,9 @@ export class GridRowBuilder {
public calcRowHeight(): number { public calcRowHeight(): number {
let width = 0; let width = 0;
for (let i = 0; i < this.photoRow.length; i++) { for (let i = 0; i < this.photoRow.length; i++) {
width += ((this.photoRow[i].metadata.size.width) / (this.photoRow[i].metadata.size.height)); //summing up aspect ratios width += ((this.photoRow[i].metadata.size.width) / (this.photoRow[i].metadata.size.height)); // summing up aspect ratios
} }
let height = (this.containerWidth - this.photoRow.length * (this.photoMargin * 2) - 1) / width; //cant be equal -> width-1 const height = (this.containerWidth - this.photoRow.length * (this.photoMargin * 2) - 1) / width; // cant be equal -> width-1
return height + (this.photoMargin * 2); return height + (this.photoMargin * 2);
}; };

View File

@ -4,7 +4,7 @@ div {
font-size: 0; font-size: 0;
} }
gallery-grid-photo { app-gallery-grid-photo {
display: inline-block; display: inline-block;
cursor: pointer; cursor: pointer;

View File

@ -1,5 +1,5 @@
<div #gridContainer> <div #gridContainer>
<gallery-grid-photo <app-gallery-grid-photo
*ngFor="let gridPhoto of photosToRender" *ngFor="let gridPhoto of photosToRender"
(click)="lightbox.show(gridPhoto.photo)" (click)="lightbox.show(gridPhoto.photo)"
[gridPhoto]="gridPhoto" [gridPhoto]="gridPhoto"
@ -8,5 +8,5 @@
[style.marginLeft.px]="IMAGE_MARGIN" [style.marginLeft.px]="IMAGE_MARGIN"
[style.marginRight.px]="IMAGE_MARGIN"> [style.marginRight.px]="IMAGE_MARGIN">
</gallery-grid-photo> </app-gallery-grid-photo>
</div> </div>

View File

@ -20,7 +20,7 @@ import {OverlayService} from '../overlay.service';
import {Config} from '../../../../common/config/public/Config'; import {Config} from '../../../../common/config/public/Config';
@Component({ @Component({
selector: 'gallery-grid', selector: 'app-gallery-grid',
templateUrl: './grid.gallery.component.html', templateUrl: './grid.gallery.component.html',
styleUrls: ['./grid.gallery.component.css'], styleUrls: ['./grid.gallery.component.css'],
}) })
@ -33,7 +33,7 @@ export class GalleryGridComponent implements OnChanges, AfterViewInit, OnDestroy
@Input() lightbox: GalleryLightboxComponent; @Input() lightbox: GalleryLightboxComponent;
photosToRender: Array<GridPhoto> = []; photosToRender: Array<GridPhoto> = [];
containerWidth: number = 0; containerWidth = 0;
public IMAGE_MARGIN = 2; public IMAGE_MARGIN = 2;
private TARGET_COL_COUNT = 5; private TARGET_COL_COUNT = 5;
@ -43,6 +43,8 @@ export class GalleryGridComponent implements OnChanges, AfterViewInit, OnDestroy
private onScrollFired = false; private onScrollFired = false;
private scrollbarWidth = 0; private scrollbarWidth = 0;
private helperTime = null; private helperTime = null;
isAfterViewInit = false;
private renderedPhotoIndex = 0;
constructor(private overlayService: OverlayService, constructor(private overlayService: OverlayService,
private changeDetector: ChangeDetectorRef) { private changeDetector: ChangeDetectorRef) {
@ -74,16 +76,13 @@ export class GalleryGridComponent implements OnChanges, AfterViewInit, OnDestroy
} }
this.updateContainerWidth(); this.updateContainerWidth();
this.sortPhotos(); this.sortPhotos();
//render the same amount of images on resize // render the same amount of images on resize
let renderedIndex = this.renderedPhotoIndex; const renderedIndex = this.renderedPhotoIndex;
this.clearRenderedPhotos(); this.clearRenderedPhotos();
this.renderPhotos(renderedIndex); this.renderPhotos(renderedIndex);
} }
isAfterViewInit: boolean = false;
ngAfterViewInit() { ngAfterViewInit() {
this.lightbox.setGridPhotoQL(this.gridPhotoQL); this.lightbox.setGridPhotoQL(this.gridPhotoQL);
@ -97,13 +96,38 @@ export class GalleryGridComponent implements OnChanges, AfterViewInit, OnDestroy
this.isAfterViewInit = true; this.isAfterViewInit = true;
} }
public renderARow(): number {
if (this.renderedPhotoIndex >= this.photos.length) {
return null;
}
private sortPhotos() {
//sort pohots by date let maxRowHeight = window.innerHeight / this.MIN_ROW_COUNT;
this.photos.sort((a: PhotoDTO, b: PhotoDTO) => { const minRowHeight = window.innerHeight / this.MAX_ROW_COUNT;
return a.metadata.creationDate - b.metadata.creationDate;
const photoRowBuilder = new GridRowBuilder(this.photos,
this.renderedPhotoIndex,
this.IMAGE_MARGIN,
this.containerWidth - this.overlayService.getPhantomScrollbarWidth()
);
photoRowBuilder.addPhotos(this.TARGET_COL_COUNT);
photoRowBuilder.adjustRowHeightBetween(minRowHeight, maxRowHeight);
// little trick: We don't want too big single images. But if a little extra height helps fit the row, its ok
if (photoRowBuilder.getPhotoRow().length > 1) {
maxRowHeight *= 1.2;
}
const rowHeight = Math.min(photoRowBuilder.calcRowHeight(), maxRowHeight);
const imageHeight = rowHeight - (this.IMAGE_MARGIN * 2);
photoRowBuilder.getPhotoRow().forEach((photo) => {
const imageWidth = imageHeight * (photo.metadata.size.width / photo.metadata.size.height);
this.photosToRender.push(new GridPhoto(photo, imageWidth, imageHeight, this.renderedPhotoIndex));
}); });
this.renderedPhotoIndex += photoRowBuilder.getPhotoRow().length;
return rowHeight;
} }
private clearRenderedPhotos() { private clearRenderedPhotos() {
@ -112,14 +136,22 @@ export class GalleryGridComponent implements OnChanges, AfterViewInit, OnDestroy
this.changeDetector.detectChanges(); this.changeDetector.detectChanges();
} }
private sortPhotos() {
// sort pohots by date
this.photos.sort((a: PhotoDTO, b: PhotoDTO) => {
return a.metadata.creationDate - b.metadata.creationDate;
});
}
private mergeNewPhotos() { private mergeNewPhotos() {
//merge new data with old one // merge new data with old one
let lastSameIndex = 0; let lastSameIndex = 0;
let lastRowId = null; let lastRowId = null;
for (let i = 0; i < this.photos.length && i < this.photosToRender.length; i++) { for (let i = 0; i < this.photos.length && i < this.photosToRender.length; i++) {
//thIf a photo changed the whole row has to be removed // thIf a photo changed the whole row has to be removed
if (this.photosToRender[i].rowId != lastRowId) { if (this.photosToRender[i].rowId !== lastRowId) {
lastSameIndex = i; lastSameIndex = i;
lastRowId = this.photosToRender[i].rowId; lastRowId = this.photosToRender[i].rowId;
} }
@ -137,30 +169,6 @@ export class GalleryGridComponent implements OnChanges, AfterViewInit, OnDestroy
} }
private renderedPhotoIndex: number = 0;
private renderPhotos(numberOfPhotos: number = 0) {
if (this.containerWidth == 0 ||
this.renderedPhotoIndex >= this.photos.length ||
!this.shouldRenderMore()) {
return;
}
let renderedContentHeight = 0;
while (this.renderedPhotoIndex < this.photos.length &&
(this.shouldRenderMore(renderedContentHeight) === true ||
this.renderedPhotoIndex < numberOfPhotos)) {
let ret = this.renderARow();
if (ret === null) {
throw new Error('Grid photos rendering failed');
}
renderedContentHeight += ret;
}
}
/** /**
* Returns true, if scroll is >= 70% to render more images. * Returns true, if scroll is >= 70% to render more images.
* Or of onscroll rendering is off: return always to render all the images at once * Or of onscroll rendering is off: return always to render all the images at once
@ -192,37 +200,25 @@ export class GalleryGridComponent implements OnChanges, AfterViewInit, OnDestroy
} }
} }
public renderARow(): number { private renderPhotos(numberOfPhotos: number = 0) {
if (this.renderedPhotoIndex >= this.photos.length) { if (this.containerWidth === 0 ||
return null; this.renderedPhotoIndex >= this.photos.length ||
!this.shouldRenderMore()) {
return;
} }
let maxRowHeight = window.innerHeight / this.MIN_ROW_COUNT; let renderedContentHeight = 0;
let minRowHeight = window.innerHeight / this.MAX_ROW_COUNT;
let photoRowBuilder = new GridRowBuilder(this.photos, while (this.renderedPhotoIndex < this.photos.length &&
this.renderedPhotoIndex, (this.shouldRenderMore(renderedContentHeight) === true ||
this.IMAGE_MARGIN, this.renderedPhotoIndex < numberOfPhotos)) {
this.containerWidth - this.overlayService.getPhantomScrollbarWidth() const ret = this.renderARow();
); if (ret === null) {
throw new Error('Grid photos rendering failed');
photoRowBuilder.addPhotos(this.TARGET_COL_COUNT); }
photoRowBuilder.adjustRowHeightBetween(minRowHeight, maxRowHeight); renderedContentHeight += ret;
if (photoRowBuilder.getPhotoRow().length > 1) { //little trick: We don't want too big single images. But if a little extra height helps fit the row, its ok
maxRowHeight *= 1.2;
} }
let rowHeight = Math.min(photoRowBuilder.calcRowHeight(), maxRowHeight);
let imageHeight = rowHeight - (this.IMAGE_MARGIN * 2);
photoRowBuilder.getPhotoRow().forEach((photo) => {
let imageWidth = imageHeight * (photo.metadata.size.width / photo.metadata.size.height);
this.photosToRender.push(new GridPhoto(photo, imageWidth, imageHeight, this.renderedPhotoIndex));
});
this.renderedPhotoIndex += photoRowBuilder.getPhotoRow().length;
return rowHeight;
} }
private updateContainerWidth(): number { private updateContainerWidth(): number {

View File

@ -1,7 +1,7 @@
import {Component, Input} from '@angular/core'; import {Component, Input} from '@angular/core';
@Component({ @Component({
selector: 'gallery-grid-photo-loading', selector: 'app-gallery-grid-photo-loading',
templateUrl: './loading.photo.grid.gallery.component.html', templateUrl: './loading.photo.grid.gallery.component.html',
styleUrls: ['./loading.photo.grid.gallery.component.css'], styleUrls: ['./loading.photo.grid.gallery.component.css'],
}) })

View File

@ -1,11 +1,11 @@
<div #photoContainer class="photo-container" (mouseover)="mouseOver()" (mouseout)="mouseOut()"> <div #photoContainer class="photo-container" (mouseover)="mouseOver()" (mouseout)="mouseOut()">
<img #img [src]="thumbnail.Src" *ngIf="thumbnail.Available"> <img #img [src]="thumbnail.Src" *ngIf="thumbnail.Available">
<gallery-grid-photo-loading <app-gallery-grid-photo-loading
[error]="thumbnail.Error" [error]="thumbnail.Error"
[animate]="thumbnail.loading" [animate]="thumbnail.loading"
*ngIf="!thumbnail.Available"> *ngIf="!thumbnail.Available">
</gallery-grid-photo-loading> </app-gallery-grid-photo-loading>
<!--Info box --> <!--Info box -->
<div #info class="info" <div #info class="info"

View File

@ -8,7 +8,7 @@ import {Config} from '../../../../../common/config/public/Config';
import {AnimationBuilder} from '@angular/animations'; import {AnimationBuilder} from '@angular/animations';
@Component({ @Component({
selector: 'gallery-grid-photo', selector: 'app-gallery-grid-photo',
templateUrl: './photo.grid.gallery.component.html', templateUrl: './photo.grid.gallery.component.html',
styleUrls: ['./photo.grid.gallery.component.css'], styleUrls: ['./photo.grid.gallery.component.css'],
providers: [RouterLink] providers: [RouterLink]
@ -20,18 +20,6 @@ export class GalleryPhotoComponent implements IRenderable, OnInit, OnDestroy {
@ViewChild('photoContainer') container: ElementRef; @ViewChild('photoContainer') container: ElementRef;
thumbnail: Thumbnail; thumbnail: Thumbnail;
/*
image = {
src: '',
show: false
};
loading = {
animate: false,
show: true
};
*/
infoBar = { infoBar = {
marginTop: 0, marginTop: 0,
visible: false, visible: false,
@ -40,7 +28,7 @@ export class GalleryPhotoComponent implements IRenderable, OnInit, OnDestroy {
animationTimer = null; animationTimer = null;
SearchTypes: any = []; SearchTypes: any = [];
searchEnabled: boolean = true; searchEnabled = true;
wasInView: boolean = null; wasInView: boolean = null;
@ -71,11 +59,11 @@ export class GalleryPhotoComponent implements IRenderable, OnInit, OnDestroy {
onScroll() { onScroll() {
if (this.thumbnail.Available == true) { if (this.thumbnail.Available === true) {
return; return;
} }
let isInView = this.isInView(); const isInView = this.isInView();
if (this.wasInView != isInView) { if (this.wasInView !== isInView) {
this.wasInView = isInView; this.wasInView = isInView;
this.thumbnail.Visible = isInView; this.thumbnail.Visible = isInView;
} }

View File

@ -3,7 +3,7 @@ import {PhotoDTO} from '../../../../../common/entities/PhotoDTO';
import {Config} from '../../../../../common/config/public/Config'; import {Config} from '../../../../../common/config/public/Config';
@Component({ @Component({
selector: 'info-panel', selector: 'app-info-panel',
styleUrls: ['./info-panel.lightbox.gallery.component.css'], styleUrls: ['./info-panel.lightbox.gallery.component.css'],
templateUrl: './info-panel.lightbox.gallery.component.html', templateUrl: './info-panel.lightbox.gallery.component.html',
}) })
@ -21,7 +21,7 @@ export class InfoPanelLightboxComponent {
} }
calcFileSize() { calcFileSize() {
let postFixes = ['B', 'KB', 'MB', 'GB', 'TB']; const postFixes = ['B', 'KB', 'MB', 'GB', 'TB'];
let index = 0; let index = 0;
let size = this.photo.metadata.fileSize; let size = this.photo.metadata.fileSize;
while (size > 1000 && index < postFixes.length - 1) { while (size > 1000 && index < postFixes.length - 1) {
@ -42,7 +42,7 @@ export class InfoPanelLightboxComponent {
getDate() { getDate() {
const date = new Date(this.photo.metadata.creationDate); const date = new Date(this.photo.metadata.creationDate);
let locale = 'en-us'; const locale = 'en-us';
return date.toLocaleString(locale, {month: 'long'}) + ' ' + date.getDate(); return date.toLocaleString(locale, {month: 'long'}) + ' ' + date.getDate();
} }
@ -53,7 +53,7 @@ export class InfoPanelLightboxComponent {
getDay() { getDay() {
const date = new Date(this.photo.metadata.creationDate); const date = new Date(this.photo.metadata.creationDate);
let locale = 'en-us'; const locale = 'en-us';
return date.toLocaleString(locale, {weekday: 'long'}); return date.toLocaleString(locale, {weekday: 'long'});
} }
@ -76,7 +76,7 @@ export class InfoPanelLightboxComponent {
let str = this.photo.metadata.positionData.city || let str = this.photo.metadata.positionData.city ||
this.photo.metadata.positionData.state; this.photo.metadata.positionData.state;
if (str.length != 0) { if (str.length !== 0) {
str += ', '; str += ', ';
} }
str += this.photo.metadata.positionData.country; str += this.photo.metadata.positionData.country;

View File

@ -9,7 +9,7 @@
cursor: pointer; cursor: pointer;
} }
gallery-lightbox-photo { app-gallery-lightbox-photo {
overflow: hidden; overflow: hidden;
} }
@ -120,7 +120,7 @@ gallery-lightbox-photo {
animation: blink 3s ease-in-out infinite; animation: blink 3s ease-in-out infinite;
} }
info-panel { app-info-panel {
z-index: 1100; /* Sit on top */ z-index: 1100; /* Sit on top */
position: fixed; position: fixed;
height: 100vh; height: 100vh;

View File

@ -5,11 +5,11 @@
</div> </div>
<div class="lightbox" #lightbox> <div class="lightbox" #lightbox>
<gallery-lightbox-photo [gridPhoto]="activePhoto ? activePhoto.gridPhoto : null" <app-gallery-lightbox-photo [gridPhoto]="activePhoto ? activePhoto.gridPhoto : null"
[loadImage]="!animating" [loadImage]="!animating"
[windowAspect]="getPhotoFrameWidth()/getPhotoFrameHeight()" [windowAspect]="getPhotoFrameWidth()/getPhotoFrameHeight()"
#photo> #photo>
</gallery-lightbox-photo> </app-gallery-lightbox-photo>
</div> </div>
<div <div
(swipeleft)="nextImage()" (swiperight)="prevImage()" (swipeup)="hide()" (swipeleft)="nextImage()" (swiperight)="prevImage()" (swipeup)="hide()"
@ -62,11 +62,11 @@
title="fast auto play"></span> title="fast auto play"></span>
</div> </div>
</div> </div>
<info-panel *ngIf="activePhoto && infoPanelVisible" <app-info-panel *ngIf="activePhoto && infoPanelVisible"
id="info-panel" id="info-panel"
[style.width.px]="infoPanelWidth" [style.width.px]="infoPanelWidth"
[photo]="activePhoto.gridPhoto.photo" [photo]="activePhoto.gridPhoto.photo"
(onClose)="hideInfoPanel()"> (onClose)="hideInfoPanel()">
</info-panel> </app-info-panel>
</div> </div>

View File

@ -2,7 +2,7 @@ import {Component, ElementRef, Input, OnChanges} from '@angular/core';
import {GridPhoto} from '../../grid/GridPhoto'; import {GridPhoto} from '../../grid/GridPhoto';
@Component({ @Component({
selector: 'gallery-lightbox-photo', selector: 'app-gallery-lightbox-photo',
styleUrls: ['./photo.lightbox.gallery.component.css'], styleUrls: ['./photo.lightbox.gallery.component.css'],
templateUrl: './photo.lightbox.gallery.component.html' templateUrl: './photo.lightbox.gallery.component.html'
}) })
@ -51,7 +51,7 @@ export class GalleryLightboxPhotoComponent implements OnChanges {
} }
public showThumbnail(): boolean { public showThumbnail(): boolean {
return this.gridPhoto /*&& !this.imageLoaded*/ && return this.gridPhoto && !this.imageLoaded &&
(this.gridPhoto.isThumbnailAvailable() || this.gridPhoto.isReplacementThumbnailAvailable()); (this.gridPhoto.isThumbnailAvailable() || this.gridPhoto.isReplacementThumbnailAvailable());
} }

View File

@ -8,7 +8,7 @@ import {IconPhoto} from '../../IconPhoto';
import {Photo} from '../../Photo'; import {Photo} from '../../Photo';
@Component({ @Component({
selector: 'gallery-map-lightbox', selector: 'app-gallery-map-lightbox',
styleUrls: ['./lightbox.map.gallery.component.css'], styleUrls: ['./lightbox.map.gallery.component.css'],
templateUrl: './lightbox.map.gallery.component.html', templateUrl: './lightbox.map.gallery.component.html',
}) })
@ -32,9 +32,9 @@ export class GalleryMapLightboxComponent implements OnChanges {
private thumbnailService: ThumbnailManagerService) { private thumbnailService: ThumbnailManagerService) {
} }
//TODO: fix zooming // TODO: fix zooming
ngOnChanges() { ngOnChanges() {
if (this.visible == false) { if (this.visible === false) {
return; return;
} }
this.showImages(); this.showImages();
@ -70,9 +70,9 @@ export class GalleryMapLightboxComponent implements OnChanges {
public hide() { public hide() {
this.fullScreenService.exitFullScreen(); this.fullScreenService.exitFullScreen();
let to = this.startPosition; const to = this.startPosition;
//iff target image out of screen -> scroll to there // iff target image out of screen -> scroll to there
if (this.getBodyScrollTop() > to.top || this.getBodyScrollTop() + this.getScreenHeight() < to.top) { if (this.getBodyScrollTop() > to.top || this.getBodyScrollTop() + this.getScreenHeight() < to.top) {
this.setBodyScrollTop(to.top); this.setBodyScrollTop(to.top);
} }
@ -113,7 +113,7 @@ export class GalleryMapLightboxComponent implements OnChanges {
} }
}; };
if (iconTh.Available == true) { if (iconTh.Available === true) {
obj.iconUrl = iconTh.Src; obj.iconUrl = iconTh.Src;
} else { } else {
iconTh.OnLoad = () => { iconTh.OnLoad = () => {
@ -163,12 +163,12 @@ export class GalleryMapLightboxComponent implements OnChanges {
//noinspection JSUnusedGlobalSymbols //noinspection JSUnusedGlobalSymbols
@HostListener('window:keydown', ['$event']) @HostListener('window:keydown', ['$event'])
onKeyPress(e: KeyboardEvent) { onKeyPress(e: KeyboardEvent) {
if (this.visible != true) { if (this.visible !== true) {
return; return;
} }
let event: KeyboardEvent = window.event ? <any>window.event : e; const event: KeyboardEvent = window.event ? <any>window.event : e;
switch (event.keyCode) { switch (event.keyCode) {
case 27: //escape case 27: // escape
this.hide(); this.hide();
break; break;
} }
@ -186,6 +186,6 @@ export interface MapPhoto {
width: number; width: number;
height: number; height: number;
thumbnail: Thumbnail; thumbnail: Thumbnail;
} };
} }

View File

@ -1,5 +1,5 @@
<ng-template [ngIf]="mapPhotos.length>0"> <ng-template [ngIf]="mapPhotos.length>0">
<gallery-map-lightbox [photos]="photos"></gallery-map-lightbox> <app-gallery-map-lightbox [photos]="photos"></app-gallery-map-lightbox>
<div id="map" #map> <div id="map" #map>
<agm-map <agm-map
(click)="click()" (click)="click()"

View File

@ -4,7 +4,7 @@ import {Dimension, IRenderable} from '../../model/IRenderable';
import {GalleryMapLightboxComponent} from './lightbox/lightbox.map.gallery.component'; import {GalleryMapLightboxComponent} from './lightbox/lightbox.map.gallery.component';
@Component({ @Component({
selector: 'gallery-map', selector: 'app-gallery-map',
templateUrl: './map.gallery.component.html', templateUrl: './map.gallery.component.html',
styleUrls: ['./map.gallery.component.css'] styleUrls: ['./map.gallery.component.css']
}) })
@ -17,7 +17,7 @@ export class GalleryMapComponent implements OnChanges, IRenderable {
mapCenter = {latitude: 0, longitude: 0}; mapCenter = {latitude: 0, longitude: 0};
@ViewChild('map') map: ElementRef; @ViewChild('map') map: ElementRef;
//TODO: fix zooming // TODO: fix zooming
ngOnChanges() { ngOnChanges() {
this.mapPhotos = this.photos.filter(p => { this.mapPhotos = this.photos.filter(p => {
return p.metadata && p.metadata.positionData && p.metadata.positionData.GPSData && return p.metadata && p.metadata.positionData && p.metadata.positionData.GPSData &&

View File

@ -7,7 +7,7 @@ import {ShareService} from '../share.service';
import {I18n} from '@ngx-translate/i18n-polyfill'; import {I18n} from '@ngx-translate/i18n-polyfill';
@Component({ @Component({
selector: 'gallery-navbar', selector: 'app-gallery-navbar',
templateUrl: './navigator.gallery.component.html', templateUrl: './navigator.gallery.component.html',
providers: [RouterLink], providers: [RouterLink],
}) })
@ -31,12 +31,12 @@ export class GalleryNavigatorComponent implements OnChanges {
return []; return [];
} }
let path = this.directory.path.replace(new RegExp('\\\\', 'g'), '/'); const path = this.directory.path.replace(new RegExp('\\\\', 'g'), '/');
let dirs = path.split('/'); const dirs = path.split('/');
dirs.push(this.directory.name); dirs.push(this.directory.name);
//removing empty strings // removing empty strings
for (let i = 0; i < dirs.length; i++) { for (let i = 0; i < dirs.length; i++) {
if (!dirs[i] || 0 === dirs[i].length || '.' === dirs[i]) { if (!dirs[i] || 0 === dirs[i].length || '.' === dirs[i]) {
dirs.splice(i, 1); dirs.splice(i, 1);
@ -45,19 +45,19 @@ export class GalleryNavigatorComponent implements OnChanges {
} }
const user = this._authService.user.value; const user = this._authService.user.value;
let arr: NavigatorPath[] = []; const arr: NavigatorPath[] = [];
//create root link // create root link
if (dirs.length == 0) { if (dirs.length === 0) {
arr.push({name: this.i18n('Images'), route: null}); arr.push({name: this.i18n('Images'), route: null});
} else { } else {
arr.push({name: this.i18n('Images'), route: UserDTO.isPathAvailable('/', user.permissions) ? '/' : null}); arr.push({name: this.i18n('Images'), route: UserDTO.isPathAvailable('/', user.permissions) ? '/' : null});
} }
//create rest navigation // create rest navigation
dirs.forEach((name, index) => { dirs.forEach((name, index) => {
const route = dirs.slice(0, dirs.indexOf(name) + 1).join('/'); const route = dirs.slice(0, dirs.indexOf(name) + 1).join('/');
if (dirs.length - 1 == index) { if (dirs.length - 1 === index) {
arr.push({name: name, route: null}); arr.push({name: name, route: null});
} else { } else {
arr.push({name: name, route: UserDTO.isPathAvailable(route, user.permissions) ? route : null}); arr.push({name: name, route: UserDTO.isPathAvailable(route, user.permissions) ? route : null});

View File

@ -1,4 +1,4 @@
import {Component} from '@angular/core'; import {Component, OnDestroy} from '@angular/core';
import {AutoCompleteService} from './autocomplete.service'; import {AutoCompleteService} from './autocomplete.service';
import {AutoCompleteItem, SearchTypes} from '../../../../common/entities/AutoCompleteItem'; import {AutoCompleteItem, SearchTypes} from '../../../../common/entities/AutoCompleteItem';
import {ActivatedRoute, Params, RouterLink} from '@angular/router'; import {ActivatedRoute, Params, RouterLink} from '@angular/router';
@ -6,23 +6,23 @@ import {GalleryService} from '../gallery.service';
import {Config} from '../../../../common/config/public/Config'; import {Config} from '../../../../common/config/public/Config';
@Component({ @Component({
selector: 'gallery-search', selector: 'app-gallery-search',
templateUrl: './search.gallery.component.html', templateUrl: './search.gallery.component.html',
styleUrls: ['./search.gallery.component.css'], styleUrls: ['./search.gallery.component.css'],
providers: [AutoCompleteService, RouterLink] providers: [AutoCompleteService, RouterLink]
}) })
export class GallerySearchComponent { export class GallerySearchComponent implements OnDestroy {
autoCompleteItems: Array<AutoCompleteRenderItem> = []; autoCompleteItems: Array<AutoCompleteRenderItem> = [];
public searchText: string = ''; public searchText = '';
private cache = { private cache = {
lastAutocomplete: '', lastAutocomplete: '',
lastInstantSearch: '' lastInstantSearch: ''
}; };
SearchTypes: any = []; SearchTypes: any = [];
mouseOverAutoComplete = false;
private subscription = null; private readonly subscription = null;
constructor(private _autoCompleteService: AutoCompleteService, constructor(private _autoCompleteService: AutoCompleteService,
private _galleryService: GalleryService, private _galleryService: GalleryService,
@ -31,8 +31,8 @@ export class GallerySearchComponent {
this.SearchTypes = SearchTypes; this.SearchTypes = SearchTypes;
this.subscription = this._route.params.subscribe((params: Params) => { this.subscription = this._route.params.subscribe((params: Params) => {
let searchText = params['searchText']; const searchText = params['searchText'];
if (searchText && searchText != '') { if (searchText && searchText !== '') {
this.searchText = searchText; this.searchText = searchText;
} }
}); });
@ -47,14 +47,14 @@ export class GallerySearchComponent {
onSearchChange(event: KeyboardEvent) { onSearchChange(event: KeyboardEvent) {
let searchText = (<HTMLInputElement>event.target).value.trim(); const searchText = (<HTMLInputElement>event.target).value.trim();
if (Config.Client.Search.autocompleteEnabled && this.cache.lastAutocomplete != searchText) { if (Config.Client.Search.autocompleteEnabled && this.cache.lastAutocomplete !== searchText) {
this.cache.lastAutocomplete = searchText; this.cache.lastAutocomplete = searchText;
this.autocomplete(searchText); this.autocomplete(searchText);
} }
if (Config.Client.Search.instantSearchEnabled && this.cache.lastInstantSearch != searchText) { if (Config.Client.Search.instantSearchEnabled && this.cache.lastInstantSearch !== searchText) {
this.cache.lastInstantSearch = searchText; this.cache.lastInstantSearch = searchText;
this._galleryService.instantSearch(searchText); this._galleryService.instantSearch(searchText);
} }
@ -72,14 +72,13 @@ export class GallerySearchComponent {
} }
mouseOverAutoComplete: boolean = false;
public setMouseOverAutoComplete(value: boolean) { public setMouseOverAutoComplete(value: boolean) {
this.mouseOverAutoComplete = value; this.mouseOverAutoComplete = value;
} }
public onFocusLost() { public onFocusLost() {
if (this.mouseOverAutoComplete == false) { if (this.mouseOverAutoComplete === false) {
this.autoCompleteItems = []; this.autoCompleteItems = [];
} }
} }
@ -96,7 +95,7 @@ export class GallerySearchComponent {
if (!Config.Client.Search.autocompleteEnabled) { if (!Config.Client.Search.autocompleteEnabled) {
return; return;
} }
if (searchText.trim() == '.') { if (searchText.trim() === '.') {
return; return;
} }
@ -117,7 +116,7 @@ export class GallerySearchComponent {
private showSuggestions(suggestions: Array<AutoCompleteItem>, searchText: string) { private showSuggestions(suggestions: Array<AutoCompleteItem>, searchText: string) {
this.emptyAutoComplete(); this.emptyAutoComplete();
suggestions.forEach((item: AutoCompleteItem) => { suggestions.forEach((item: AutoCompleteItem) => {
let renderItem = new AutoCompleteRenderItem(item.text, searchText, item.type); const renderItem = new AutoCompleteRenderItem(item.text, searchText, item.type);
this.autoCompleteItems.push(renderItem); this.autoCompleteItems.push(renderItem);
}); });
} }
@ -129,13 +128,13 @@ export class GallerySearchComponent {
} }
class AutoCompleteRenderItem { class AutoCompleteRenderItem {
public preText: string = ''; public preText = '';
public highLightText: string = ''; public highLightText = '';
public postText: string = ''; public postText = '';
public type: SearchTypes; public type: SearchTypes;
constructor(public text: string, searchText: string, type: SearchTypes) { constructor(public text: string, searchText: string, type: SearchTypes) {
let preIndex = text.toLowerCase().indexOf(searchText.toLowerCase()); const preIndex = text.toLowerCase().indexOf(searchText.toLowerCase());
if (preIndex > -1) { if (preIndex > -1) {
this.preText = text.substring(0, preIndex); this.preText = text.substring(0, preIndex);
this.highLightText = text.substring(preIndex, preIndex + searchText.length); this.highLightText = text.substring(preIndex, preIndex + searchText.length);

View File

@ -12,15 +12,15 @@ import {I18n} from '@ngx-translate/i18n-polyfill';
@Component({ @Component({
selector: 'gallery-share', selector: 'app-gallery-share',
templateUrl: './share.gallery.component.html', templateUrl: './share.gallery.component.html',
styleUrls: ['./share.gallery.component.css'], styleUrls: ['./share.gallery.component.css'],
}) })
export class GalleryShareComponent implements OnInit, OnDestroy { export class GalleryShareComponent implements OnInit, OnDestroy {
@ViewChild('shareModal') public childModal: ModalDirective; @ViewChild('shareModal') public childModal: ModalDirective;
enabled: boolean = true; enabled = true;
url: string = ''; url = '';
input = { input = {
includeSubfolders: true, includeSubfolders: true,
@ -30,7 +30,7 @@ export class GalleryShareComponent implements OnInit, OnDestroy {
}, },
password: '' password: ''
}; };
currentDir: string = ''; currentDir = '';
sharing: SharingDTO = null; sharing: SharingDTO = null;
contentSubscription = null; contentSubscription = null;
passwordProtection = false; passwordProtection = false;
@ -62,7 +62,7 @@ export class GalleryShareComponent implements OnInit, OnDestroy {
} }
calcValidity() { calcValidity() {
switch (parseInt(this.input.valid.type.toString())) { switch (parseInt(this.input.valid.type.toString(), 10)) {
case ValidityTypes.Minutes: case ValidityTypes.Minutes:
return this.input.valid.amount * 1000 * 60; return this.input.valid.amount * 1000 * 60;
case ValidityTypes.Hours: case ValidityTypes.Hours:
@ -80,7 +80,8 @@ export class GalleryShareComponent implements OnInit, OnDestroy {
return; return;
} }
this.url = 'loading..'; this.url = 'loading..';
this.sharing = await this._sharingService.updateSharing(this.currentDir, this.sharing.id, this.input.includeSubfolders, this.input.password, this.calcValidity()); this.sharing = await this._sharingService.updateSharing(this.currentDir,
this.sharing.id, this.input.includeSubfolders, this.input.password, this.calcValidity());
this.url = Config.Client.publicUrl + '/share/' + this.sharing.sharingKey; this.url = Config.Client.publicUrl + '/share/' + this.sharing.sharingKey;
} }

View File

@ -4,7 +4,7 @@ import {Cookie} from 'ng2-cookies';
import {CookieNames} from '../../../common/CookieNames'; import {CookieNames} from '../../../common/CookieNames';
@Component({ @Component({
selector: 'language', selector: 'app-language',
templateUrl: './language.component.html', templateUrl: './language.component.html',
styleUrls: ['./language.component.css'], styleUrls: ['./language.component.css'],
}) })

View File

@ -1,6 +1,6 @@
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<language class="pull-right"></language> <app-language class="pull-right"></app-language>
</div> </div>
<div class="row title"> <div class="row title">
<h1><img src="assets/icon.png"/>{{title}}</h1> <h1><img src="assets/icon.png"/>{{title}}</h1>

View File

@ -26,7 +26,7 @@ describe('UserService', () => {
it('should call postJson at login', inject([UserService, NetworkService], (userService, networkService) => { it('should call postJson at login', inject([UserService, NetworkService], (userService, networkService) => {
spyOn(networkService, 'postJson'); spyOn(networkService, 'postJson');
let credential = new LoginCredential('name', 'pass'); const credential = new LoginCredential('name', 'pass');
userService.login(credential); userService.login(credential);
expect(networkService.postJson).toHaveBeenCalled(); expect(networkService.postJson).toHaveBeenCalled();
expect(networkService.postJson.calls.argsFor(0)).toEqual(['/user/login', {'loginCredential': credential}]); expect(networkService.postJson.calls.argsFor(0)).toEqual(['/user/login', {'loginCredential': credential}]);

View File

@ -27,7 +27,7 @@ export class UserService {
public async getSessionUser(): Promise<UserDTO> { public async getSessionUser(): Promise<UserDTO> {
await this._shareService.wait(); await this._shareService.wait();
if (Config.Client.Sharing.enabled == true) { if (Config.Client.Sharing.enabled === true) {
if (this._shareService.isSharing()) { if (this._shareService.isSharing()) {
return this._networkService.getJson<UserDTO>('/user/login?sk=' + this._shareService.getSharingKey()); return this._networkService.getJson<UserDTO>('/user/login?sk=' + this._shareService.getSharingKey());
} }

View File

@ -26,7 +26,7 @@ export abstract class SettingsComponent<T, S extends AbstractSettingsService<T>=
public error: string = null; public error: string = null;
public changed = false; public changed = false;
private _subscription = null; private _subscription = null;
private _settingsSubscription = null; private readonly _settingsSubscription = null;
public settings: T = <any>{}; public settings: T = <any>{};
public original: T = <any>{}; public original: T = <any>{};

View File

@ -8,7 +8,7 @@ import {BasicConfigDTO} from '../../../../common/entities/settings/BasicConfigDT
import {I18n} from '@ngx-translate/i18n-polyfill'; import {I18n} from '@ngx-translate/i18n-polyfill';
@Component({ @Component({
selector: 'settings-basic', selector: 'app-settings-basic',
templateUrl: './basic.settings.component.html', templateUrl: './basic.settings.component.html',
styleUrls: ['./basic.settings.component.css', styleUrls: ['./basic.settings.component.css',
'./../_abstract/abstract.settings.component.css'], './../_abstract/abstract.settings.component.css'],
@ -33,7 +33,7 @@ export class BasicSettingsComponent extends SettingsComponent<BasicConfigDTO> {
public async save(): Promise<boolean> { public async save(): Promise<boolean> {
const val = await super.save(); const val = await super.save();
if (val == true) { if (val === true) {
this.notification.info('Restart the server to apply the new settings'); this.notification.info('Restart the server to apply the new settings');
} }

View File

@ -1,4 +1,4 @@
import {Component} from '@angular/core'; import {Component, OnInit} from '@angular/core';
import {AuthenticationService} from '../../model/network/authentication.service'; import {AuthenticationService} from '../../model/network/authentication.service';
import {DataBaseConfig, DatabaseType} from '../../../../common/config/private/IPrivateConfig'; import {DataBaseConfig, DatabaseType} from '../../../../common/config/private/IPrivateConfig';
import {Utils} from '../../../../common/Utils'; import {Utils} from '../../../../common/Utils';
@ -9,13 +9,13 @@ import {DatabaseSettingsService} from './database.settings.service';
import {I18n} from '@ngx-translate/i18n-polyfill'; import {I18n} from '@ngx-translate/i18n-polyfill';
@Component({ @Component({
selector: 'settings-database', selector: 'app-settings-database',
templateUrl: './database.settings.component.html', templateUrl: './database.settings.component.html',
styleUrls: ['./database.settings.component.css', styleUrls: ['./database.settings.component.css',
'./../_abstract/abstract.settings.component.css'], './../_abstract/abstract.settings.component.css'],
providers: [DatabaseSettingsService], providers: [DatabaseSettingsService],
}) })
export class DatabaseSettingsComponent extends SettingsComponent<DataBaseConfig> { export class DatabaseSettingsComponent extends SettingsComponent<DataBaseConfig> implements OnInit {
public types: Array<any> = []; public types: Array<any> = [];
public DatabaseType: any; public DatabaseType: any;

View File

@ -12,7 +12,7 @@ import {Utils} from '../../../../common/Utils';
import {I18n} from '@ngx-translate/i18n-polyfill'; import {I18n} from '@ngx-translate/i18n-polyfill';
@Component({ @Component({
selector: 'settings-indexing', selector: 'app-settings-indexing',
templateUrl: './indexing.settings.component.html', templateUrl: './indexing.settings.component.html',
styleUrls: ['./indexing.settings.component.css', styleUrls: ['./indexing.settings.component.css',
'./../_abstract/abstract.settings.component.css'], './../_abstract/abstract.settings.component.css'],
@ -47,7 +47,6 @@ export class IndexingSettingsComponent extends SettingsComponent<IndexingConfig,
this.subscription.timer.unsubscribe(); this.subscription.timer.unsubscribe();
this.subscription.timer = null; this.subscription.timer = null;
} }
}; };
constructor(_authService: AuthenticationService, constructor(_authService: AuthenticationService,

View File

@ -9,7 +9,7 @@ import {I18n} from '@ngx-translate/i18n-polyfill';
@Component({ @Component({
selector: 'settings-map', selector: 'app-settings-map',
templateUrl: './map.settings.component.html', templateUrl: './map.settings.component.html',
styleUrls: ['./map.settings.component.css', styleUrls: ['./map.settings.component.css',
'./../_abstract/abstract.settings.component.css'], './../_abstract/abstract.settings.component.css'],

View File

@ -8,7 +8,7 @@ import {OtherConfigDTO} from '../../../../common/entities/settings/OtherConfigDT
import {I18n} from '@ngx-translate/i18n-polyfill'; import {I18n} from '@ngx-translate/i18n-polyfill';
@Component({ @Component({
selector: 'settings-other', selector: 'app-settings-other',
templateUrl: './other.settings.component.html', templateUrl: './other.settings.component.html',
styleUrls: ['./other.settings.component.css', styleUrls: ['./other.settings.component.css',
'./../_abstract/abstract.settings.component.css'], './../_abstract/abstract.settings.component.css'],
@ -36,7 +36,7 @@ export class OtherSettingsComponent extends SettingsComponent<OtherConfigDTO> im
public async save(): Promise<boolean> { public async save(): Promise<boolean> {
const val = await super.save(); const val = await super.save();
if (val == true) { if (val === true) {
this.notification.info(this.i18n('Restart the server to apply the new settings'), this.i18n('Info')); this.notification.info(this.i18n('Restart the server to apply the new settings'), this.i18n('Info'));
} }

View File

@ -8,7 +8,7 @@ import {SearchSettingsService} from './search.settings.service';
import {I18n} from '@ngx-translate/i18n-polyfill'; import {I18n} from '@ngx-translate/i18n-polyfill';
@Component({ @Component({
selector: 'settings-search', selector: 'app-settings-search',
templateUrl: './search.settings.component.html', templateUrl: './search.settings.component.html',
styleUrls: ['./search.settings.component.css', styleUrls: ['./search.settings.component.css',
'./../_abstract/abstract.settings.component.css'], './../_abstract/abstract.settings.component.css'],

View File

@ -13,7 +13,7 @@ export class SearchSettingsService extends AbstractSettingsService<ClientConfig.
} }
public isSupported(): boolean { public isSupported(): boolean {
return this._settingsService.settings.value.Server.database.type != DatabaseType.memory; return this._settingsService.settings.value.Server.database.type !== DatabaseType.memory;
} }
public updateSettings(settings: ClientConfig.SearchConfig): Promise<void> { public updateSettings(settings: ClientConfig.SearchConfig): Promise<void> {

View File

@ -8,7 +8,7 @@ import {ShareSettingsService} from './share.settings.service';
import {I18n} from '@ngx-translate/i18n-polyfill'; import {I18n} from '@ngx-translate/i18n-polyfill';
@Component({ @Component({
selector: 'settings-share', selector: 'app-settings-share',
templateUrl: './share.settings.component.html', templateUrl: './share.settings.component.html',
styleUrls: ['./share.settings.component.css', styleUrls: ['./share.settings.component.css',
'./../_abstract/abstract.settings.component.css'], './../_abstract/abstract.settings.component.css'],

View File

@ -15,7 +15,7 @@ export class ShareSettingsService extends AbstractSettingsService<ClientConfig.S
public isSupported(): boolean { public isSupported(): boolean {
return this._settingsService.settings.value.Server.database.type != DatabaseType.memory; return this._settingsService.settings.value.Server.database.type !== DatabaseType.memory;
} }
public updateSettings(settings: ClientConfig.SharingConfig): Promise<void> { public updateSettings(settings: ClientConfig.SharingConfig): Promise<void> {

View File

@ -1,4 +1,4 @@
import {Component} from '@angular/core'; import {Component, OnInit} from '@angular/core';
import {SettingsComponent} from '../_abstract/abstract.settings.component'; import {SettingsComponent} from '../_abstract/abstract.settings.component';
import {AuthenticationService} from '../../model/network/authentication.service'; import {AuthenticationService} from '../../model/network/authentication.service';
import {NavigationService} from '../../model/navigation.service'; import {NavigationService} from '../../model/navigation.service';
@ -10,13 +10,15 @@ import {Utils} from '../../../../common/Utils';
import {I18n} from '@ngx-translate/i18n-polyfill'; import {I18n} from '@ngx-translate/i18n-polyfill';
@Component({ @Component({
selector: 'settings-thumbnail', selector: 'app-settings-thumbnail',
templateUrl: './thumbanil.settings.component.html', templateUrl: './thumbanil.settings.component.html',
styleUrls: ['./thumbanil.settings.component.css', styleUrls: ['./thumbanil.settings.component.css',
'./../_abstract/abstract.settings.component.css'], './../_abstract/abstract.settings.component.css'],
providers: [ThumbnailSettingsService], providers: [ThumbnailSettingsService],
}) })
export class ThumbnailSettingsComponent extends SettingsComponent<{ server: ThumbnailConfig, client: ClientConfig.ThumbnailConfig }> { export class ThumbnailSettingsComponent
extends SettingsComponent<{ server: ThumbnailConfig, client: ClientConfig.ThumbnailConfig }>
implements OnInit {
types: Array<any> = []; types: Array<any> = [];
ThumbnailProcessingLib: any; ThumbnailProcessingLib: any;
@ -38,14 +40,16 @@ export class ThumbnailSettingsComponent extends SettingsComponent<{ server: Thum
set ThumbnailSizes(value: string) { set ThumbnailSizes(value: string) {
value = value.replace(new RegExp(',', 'g'), ';'); value = value.replace(new RegExp(',', 'g'), ';');
value = value.replace(new RegExp(' ', 'g'), ';'); value = value.replace(new RegExp(' ', 'g'), ';');
this.settings.client.thumbnailSizes = value.split(';').map(s => parseInt(s)).filter(i => !isNaN(i) && i > 0); this.settings.client.thumbnailSizes = value.split(';')
.map(s => parseInt(s, 10))
.filter(i => !isNaN(i) && i > 0);
} }
ngOnInit() { ngOnInit() {
super.ngOnInit(); super.ngOnInit();
this.types = Utils this.types = Utils
.enumToArray(ThumbnailProcessingLib).map((v) => { .enumToArray(ThumbnailProcessingLib).map((v) => {
if (v.value.toLowerCase() == 'sharp') { if (v.value.toLowerCase() === 'sharp') {
v.value += ' ' + this.i18n('(recommended)'); v.value += ' ' + this.i18n('(recommended)');
} }
return v; return v;

View File

@ -10,7 +10,7 @@ import {ErrorCodes, ErrorDTO} from '../../../../common/entities/Error';
import {I18n} from '@ngx-translate/i18n-polyfill'; import {I18n} from '@ngx-translate/i18n-polyfill';
@Component({ @Component({
selector: 'settings-usermanager', selector: 'app-settings-usermanager',
templateUrl: './usermanager.settings.component.html', templateUrl: './usermanager.settings.component.html',
styleUrls: ['./usermanager.settings.component.css', styleUrls: ['./usermanager.settings.component.css',
'./../_abstract/abstract.settings.component.css'], './../_abstract/abstract.settings.component.css'],

View File

@ -1,7 +1,7 @@
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<language class="pull-right"></language> <app-language class="pull-right"></app-language>
</div> </div>
<div class="row title"> <div class="row title">
<h1><img src="assets/icon.png"/>{{title}}</h1> <h1><img src="assets/icon.png"/>{{title}}</h1>

View File

@ -5,7 +5,7 @@ import {Config} from '../../../common/config/public/Config';
import {NavigationService} from '../model/navigation.service'; import {NavigationService} from '../model/navigation.service';
@Component({ @Component({
selector: 'share-login', selector: 'app-share-login',
templateUrl: './share-login.component.html', templateUrl: './share-login.component.html',
styleUrls: ['./share-login.component.css'], styleUrls: ['./share-login.component.css'],
}) })