implementing photo sorting
This commit is contained in:
parent
86402d229f
commit
795c0ebba9
@ -225,12 +225,14 @@ export class AdminMWs {
|
|||||||
Config.Client.enableCache = settings.enableCache;
|
Config.Client.enableCache = settings.enableCache;
|
||||||
Config.Client.enableOnScrollRendering = settings.enableOnScrollRendering;
|
Config.Client.enableOnScrollRendering = settings.enableOnScrollRendering;
|
||||||
Config.Client.enableOnScrollThumbnailPrioritising = settings.enableOnScrollThumbnailPrioritising;
|
Config.Client.enableOnScrollThumbnailPrioritising = settings.enableOnScrollThumbnailPrioritising;
|
||||||
|
Config.Client.defaultPhotoSortingMethod = settings.defaultPhotoSortingMethod;
|
||||||
|
|
||||||
// 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 = Config.original();
|
||||||
original.Client.enableCache = settings.enableCache;
|
original.Client.enableCache = settings.enableCache;
|
||||||
original.Client.enableOnScrollRendering = settings.enableOnScrollRendering;
|
original.Client.enableOnScrollRendering = settings.enableOnScrollRendering;
|
||||||
original.Client.enableOnScrollThumbnailPrioritising = settings.enableOnScrollThumbnailPrioritising;
|
original.Client.enableOnScrollThumbnailPrioritising = settings.enableOnScrollThumbnailPrioritising;
|
||||||
|
original.Client.defaultPhotoSortingMethod = settings.defaultPhotoSortingMethod;
|
||||||
original.Server.enableThreading = settings.enableThreading;
|
original.Server.enableThreading = settings.enableThreading;
|
||||||
original.save();
|
original.save();
|
||||||
await ConfigDiagnostics.runDiagnostics();
|
await ConfigDiagnostics.runDiagnostics();
|
||||||
|
|||||||
@ -38,7 +38,7 @@ export class Worker {
|
|||||||
|
|
||||||
|
|
||||||
export enum WorkerTaskTypes {
|
export enum WorkerTaskTypes {
|
||||||
thumbnail, diskManager
|
thumbnail = 1, diskManager = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface WorkerTask {
|
export interface WorkerTask {
|
||||||
|
|||||||
@ -9,6 +9,9 @@ export class Utils {
|
|||||||
if (typeof filter !== 'object' || filter == null) {
|
if (typeof filter !== 'object' || filter == null) {
|
||||||
return object === filter;
|
return object === filter;
|
||||||
}
|
}
|
||||||
|
if (!object) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
const keys = Object.keys(filter);
|
const keys = Object.keys(filter);
|
||||||
for (let i = 0; i < keys.length; i++) {
|
for (let i = 0; i < keys.length; i++) {
|
||||||
const key = keys[i];
|
const key = keys[i];
|
||||||
|
|||||||
@ -1,17 +1,17 @@
|
|||||||
import {ClientConfig} from '../public/ConfigClass';
|
import {ClientConfig} from '../public/ConfigClass';
|
||||||
|
|
||||||
export enum DatabaseType {
|
export enum DatabaseType {
|
||||||
memory = 0, mysql = 1, sqlite = 2
|
memory = 1, mysql = 2, sqlite = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum LogLevel {
|
export enum LogLevel {
|
||||||
error, warn, info, debug, verbose
|
error = 1, warn = 2, info = 3, debug = 4, verbose = 5
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum ThumbnailProcessingLib {
|
export enum ThumbnailProcessingLib {
|
||||||
Jimp = 0,
|
Jimp = 1,
|
||||||
gm = 1,
|
gm = 2,
|
||||||
sharp = 2
|
sharp = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MySQLConfig {
|
export interface MySQLConfig {
|
||||||
@ -42,7 +42,7 @@ export interface SharingConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export enum ReIndexingSensitivity {
|
export enum ReIndexingSensitivity {
|
||||||
low, medium, high
|
low = 1, medium = 2, high = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IndexingConfig {
|
export interface IndexingConfig {
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import {SortingMethods} from '../../entities/SortingMethods';
|
||||||
|
|
||||||
export module ClientConfig {
|
export module ClientConfig {
|
||||||
export interface SearchConfig {
|
export interface SearchConfig {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
@ -38,6 +40,7 @@ export module ClientConfig {
|
|||||||
publicUrl: string;
|
publicUrl: string;
|
||||||
urlBase: string;
|
urlBase: string;
|
||||||
languages: string[];
|
languages: string[];
|
||||||
|
defaultPhotoSortingMethod: SortingMethods;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -77,7 +80,8 @@ export class PublicConfigClass {
|
|||||||
authenticationRequired: true,
|
authenticationRequired: true,
|
||||||
publicUrl: '',
|
publicUrl: '',
|
||||||
urlBase: '',
|
urlBase: '',
|
||||||
languages: []
|
languages: [],
|
||||||
|
defaultPhotoSortingMethod: SortingMethods.ascDate
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,23 +1,23 @@
|
|||||||
export enum ErrorCodes {
|
export enum ErrorCodes {
|
||||||
NOT_AUTHENTICATED = 0,
|
NOT_AUTHENTICATED = 1,
|
||||||
ALREADY_AUTHENTICATED = 1,
|
ALREADY_AUTHENTICATED = 2,
|
||||||
NOT_AUTHORISED = 2,
|
NOT_AUTHORISED = 3,
|
||||||
PERMISSION_DENIED = 3,
|
PERMISSION_DENIED = 4,
|
||||||
CREDENTIAL_NOT_FOUND = 4,
|
CREDENTIAL_NOT_FOUND = 5,
|
||||||
|
|
||||||
|
|
||||||
USER_CREATION_ERROR = 5,
|
USER_CREATION_ERROR = 6,
|
||||||
|
|
||||||
|
|
||||||
GENERAL_ERROR = 6,
|
GENERAL_ERROR = 7,
|
||||||
THUMBNAIL_GENERATION_ERROR = 7,
|
THUMBNAIL_GENERATION_ERROR = 8,
|
||||||
SERVER_ERROR = 8,
|
SERVER_ERROR = 9,
|
||||||
|
|
||||||
USER_MANAGEMENT_DISABLED = 9,
|
USER_MANAGEMENT_DISABLED = 10,
|
||||||
|
|
||||||
INPUT_ERROR = 10,
|
INPUT_ERROR = 11,
|
||||||
|
|
||||||
SETTINGS_ERROR = 11
|
SETTINGS_ERROR = 12
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ErrorDTO {
|
export class ErrorDTO {
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
export enum NotificationType {
|
export enum NotificationType {
|
||||||
error, warning, info
|
error = 1, warning = 2, info = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface NotificationDTO {
|
export interface NotificationDTO {
|
||||||
|
|||||||
3
common/entities/SortingMethods.ts
Normal file
3
common/entities/SortingMethods.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export enum SortingMethods {
|
||||||
|
ascName = 1, descName = 2, ascDate = 3, descDate = 4
|
||||||
|
}
|
||||||
@ -2,11 +2,11 @@ import {DirectoryDTO} from './DirectoryDTO';
|
|||||||
import {Utils} from '../Utils';
|
import {Utils} from '../Utils';
|
||||||
|
|
||||||
export enum UserRoles {
|
export enum UserRoles {
|
||||||
LimitedGuest = 0,
|
LimitedGuest = 1,
|
||||||
Guest = 1,
|
Guest = 2,
|
||||||
User = 2,
|
User = 3,
|
||||||
Admin = 3,
|
Admin = 4,
|
||||||
Developer = 4,
|
Developer = 5,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,9 @@
|
|||||||
|
import {SortingMethods} from '../SortingMethods';
|
||||||
|
|
||||||
export interface OtherConfigDTO {
|
export interface OtherConfigDTO {
|
||||||
enableCache: boolean;
|
enableCache: boolean;
|
||||||
enableOnScrollRendering: boolean;
|
enableOnScrollRendering: boolean;
|
||||||
enableOnScrollThumbnailPrioritising: boolean;
|
enableOnScrollThumbnailPrioritising: boolean;
|
||||||
enableThreading: boolean;
|
enableThreading: boolean;
|
||||||
|
defaultPhotoSortingMethod: SortingMethods;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -50,7 +50,7 @@
|
|||||||
<app-settings-map #map [hidden]="!map.hasAvailableSettings" [simplifiedMode]="simplifiedMode"></app-settings-map>
|
<app-settings-map #map [hidden]="!map.hasAvailableSettings" [simplifiedMode]="simplifiedMode"></app-settings-map>
|
||||||
<app-settings-other #other [hidden]="!other.hasAvailableSettings"
|
<app-settings-other #other [hidden]="!other.hasAvailableSettings"
|
||||||
[simplifiedMode]="simplifiedMode"></app-settings-other>
|
[simplifiedMode]="simplifiedMode"></app-settings-other>
|
||||||
<app-settings-indexing #other [hidden]="!other.hasAvailableSettings"
|
<app-settings-indexing #indexing [hidden]="!indexing.hasAvailableSettings"
|
||||||
[simplifiedMode]="simplifiedMode"></app-settings-indexing>
|
[simplifiedMode]="simplifiedMode"></app-settings-indexing>
|
||||||
</div>
|
</div>
|
||||||
</app-frame>
|
</app-frame>
|
||||||
|
|||||||
@ -67,6 +67,8 @@ import {IndexingSettingsComponent} from './settings/indexing/indexing.settings.c
|
|||||||
import {LanguageComponent} from './language/language.component';
|
import {LanguageComponent} from './language/language.component';
|
||||||
import {I18n, MISSING_TRANSLATION_STRATEGY} from '@ngx-translate/i18n-polyfill';
|
import {I18n, MISSING_TRANSLATION_STRATEGY} from '@ngx-translate/i18n-polyfill';
|
||||||
import {QueryService} from './model/query.service';
|
import {QueryService} from './model/query.service';
|
||||||
|
import {IconizeSortingMethod} from './pipes/IconizeSortingMethod';
|
||||||
|
import {StringifySortingMethod} from './pipes/StringifySortingMethod';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class GoogleMapsConfig {
|
export class GoogleMapsConfig {
|
||||||
@ -156,7 +158,9 @@ export function translationsFactory(locale: string) {
|
|||||||
BasicSettingsComponent,
|
BasicSettingsComponent,
|
||||||
OtherSettingsComponent,
|
OtherSettingsComponent,
|
||||||
IndexingSettingsComponent,
|
IndexingSettingsComponent,
|
||||||
StringifyRole],
|
StringifyRole,
|
||||||
|
IconizeSortingMethod,
|
||||||
|
StringifySortingMethod],
|
||||||
providers: [
|
providers: [
|
||||||
{provide: UrlSerializer, useClass: CustomUrlSerializer},
|
{provide: UrlSerializer, useClass: CustomUrlSerializer},
|
||||||
{provide: LAZY_MAPS_API_CONFIG, useClass: GoogleMapsConfig},
|
{provide: LAZY_MAPS_API_CONFIG, useClass: GoogleMapsConfig},
|
||||||
|
|||||||
@ -9,11 +9,15 @@ import {SharingDTO} from '../../../common/entities/SharingDTO';
|
|||||||
import {Config} from '../../../common/config/public/Config';
|
import {Config} from '../../../common/config/public/Config';
|
||||||
import {ShareService} from './share.service';
|
import {ShareService} from './share.service';
|
||||||
import {NavigationService} from '../model/navigation.service';
|
import {NavigationService} from '../model/navigation.service';
|
||||||
|
import {SortingMethods} from '../../../common/entities/SortingMethods';
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class GalleryService {
|
export class GalleryService {
|
||||||
|
|
||||||
|
|
||||||
public content: BehaviorSubject<ContentWrapper>;
|
public content: BehaviorSubject<ContentWrapper>;
|
||||||
|
public sorting: BehaviorSubject<SortingMethods>;
|
||||||
private lastDirectory: DirectoryDTO;
|
private lastDirectory: DirectoryDTO;
|
||||||
private searchId: any;
|
private searchId: any;
|
||||||
|
|
||||||
@ -22,12 +26,17 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
lastRequest: { directory: string } = {
|
lastRequest: { directory: string } = {
|
||||||
directory: null
|
directory: null
|
||||||
};
|
};
|
||||||
|
|
||||||
|
setSorting(sorting: SortingMethods): void {
|
||||||
|
this.sorting.next(sorting);
|
||||||
|
}
|
||||||
|
|
||||||
public loadDirectory(directoryName: string): void {
|
public loadDirectory(directoryName: string): void {
|
||||||
const content = new ContentWrapper();
|
const content = new ContentWrapper();
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import {
|
|||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import {PhotoDTO} from '../../../../common/entities/PhotoDTO';
|
import {PhotoDTO} from '../../../../common/entities/PhotoDTO';
|
||||||
import {GridRowBuilder} from './GridRowBuilder';
|
import {GridRowBuilder} from './GridRowBuilder';
|
||||||
import {GalleryLightboxComponent, LightboxStates} from '../lightbox/lightbox.gallery.component';
|
import {GalleryLightboxComponent} from '../lightbox/lightbox.gallery.component';
|
||||||
import {GridPhoto} from './GridPhoto';
|
import {GridPhoto} from './GridPhoto';
|
||||||
import {GalleryPhotoComponent} from './photo/photo.grid.gallery.component';
|
import {GalleryPhotoComponent} from './photo/photo.grid.gallery.component';
|
||||||
import {OverlayService} from '../overlay.service';
|
import {OverlayService} from '../overlay.service';
|
||||||
@ -23,7 +23,8 @@ import {PageHelper} from '../../model/page.helper';
|
|||||||
import {Subscription} from 'rxjs';
|
import {Subscription} from 'rxjs';
|
||||||
import {ActivatedRoute, Params, Router} from '@angular/router';
|
import {ActivatedRoute, Params, Router} from '@angular/router';
|
||||||
import {QueryService} from '../../model/query.service';
|
import {QueryService} from '../../model/query.service';
|
||||||
import {SimpleChanges} from '@angular/core';
|
import {GalleryService} from '../gallery.service';
|
||||||
|
import {SortingMethods} from '../../../../common/entities/SortingMethods';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-gallery-grid',
|
selector: 'app-gallery-grid',
|
||||||
@ -52,18 +53,25 @@ export class GalleryGridComponent implements OnChanges, OnInit, AfterViewInit, O
|
|||||||
private helperTime = null;
|
private helperTime = null;
|
||||||
isAfterViewInit = false;
|
isAfterViewInit = false;
|
||||||
private renderedPhotoIndex = 0;
|
private renderedPhotoIndex = 0;
|
||||||
routeSubscription: Subscription = null;
|
subscriptions: {
|
||||||
|
route: Subscription,
|
||||||
|
sorting: Subscription
|
||||||
|
} = {
|
||||||
|
route: null,
|
||||||
|
sorting: null
|
||||||
|
};
|
||||||
delayedRenderUpToPhoto: string = null;
|
delayedRenderUpToPhoto: string = null;
|
||||||
|
|
||||||
constructor(private overlayService: OverlayService,
|
constructor(private overlayService: OverlayService,
|
||||||
private changeDetector: ChangeDetectorRef,
|
private changeDetector: ChangeDetectorRef,
|
||||||
public queryService: QueryService,
|
public queryService: QueryService,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
|
public galleryService: GalleryService,
|
||||||
private route: ActivatedRoute) {
|
private route: ActivatedRoute) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.routeSubscription = this.route.queryParams.subscribe((params: Params) => {
|
this.subscriptions.route = this.route.queryParams.subscribe((params: Params) => {
|
||||||
if (params[QueryService.PHOTO_PARAM] && params[QueryService.PHOTO_PARAM] !== '') {
|
if (params[QueryService.PHOTO_PARAM] && params[QueryService.PHOTO_PARAM] !== '') {
|
||||||
this.delayedRenderUpToPhoto = params[QueryService.PHOTO_PARAM];
|
this.delayedRenderUpToPhoto = params[QueryService.PHOTO_PARAM];
|
||||||
if (!this.photos || this.photos.length === 0) {
|
if (!this.photos || this.photos.length === 0) {
|
||||||
@ -73,6 +81,11 @@ export class GalleryGridComponent implements OnChanges, OnInit, AfterViewInit, O
|
|||||||
this.renderUpToPhoto(params[QueryService.PHOTO_PARAM]);
|
this.renderUpToPhoto(params[QueryService.PHOTO_PARAM]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this.subscriptions.sorting = this.galleryService.sorting.subscribe(() => {
|
||||||
|
this.clearRenderedPhotos();
|
||||||
|
this.sortPhotos();
|
||||||
|
this.renderPhotos();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges() {
|
ngOnChanges() {
|
||||||
@ -95,6 +108,14 @@ export class GalleryGridComponent implements OnChanges, OnInit, AfterViewInit, O
|
|||||||
if (this.helperTime != null) {
|
if (this.helperTime != null) {
|
||||||
clearTimeout(this.helperTime);
|
clearTimeout(this.helperTime);
|
||||||
}
|
}
|
||||||
|
if (this.subscriptions.route !== null) {
|
||||||
|
this.subscriptions.route.unsubscribe();
|
||||||
|
this.subscriptions.route = null;
|
||||||
|
}
|
||||||
|
if (this.subscriptions.sorting !== null) {
|
||||||
|
this.subscriptions.sorting.unsubscribe();
|
||||||
|
this.subscriptions.sorting = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@HostListener('window:resize')
|
@HostListener('window:resize')
|
||||||
@ -183,10 +204,41 @@ export class GalleryGridComponent implements OnChanges, OnInit, AfterViewInit, O
|
|||||||
}
|
}
|
||||||
|
|
||||||
private sortPhotos() {
|
private sortPhotos() {
|
||||||
// sort photos by date
|
switch (this.galleryService.sorting.value) {
|
||||||
this.photos.sort((a: PhotoDTO, b: PhotoDTO) => {
|
case SortingMethods.ascName:
|
||||||
return a.metadata.creationDate - b.metadata.creationDate;
|
this.photos.sort((a: PhotoDTO, b: PhotoDTO) => {
|
||||||
});
|
if (a.name.toLowerCase() < b.name.toLowerCase()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (a.name.toLowerCase() > b.name.toLowerCase()) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case SortingMethods.descName:
|
||||||
|
this.photos.sort((a: PhotoDTO, b: PhotoDTO) => {
|
||||||
|
if (a.name.toLowerCase() < b.name.toLowerCase()) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (a.name.toLowerCase() > b.name.toLowerCase()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case SortingMethods.ascDate:
|
||||||
|
this.photos.sort((a: PhotoDTO, b: PhotoDTO) => {
|
||||||
|
return a.metadata.creationDate - b.metadata.creationDate;
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case SortingMethods.descDate:
|
||||||
|
this.photos.sort((a: PhotoDTO, b: PhotoDTO) => {
|
||||||
|
return b.metadata.creationDate - a.metadata.creationDate;
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -24,9 +24,9 @@ import {PageHelper} from '../../model/page.helper';
|
|||||||
import {QueryService} from '../../model/query.service';
|
import {QueryService} from '../../model/query.service';
|
||||||
|
|
||||||
export enum LightboxStates {
|
export enum LightboxStates {
|
||||||
Open,
|
Open = 1,
|
||||||
Closing,
|
Closing = 2,
|
||||||
Closed
|
Closed = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
|||||||
@ -0,0 +1,31 @@
|
|||||||
|
.nav-container {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group {
|
||||||
|
position: absolute;
|
||||||
|
right: 1rem;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
ol {
|
||||||
|
padding-right: 130px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu {
|
||||||
|
min-width: 16rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav{
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
.dropdown-toggle::after {
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
<nav aria-label="breadcrumb">
|
<nav class="nav-container" aria-label="breadcrumb">
|
||||||
<ol id="directory-path" class="breadcrumb">
|
<ol id="directory-path" class="breadcrumb">
|
||||||
<li *ngFor="let path of routes" class="breadcrumb-item">
|
<li *ngFor="let path of routes" class="breadcrumb-item">
|
||||||
<a *ngIf="path.route" [routerLink]="['/gallery',path.route]"
|
<a *ngIf="path.route" [routerLink]="['/gallery',path.route]"
|
||||||
@ -6,4 +6,21 @@
|
|||||||
<ng-container *ngIf="!path.route">{{path.name}}</ng-container>
|
<ng-container *ngIf="!path.route">{{path.name}}</ng-container>
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
|
<div class="btn-group" dropdown placement="bottom right">
|
||||||
|
<button id="button-alignment" dropdownToggle type="button"
|
||||||
|
class="btn btn-default dropdown-toggle" aria-controls="dropdown-alignment"
|
||||||
|
[innerHTML]="galleryService.sorting.value| iconizeSorting">
|
||||||
|
</button>
|
||||||
|
<ul id="dropdown-alignment" *dropdownMenu class="dropdown-menu dropdown-menu-right"
|
||||||
|
role="menu" aria-labelledby="button-alignment">
|
||||||
|
<li class="row dropdown-item" role="menuitem"
|
||||||
|
*ngFor="let type of sortingMethodsType"
|
||||||
|
(click)="setSorting(type.key)">
|
||||||
|
<div class="col-3" [outerHTML]="type.key | iconizeSorting"></div>
|
||||||
|
<div class="col-9">{{type.key | stringifySorting}}</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
|||||||
@ -3,12 +3,15 @@ import {DirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
|||||||
import {RouterLink} from '@angular/router';
|
import {RouterLink} from '@angular/router';
|
||||||
import {UserDTO} from '../../../../common/entities/UserDTO';
|
import {UserDTO} from '../../../../common/entities/UserDTO';
|
||||||
import {AuthenticationService} from '../../model/network/authentication.service';
|
import {AuthenticationService} from '../../model/network/authentication.service';
|
||||||
import {ShareService} from '../share.service';
|
|
||||||
import {I18n} from '@ngx-translate/i18n-polyfill';
|
import {I18n} from '@ngx-translate/i18n-polyfill';
|
||||||
import {QueryService} from '../../model/query.service';
|
import {QueryService} from '../../model/query.service';
|
||||||
|
import {GalleryService} from '../gallery.service';
|
||||||
|
import {Utils} from '../../../../common/Utils';
|
||||||
|
import {SortingMethods} from '../../../../common/entities/SortingMethods';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-gallery-navbar',
|
selector: 'app-gallery-navbar',
|
||||||
|
styleUrls: ['./navigator.gallery.component.css'],
|
||||||
templateUrl: './navigator.gallery.component.html',
|
templateUrl: './navigator.gallery.component.html',
|
||||||
providers: [RouterLink],
|
providers: [RouterLink],
|
||||||
})
|
})
|
||||||
@ -16,10 +19,14 @@ export class GalleryNavigatorComponent implements OnChanges {
|
|||||||
@Input() directory: DirectoryDTO;
|
@Input() directory: DirectoryDTO;
|
||||||
|
|
||||||
routes: Array<NavigatorPath> = [];
|
routes: Array<NavigatorPath> = [];
|
||||||
|
SortingMethods = SortingMethods;
|
||||||
|
sortingMethodsType: { key: number; value: string }[] = [];
|
||||||
|
|
||||||
constructor(private _authService: AuthenticationService,
|
constructor(private _authService: AuthenticationService,
|
||||||
public queryService: QueryService,
|
public queryService: QueryService,
|
||||||
|
public galleryService: GalleryService,
|
||||||
private i18n: I18n) {
|
private i18n: I18n) {
|
||||||
|
this.sortingMethodsType = Utils.enumToArray(SortingMethods);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -71,6 +78,10 @@ export class GalleryNavigatorComponent implements OnChanges {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setSorting(sorting: SortingMethods) {
|
||||||
|
this.galleryService.setSorting(sorting);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -127,5 +127,5 @@ export class GalleryShareComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
|
|
||||||
export enum ValidityTypes {
|
export enum ValidityTypes {
|
||||||
Minutes = 0, Hours = 1, Days = 2, Months = 3
|
Minutes = 1, Hours = 2, Days = 3, Months = 4
|
||||||
}
|
}
|
||||||
|
|||||||
20
frontend/app/pipes/IconizeSortingMethod.ts
Normal file
20
frontend/app/pipes/IconizeSortingMethod.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import {Pipe, PipeTransform} from '@angular/core';
|
||||||
|
import {SortingMethods} from '../../../common/entities/SortingMethods';
|
||||||
|
|
||||||
|
|
||||||
|
@Pipe({name: 'iconizeSorting'})
|
||||||
|
export class IconizeSortingMethod implements PipeTransform {
|
||||||
|
transform(method: SortingMethods): string {
|
||||||
|
switch (method) {
|
||||||
|
case SortingMethods.ascName:
|
||||||
|
return '<span class="oi oi-sort-ascending"></span><strong>A</strong>';
|
||||||
|
case SortingMethods.descName:
|
||||||
|
return '<span class="oi oi-sort-descending"></span><strong>A</strong>';
|
||||||
|
case SortingMethods.ascDate:
|
||||||
|
return '<span class="oi oi-sort-ascending"></span>';
|
||||||
|
case SortingMethods.descDate:
|
||||||
|
return '<span class="oi oi-sort-descending"></span>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
24
frontend/app/pipes/StringifySortingMethod.ts
Normal file
24
frontend/app/pipes/StringifySortingMethod.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import {Pipe, PipeTransform} from '@angular/core';
|
||||||
|
import {I18n} from '@ngx-translate/i18n-polyfill';
|
||||||
|
import {SortingMethods} from '../../../common/entities/SortingMethods';
|
||||||
|
|
||||||
|
|
||||||
|
@Pipe({name: 'stringifySorting'})
|
||||||
|
export class StringifySortingMethod implements PipeTransform {
|
||||||
|
constructor(private i18n: I18n) {
|
||||||
|
}
|
||||||
|
|
||||||
|
transform(method: SortingMethods): string {
|
||||||
|
switch (method) {
|
||||||
|
case SortingMethods.ascName:
|
||||||
|
return this.i18n('ascending name');
|
||||||
|
case SortingMethods.descName:
|
||||||
|
return this.i18n('descending name');
|
||||||
|
case SortingMethods.ascDate:
|
||||||
|
return this.i18n('ascending date');
|
||||||
|
case SortingMethods.descDate:
|
||||||
|
return this.i18n('descending date');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -70,7 +70,10 @@ export abstract class SettingsComponent<T, S extends AbstractSettingsService<T>=
|
|||||||
this.getSettings();
|
this.getSettings();
|
||||||
|
|
||||||
this._subscription = this.form.valueChanges.subscribe((data) => {
|
this._subscription = this.form.valueChanges.subscribe((data) => {
|
||||||
this.changed = !Utils.equalsFilter(this.settings, this.original);
|
if (!data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.changed = !Utils.equalsFilter(data, this.original);
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -92,6 +92,18 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="form-group row" [hidden]="simplifiedMode">
|
||||||
|
<label class="col-md-2 control-label" for="defaultPhotoSortingMethod" i18n>Default photo sorting method</label>
|
||||||
|
<div class="col-md-10">
|
||||||
|
<select id="defaultPhotoSortingMethod" class="form-control" [(ngModel)]="settings.defaultPhotoSortingMethod"
|
||||||
|
name="defaultPhotoSortingMethod" required>
|
||||||
|
<option *ngFor="let type of types" [ngValue]="type.key">{{type.key | stringifySorting}}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<button class="btn btn-success float-right"
|
<button class="btn btn-success float-right"
|
||||||
[disabled]="!settingsForm.form.valid || !changed || inProgress"
|
[disabled]="!settingsForm.form.valid || !changed || inProgress"
|
||||||
(click)="save()" i18n>Save
|
(click)="save()" i18n>Save
|
||||||
|
|||||||
@ -6,6 +6,9 @@ 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 {SortingMethods} from '../../../../common/entities/SortingMethods';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-settings-other',
|
selector: 'app-settings-other',
|
||||||
@ -16,6 +19,9 @@ import {I18n} from '@ngx-translate/i18n-polyfill';
|
|||||||
})
|
})
|
||||||
export class OtherSettingsComponent extends SettingsComponent<OtherConfigDTO> implements OnChanges {
|
export class OtherSettingsComponent extends SettingsComponent<OtherConfigDTO> implements OnChanges {
|
||||||
|
|
||||||
|
|
||||||
|
types: { key: number; value: string }[] = [];
|
||||||
|
|
||||||
constructor(_authService: AuthenticationService,
|
constructor(_authService: AuthenticationService,
|
||||||
_navigation: NavigationService,
|
_navigation: NavigationService,
|
||||||
_settingsService: OtherSettingsService,
|
_settingsService: OtherSettingsService,
|
||||||
@ -25,8 +31,11 @@ export class OtherSettingsComponent extends SettingsComponent<OtherConfigDTO> im
|
|||||||
enableThreading: s.Server.enableThreading,
|
enableThreading: s.Server.enableThreading,
|
||||||
enableOnScrollThumbnailPrioritising: s.Client.enableOnScrollThumbnailPrioritising,
|
enableOnScrollThumbnailPrioritising: s.Client.enableOnScrollThumbnailPrioritising,
|
||||||
enableOnScrollRendering: s.Client.enableOnScrollRendering,
|
enableOnScrollRendering: s.Client.enableOnScrollRendering,
|
||||||
enableCache: s.Client.enableCache
|
enableCache: s.Client.enableCache,
|
||||||
|
defaultPhotoSortingMethod: s.Client.defaultPhotoSortingMethod
|
||||||
}));
|
}));
|
||||||
|
this.types = Utils.enumToArray(SortingMethods);
|
||||||
|
this.hasAvailableSettings = !this.simplifiedMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges(): void {
|
ngOnChanges(): void {
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import {Injectable} from '@angular/core';
|
|||||||
import {BehaviorSubject} from 'rxjs';
|
import {BehaviorSubject} from 'rxjs';
|
||||||
import {DatabaseType, IPrivateConfig, ReIndexingSensitivity, ThumbnailProcessingLib} from '../../../common/config/private/IPrivateConfig';
|
import {DatabaseType, IPrivateConfig, ReIndexingSensitivity, ThumbnailProcessingLib} from '../../../common/config/private/IPrivateConfig';
|
||||||
import {NetworkService} from '../model/network/network.service';
|
import {NetworkService} from '../model/network/network.service';
|
||||||
|
import {SortingMethods} from '../../../common/entities/SortingMethods';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SettingsService {
|
export class SettingsService {
|
||||||
@ -39,7 +40,8 @@ export class SettingsService {
|
|||||||
enableOnScrollRendering: true,
|
enableOnScrollRendering: true,
|
||||||
enableOnScrollThumbnailPrioritising: true,
|
enableOnScrollThumbnailPrioritising: true,
|
||||||
authenticationRequired: true,
|
authenticationRequired: true,
|
||||||
languages: []
|
languages: [],
|
||||||
|
defaultPhotoSortingMethod: SortingMethods.ascDate
|
||||||
},
|
},
|
||||||
Server: {
|
Server: {
|
||||||
database: {
|
database: {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user