mirror of
https://github.com/xuthus83/pigallery2.git
synced 2025-01-14 14:43:17 +08:00
Implementing grouping selector button
This commit is contained in:
parent
3f35c35a13
commit
434e6aaacd
@ -1,7 +1,7 @@
|
||||
import {ConfigTemplateEntry, DefaultsJobs,} from '../../../../common/entities/job/JobDTO';
|
||||
import {Job} from './Job';
|
||||
import {backendTexts} from '../../../../common/BackendTexts';
|
||||
import {SortingMethods} from '../../../../common/entities/SortingMethods';
|
||||
import {SortingByTypes} from '../../../../common/entities/SortingMethods';
|
||||
import {DatePatternFrequency, DatePatternSearch, SearchQueryTypes} from '../../../../common/entities/SearchQueryDTO';
|
||||
import {ObjectManagers} from '../../ObjectManagers';
|
||||
import {PhotoEntity} from '../../database/enitites/PhotoEntity';
|
||||
@ -30,7 +30,8 @@ export class TopPickSendJob extends Job<{
|
||||
daysLength: 7,
|
||||
frequency: DatePatternFrequency.every_year
|
||||
} as DatePatternSearch,
|
||||
sortBy: [SortingMethods.descRating, SortingMethods.descPersonCount],
|
||||
sortBy: [{method: SortingByTypes.Rating, ascending: false},
|
||||
{method: SortingByTypes.PersonCount, ascending: false}],
|
||||
pick: 5
|
||||
}] as MediaPickDTO[],
|
||||
}, {
|
||||
|
@ -1,23 +1,23 @@
|
||||
import {SortingByTypes, SortingMethod} from './entities/SortingMethods';
|
||||
import {Utils} from './Utils';
|
||||
|
||||
/**
|
||||
* This contains the action of the supported list of *.pg2conf files.
|
||||
* These files are passed down to the client as metaFiles (like photos and directories)
|
||||
*/
|
||||
export const PG2ConfMap = {
|
||||
sorting: {
|
||||
'.order_descending_name.pg2conf': {method: SortingByTypes.Name, ascending: false} as SortingMethod,
|
||||
'.order_ascending_name.pg2conf': {method: SortingByTypes.Name, ascending: true} as SortingMethod,
|
||||
'.order_descending_date.pg2conf': {method: SortingByTypes.Date, ascending: false} as SortingMethod,
|
||||
'.order_ascending_date.pg2conf': {method: SortingByTypes.Date, ascending: true} as SortingMethod,
|
||||
'.order_descending_rating.pg2conf': {method: SortingByTypes.Rating, ascending: false} as SortingMethod,
|
||||
'.order_ascending_rating.pg2conf': {method: SortingByTypes.Rating, ascending: true} as SortingMethod,
|
||||
'.order_random.pg2conf': {method: SortingByTypes.Rating, ascending: null} as SortingMethod,
|
||||
'.order_descending_person_count.pg2conf': {method: SortingByTypes.PersonCount, ascending: false} as SortingMethod,
|
||||
'.order_ascending_person_count.pg2conf': {method: SortingByTypes.PersonCount, ascending: true} as SortingMethod,
|
||||
},
|
||||
export const PG2ConfMap: { sorting: { [key: string]: SortingMethod } } = {
|
||||
sorting: {}
|
||||
};
|
||||
|
||||
Utils.enumToArray(SortingByTypes).forEach(kv => {
|
||||
if (kv.key === SortingByTypes.random) {
|
||||
PG2ConfMap.sorting['.order_random.pg2conf'] = {method: kv.key, ascending: null} as SortingMethod;
|
||||
return;
|
||||
}
|
||||
PG2ConfMap.sorting['.order_descending' + kv.value.toLowerCase() + '.pg2conf'] = {method: kv.key, ascending: false} as SortingMethod;
|
||||
PG2ConfMap.sorting['.order_ascending' + kv.value.toLowerCase() + '.pg2conf'] = {method: kv.key, ascending: true} as SortingMethod;
|
||||
});
|
||||
|
||||
/**
|
||||
* These files are processed on the server side,
|
||||
* do not get passed down to the client or saved to the DB
|
||||
|
@ -944,6 +944,26 @@ export class ClientGalleryConfig {
|
||||
})
|
||||
defaultSearchSortingMethod: ClientSortingConfig = new ClientSortingConfig(SortingByTypes.Date, false);
|
||||
|
||||
@ConfigProperty({
|
||||
type: ClientSortingConfig,
|
||||
tags: {
|
||||
name: $localize`Default grouping`,
|
||||
priority: ConfigPriority.advanced,
|
||||
},
|
||||
description: $localize`Default grouping method for photo and video in a directory results.`
|
||||
})
|
||||
defaultPhotoGroupingMethod: ClientSortingConfig = new ClientSortingConfig(SortingByTypes.Date, true);
|
||||
|
||||
@ConfigProperty({
|
||||
type: ClientSortingConfig,
|
||||
tags: {
|
||||
name: $localize`Default search grouping`,
|
||||
priority: ConfigPriority.advanced,
|
||||
},
|
||||
description: $localize`Default grouping method for photo and video in a search results.`
|
||||
})
|
||||
defaultSearchGroupingMethod: ClientSortingConfig = new ClientSortingConfig(SortingByTypes.Date, false);
|
||||
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Sort directories by date`,
|
||||
|
@ -178,6 +178,7 @@ import {
|
||||
import {SortingMethodIconComponent} from './ui/sorting-method-icon/sorting-method-icon.component';
|
||||
import {SafeHtmlPipe} from './pipes/SafeHTMLPipe';
|
||||
import {DatePipe} from '@angular/common';
|
||||
import {ParseIntPipe} from './pipes/ParseIntPipe';
|
||||
|
||||
@Injectable()
|
||||
export class MyHammerConfig extends HammerGestureConfig {
|
||||
@ -191,7 +192,7 @@ export class MyHammerConfig extends HammerGestureConfig {
|
||||
|
||||
export class CustomUrlSerializer implements UrlSerializer {
|
||||
private defaultUrlSerializer: DefaultUrlSerializer =
|
||||
new DefaultUrlSerializer();
|
||||
new DefaultUrlSerializer();
|
||||
|
||||
parse(url: string): UrlTree {
|
||||
// Encode parentheses
|
||||
@ -202,9 +203,9 @@ export class CustomUrlSerializer implements UrlSerializer {
|
||||
|
||||
serialize(tree: UrlTree): string {
|
||||
return this.defaultUrlSerializer
|
||||
.serialize(tree)
|
||||
.replace(/%28/g, '(')
|
||||
.replace(/%29/g, ')');
|
||||
.serialize(tree)
|
||||
.replace(/%28/g, '(')
|
||||
.replace(/%29/g, ')');
|
||||
}
|
||||
}
|
||||
|
||||
@ -320,6 +321,7 @@ Marker.prototype.options.icon = MarkerFactory.defIcon;
|
||||
StringifySearchType,
|
||||
FileDTOToPathPipe,
|
||||
PhotoFilterPipe,
|
||||
ParseIntPipe,
|
||||
UsersComponent,
|
||||
SharingsListComponent,
|
||||
SortingMethodIconComponent,
|
||||
|
10
src/frontend/app/pipes/ParseIntPipe.ts
Normal file
10
src/frontend/app/pipes/ParseIntPipe.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import {Pipe, PipeTransform} from '@angular/core';
|
||||
|
||||
@Pipe({name: 'parseInt'})
|
||||
export class ParseIntPipe implements PipeTransform {
|
||||
|
||||
transform(num: string): number {
|
||||
return parseInt(num);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import {Pipe, PipeTransform} from '@angular/core';
|
||||
import {ConfigPriority} from '../../../common/config/public/ClientConfig';
|
||||
import {EnumTranslations} from '../ui/EnumTranslations';
|
||||
|
||||
@Pipe({name: 'stringifyEnum'})
|
||||
|
@ -1,7 +1,15 @@
|
||||
<div #gridContainer [style.width]="renderDelayTimer ? containerWidth+'px' : ''">
|
||||
<ng-container *ngIf="mediaToRender?.length > 0">
|
||||
<ng-container *ngFor="let group of mediaToRender">
|
||||
<div *ngIf="group.name" class="mt-4 mb-3"><h6 class="ms-2">{{group.name}}</h6></div>
|
||||
<ng-container *ngIf="group.name">
|
||||
<ng-container [ngSwitch]="sortingService.grouping.value.method">
|
||||
<div *ngSwitchCase="SortingByTypes.Rating" class="mt-4 mb-3"><h6 class="ms-2">
|
||||
<ng-icon *ngFor="let i of [0,1,2,3,4]" [name]="(i < (group.name | parseInt)) ? 'ionStar' : 'ionStarOutline'"></ng-icon>
|
||||
</h6></div>
|
||||
<div *ngSwitchCase="SortingByTypes.PersonCount" class="mt-4 mb-3"><h6 class="ms-2">{{group.name}} <ng-icon class="ms-1" name="ionPeopleOutline"></ng-icon></h6></div>
|
||||
<div *ngSwitchDefault class="mt-4 mb-3"><h6 class="ms-2">{{group.name}}</h6></div>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
<div class="media-grid">
|
||||
<app-gallery-grid-photo
|
||||
*ngFor="let gridPhoto of group.media"
|
||||
|
@ -25,8 +25,8 @@ import {QueryService} from '../../../model/query.service';
|
||||
import {ContentService} from '../content.service';
|
||||
import {MediaDTO, MediaDTOUtils,} from '../../../../../common/entities/MediaDTO';
|
||||
import {QueryParams} from '../../../../../common/QueryParams';
|
||||
import {MediaGroup} from '../navigator/sorting.service';
|
||||
import {SimpleChanges} from '../../../../../../node_modules/@angular/core';
|
||||
import {GallerySortingService, MediaGroup} from '../navigator/sorting.service';
|
||||
import {SortingByTypes} from '../../../../../common/entities/SortingMethods';
|
||||
|
||||
@Component({
|
||||
selector: 'app-gallery-grid',
|
||||
@ -58,6 +58,7 @@ export class GalleryGridComponent
|
||||
private onScrollFired = false;
|
||||
private helperTime: number = null;
|
||||
public renderDelayTimer: number = null; // delays render on resize
|
||||
public readonly SortingByTypes = SortingByTypes;
|
||||
|
||||
constructor(
|
||||
private overlayService: OverlayService,
|
||||
@ -65,13 +66,23 @@ export class GalleryGridComponent
|
||||
public queryService: QueryService,
|
||||
private router: Router,
|
||||
public galleryService: ContentService,
|
||||
public sortingService: GallerySortingService,
|
||||
private route: ActivatedRoute
|
||||
) {
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
console.log(changes);
|
||||
this.onChange();
|
||||
ngOnChanges(): void {
|
||||
if (this.isAfterViewInit === false) {
|
||||
return;
|
||||
}
|
||||
this.updateContainerDimensions();
|
||||
this.mergeNewPhotos();
|
||||
this.helperTime = window.setTimeout((): void => {
|
||||
this.renderPhotos();
|
||||
if (this.delayedRenderUpToPhoto) {
|
||||
this.renderUpToMedia(this.delayedRenderUpToPhoto);
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
@ -92,20 +103,6 @@ export class GalleryGridComponent
|
||||
);
|
||||
}
|
||||
|
||||
onChange = () => {
|
||||
if (this.isAfterViewInit === false) {
|
||||
return;
|
||||
}
|
||||
this.updateContainerDimensions();
|
||||
this.mergeNewPhotos();
|
||||
this.helperTime = window.setTimeout((): void => {
|
||||
this.renderPhotos();
|
||||
if (this.delayedRenderUpToPhoto) {
|
||||
this.renderUpToMedia(this.delayedRenderUpToPhoto);
|
||||
}
|
||||
}, 0);
|
||||
};
|
||||
|
||||
ngOnDestroy(): void {
|
||||
if (this.helperTime != null) {
|
||||
clearTimeout(this.helperTime);
|
||||
@ -170,9 +167,15 @@ export class GalleryGridComponent
|
||||
}
|
||||
|
||||
|
||||
// TODO: This is deprecated,
|
||||
// we do not post update galleries anymore since the preview member in the DriectoryDTO
|
||||
// Merging photos after new sorting and filter was applied
|
||||
private mergeNewPhotos(): void {
|
||||
if (this.mediaToRender.length === 0) {
|
||||
return;
|
||||
}
|
||||
if (this.mediaGroups?.length === 0) {
|
||||
this.clearRenderedPhotos();
|
||||
return;
|
||||
}
|
||||
// merge new data with old one
|
||||
const lastSameIndex = {groups: 0, media: 0};
|
||||
let lastRowId = 0;
|
||||
@ -195,7 +198,7 @@ export class GalleryGridComponent
|
||||
|
||||
// delete last row if the length of the two are not equal
|
||||
if (!diffFound && this.mediaGroups[i].media.length < this.mediaToRender[i].media.length) {
|
||||
lastRowId = this.mediaToRender[i].media[this.mediaToRender[i].media.length].rowId;
|
||||
lastRowId = this.mediaToRender[i].media[this.mediaToRender[i].media.length - 1].rowId;
|
||||
for (let j = this.mediaToRender[i].media.length - 2; j >= 0; --j) {
|
||||
const gridMedia = this.mediaToRender[i].media[j];
|
||||
if (gridMedia.rowId !== lastRowId) {
|
||||
@ -211,9 +214,17 @@ export class GalleryGridComponent
|
||||
this.clearRenderedPhotos();
|
||||
return;
|
||||
}
|
||||
this.mediaToRender.splice(lastSameIndex.groups, this.mediaToRender.length - lastSameIndex.groups);
|
||||
// only delete the whole group if all media is different
|
||||
if (lastSameIndex.media === 0) {
|
||||
this.mediaToRender.splice(lastSameIndex.groups, this.mediaToRender.length - lastSameIndex.groups);
|
||||
return;
|
||||
}
|
||||
this.mediaToRender.splice(lastSameIndex.groups + 1, this.mediaToRender.length - lastSameIndex.groups);
|
||||
|
||||
const media = this.mediaToRender[lastSameIndex.groups].media;
|
||||
media.splice(lastSameIndex.media, media.length - lastSameIndex.media);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -53,3 +53,10 @@ app-gallery-filter {
|
||||
--bs-text-opacity: 1;
|
||||
color: rgba(var(--bs-body-color-rgb), var(--bs-text-opacity)) !important;
|
||||
}
|
||||
|
||||
.grouping-icon{
|
||||
display: inline-block;
|
||||
font-size: xx-small;
|
||||
vertical-align: top;
|
||||
line-height: 1;
|
||||
}
|
||||
|
@ -29,7 +29,7 @@
|
||||
<ng-container *ngIf="config.Gallery.enableDownloadZip && isDirectory && ItemCount > 0">
|
||||
<a [href]="getDownloadZipLink()"
|
||||
class="btn btn-outline-secondary btn-navigator">
|
||||
<ng-icon name="ionDownloadOutline" title="download" i18n-title></ng-icon>
|
||||
<ng-icon name="ionDownloadOutline" title="Download" i18n-title></ng-icon>
|
||||
</a>
|
||||
<div class="divider"> </div>
|
||||
</ng-container>
|
||||
@ -53,23 +53,35 @@
|
||||
</a>
|
||||
<div class="divider"> </div>
|
||||
</ng-container>
|
||||
<div class="btn-group" dropdown #dropdown="bs-dropdown" placement="bottom right">
|
||||
<div class="btn-group" dropdown #dropdown="bs-dropdown" placement="bottom right"
|
||||
[autoClose]="false"
|
||||
title="Sort and group" i18n-title>
|
||||
<button id="button-alignment" dropdownToggle type="button"
|
||||
class="btn dropdown-toggle btn-outline-secondary btn-navigator"
|
||||
[class.btn-secondary]="sortingService.sorting.value !== DefaultSorting"
|
||||
[class.btn-outline-secondary]="sortingService.sorting.value == DefaultSorting"
|
||||
[class.btn-secondary]="!isDefaultSortingAndGrouping()"
|
||||
[class.btn-outline-secondary]="isDefaultSortingAndGrouping()"
|
||||
aria-controls="sorting-dropdown">
|
||||
<ng-icon
|
||||
[name]="sortingService.sorting.value.ascending ? 'ionArrowDownOutline' : 'ionArrowUpOutline'"></ng-icon>
|
||||
<ng-icon *ngIf="sortingService.sorting.value.ascending !== null"
|
||||
[name]="!sortingService.sorting.value.ascending ? 'ionArrowDownOutline' : 'ionArrowUpOutline'"></ng-icon>
|
||||
<app-sorting-method-icon [method]="sortingService.sorting.value.method"></app-sorting-method-icon>
|
||||
<div class="grouping-icon" *ngIf="sortingService.grouping.value.method !== null">
|
||||
<div>
|
||||
<ng-icon
|
||||
[name]="!sortingService.grouping.value.ascending ? 'ionArrowDownOutline' : 'ionArrowUpOutline'"></ng-icon>
|
||||
<app-sorting-method-icon [method]="sortingService.grouping.value.method"></app-sorting-method-icon>
|
||||
</div>
|
||||
<div class="ps-1" i18n>
|
||||
group
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
<div id="sorting-dropdown" *dropdownMenu class="dropdown-menu dropdown-menu-right"
|
||||
role="menu" aria-labelledby="button-alignment">
|
||||
<div class="row flex-nowrap">
|
||||
<div class="col-6 p-1 border-end">
|
||||
<span class="ps-2">Sorting</span>
|
||||
<div class="col p-1 border-end">
|
||||
<h6 class="ps-2">Sorting</h6>
|
||||
<div class="row">
|
||||
<div class="dropdown-item sorting-grouping-item ps-3 pe-3" role="menuitem"
|
||||
<div class="dropdown-item sorting-grouping-item ps-3 pe-3" role="menuitem"
|
||||
[class.active]="sortingService.sorting.value.method == type.key"
|
||||
*ngFor="let type of sortingByTypes"
|
||||
(click)="setSortingBy(type.key)">
|
||||
@ -78,58 +90,69 @@
|
||||
</div>
|
||||
<div class="d-inline-block">{{type.key | stringifySorting}}</div>
|
||||
</div>
|
||||
<hr>
|
||||
|
||||
<div class="dropdown-item sorting-grouping-item ps-3 pe-3" role="menuitem"
|
||||
[class.active]="sortingService.sorting.value.ascending == true"
|
||||
(click)="setSortingAscending(true)">
|
||||
<div class="me-2 d-inline-block">
|
||||
<ng-icon name="">ionArrowUpOutline</ng-icon>
|
||||
<ng-container *ngIf="sortingService.sorting.value.method != SortingByTypes.random">
|
||||
<hr>
|
||||
<div class="dropdown-item sorting-grouping-item ps-3 pe-3" role="menuitem"
|
||||
[class.active]="sortingService.sorting.value.ascending == true"
|
||||
(click)="setSortingAscending(true)">
|
||||
<div class="me-2 d-inline-block">
|
||||
<ng-icon name="ionArrowUpOutline"></ng-icon>
|
||||
</div>
|
||||
<div class="d-inline-block" i18n>ascending</div>
|
||||
</div>
|
||||
<div class="d-inline-block" i18n>ascending</div>
|
||||
</div>
|
||||
|
||||
<div class="dropdown-item sorting-grouping-item ps-3 pe-3" role="menuitem"
|
||||
[class.active]="sortingService.sorting.value.ascending == false"
|
||||
(click)="setSortingAscending(false)">
|
||||
<div class="me-2 d-inline-block">
|
||||
<ng-icon name="ionArrowDownOutline"></ng-icon>
|
||||
<div class="dropdown-item sorting-grouping-item ps-3 pe-3" role="menuitem"
|
||||
[class.active]="sortingService.sorting.value.ascending == false"
|
||||
(click)="setSortingAscending(false)">
|
||||
<div class="me-2 d-inline-block">
|
||||
<ng-icon name="ionArrowDownOutline"></ng-icon>
|
||||
</div>
|
||||
<div class="d-inline-block" i18n>descending</div>
|
||||
</div>
|
||||
<div class="d-inline-block" i18n>descending</div>
|
||||
</div>
|
||||
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 p-1">
|
||||
<span class="ps-2">Grouping</span>
|
||||
<div class="col p-1">
|
||||
<h6 class="ps-2">Grouping</h6>
|
||||
<div class="row">
|
||||
<div class="dropdown-item sorting-grouping-item ps-3 pe-3" role="menuitem"
|
||||
[class.active]="sortingService.grouping.value.method == type.key"
|
||||
*ngFor="let type of sortingByTypes"
|
||||
*ngFor="let type of groupingByTypes"
|
||||
(click)="setGroupingBy(type.key)">
|
||||
<div class="me-2 d-inline-block">
|
||||
<app-sorting-method-icon [method]="type.key"></app-sorting-method-icon>
|
||||
</div>
|
||||
<div class="d-inline-block">{{type.key | stringifySorting}}</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="dropdown-item sorting-grouping-item ps-3 pe-3" role="menuitem"
|
||||
[class.active]="sortingService.grouping.value.method == null"
|
||||
(click)="setGroupingBy(null)">
|
||||
<div class="me-2 d-inline-block">
|
||||
<ng-icon name="ionCloseOutline"></ng-icon>
|
||||
</div>
|
||||
<div class="d-inline-block" i18n>don't group</div>
|
||||
</div>
|
||||
<ng-container *ngIf="sortingService.grouping.value.method !== null">
|
||||
<hr>
|
||||
|
||||
<div class="dropdown-item sorting-grouping-item ps-3 pe-3" role="menuitem"
|
||||
[class.active]="sortingService.grouping.value.ascending == true"
|
||||
(click)="setGroupingAscending(true)">
|
||||
<div class="me-2 d-inline-block">
|
||||
<ng-icon name="ionArrowUpOutline"></ng-icon>
|
||||
<div class="dropdown-item sorting-grouping-item ps-3 pe-3" role="menuitem"
|
||||
[class.active]="sortingService.grouping.value.ascending == true"
|
||||
(click)="setGroupingAscending(true)">
|
||||
<div class="me-2 d-inline-block">
|
||||
<ng-icon name="ionArrowUpOutline"></ng-icon>
|
||||
</div>
|
||||
<div class="d-inline-block" i18n>ascending</div>
|
||||
</div>
|
||||
<div class="d-inline-block" i18n>ascending</div>
|
||||
</div>
|
||||
<div class="dropdown-item sorting-grouping-item ps-3 pe-3" role="menuitem"
|
||||
[class.active]="sortingService.grouping.value.ascending == false"
|
||||
(click)="setGroupingAscending(false)">
|
||||
<div class="me-2 d-inline-block">
|
||||
<ng-icon name="ionArrowDownOutline"></ng-icon>
|
||||
<div class="dropdown-item sorting-grouping-item ps-3 pe-3" role="menuitem"
|
||||
[class.active]="sortingService.grouping.value.ascending == false"
|
||||
(click)="setGroupingAscending(false)">
|
||||
<div class="me-2 d-inline-block">
|
||||
<ng-icon name="ionArrowDownOutline"></ng-icon>
|
||||
</div>
|
||||
<div class="d-inline-block" i18n>descending</div>
|
||||
</div>
|
||||
<div class="d-inline-block" i18n>descending</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -6,7 +6,7 @@ import {AuthenticationService} from '../../../model/network/authentication.servi
|
||||
import {QueryService} from '../../../model/query.service';
|
||||
import {ContentService, ContentWrapperWithError, DirectoryContent,} from '../content.service';
|
||||
import {Utils} from '../../../../../common/Utils';
|
||||
import {SortingByTypes, SortingMethod} from '../../../../../common/entities/SortingMethods';
|
||||
import {SortingByTypes} from '../../../../../common/entities/SortingMethods';
|
||||
import {Config} from '../../../../../common/config/public/Config';
|
||||
import {SearchQueryTypes, TextSearch, TextSearchQueryMatchTypes,} from '../../../../../common/entities/SearchQueryDTO';
|
||||
import {Observable} from 'rxjs';
|
||||
@ -23,8 +23,9 @@ import {FilterService} from '../filter/filter.service';
|
||||
providers: [RouterLink],
|
||||
})
|
||||
export class GalleryNavigatorComponent {
|
||||
public SortingByTypes = SortingByTypes;
|
||||
public sortingByTypes: { key: number; value: string }[] = [];
|
||||
public readonly SortingByTypes = SortingByTypes;
|
||||
public readonly sortingByTypes: { key: number; value: string }[] = [];
|
||||
public readonly groupingByTypes: { key: number; value: string }[] = [];
|
||||
public readonly config = Config;
|
||||
// DefaultSorting = Config.Gallery.defaultPhotoSortingMethod;
|
||||
public readonly SearchQueryTypes = SearchQueryTypes;
|
||||
@ -53,6 +54,8 @@ export class GalleryNavigatorComponent {
|
||||
public sanitizer: DomSanitizer
|
||||
) {
|
||||
this.sortingByTypes = Utils.enumToArray(SortingByTypes);
|
||||
// can't group by random
|
||||
this.groupingByTypes = this.sortingByTypes.filter(s => s.key !== SortingByTypes.random);
|
||||
this.RootFolderName = $localize`Home`;
|
||||
this.wrappedContent = this.galleryService.content;
|
||||
this.directoryContent = this.wrappedContent.pipe(
|
||||
@ -137,22 +140,40 @@ export class GalleryNavigatorComponent {
|
||||
: 0;
|
||||
}
|
||||
|
||||
get DefaultSorting(): SortingMethod {
|
||||
return this.sortingService.getDefaultSorting(
|
||||
isDefaultSortingAndGrouping(): boolean {
|
||||
return this.sortingService.isDefaultSortingAndGrouping(
|
||||
this.galleryService.content.value
|
||||
);
|
||||
}
|
||||
|
||||
setSortingBy(sorting: SortingByTypes): void {
|
||||
const s = {method: sorting, ascending: this.sortingService.sorting.value.ascending};
|
||||
// random does not have a direction
|
||||
if (sorting === SortingByTypes.random) {
|
||||
s.ascending = null;
|
||||
} else if (s.ascending === null) {
|
||||
s.ascending = true;
|
||||
}
|
||||
this.sortingService.setSorting(s);
|
||||
this.sortingService.setGrouping(s);
|
||||
|
||||
// you cannot group by random
|
||||
if (sorting === SortingByTypes.random) {
|
||||
return;
|
||||
}
|
||||
// if grouping is disabled, do not update it
|
||||
if (this.sortingService.grouping.value.method !== null) {
|
||||
this.sortingService.setGrouping(s);
|
||||
}
|
||||
}
|
||||
|
||||
setSortingAscending(asc: boolean) {
|
||||
const s = {method: this.sortingService.sorting.value.method, ascending: asc};
|
||||
this.sortingService.setSorting(s);
|
||||
this.sortingService.setGrouping(s);
|
||||
|
||||
// if grouping is disabled, do not update it
|
||||
if (this.sortingService.grouping.value.method !== null) {
|
||||
this.sortingService.setGrouping(s);
|
||||
}
|
||||
}
|
||||
|
||||
setGroupingBy(grouping: SortingByTypes): void {
|
||||
|
@ -46,6 +46,15 @@ export class GallerySortingService {
|
||||
});
|
||||
}
|
||||
|
||||
isDefaultSortingAndGrouping(cw: ContentWrapper): boolean {
|
||||
const defS = this.getDefaultSorting(cw);
|
||||
const defG = this.getDefaultGrouping(cw);
|
||||
const s = this.sorting.value;
|
||||
const g = this.grouping.value;
|
||||
return s.method === defS.method && s.ascending === defS.ascending &&
|
||||
g.method === defG.method && g.ascending === defG.ascending;
|
||||
}
|
||||
|
||||
getDefaultSorting(cw: ContentWrapper): SortingMethod {
|
||||
if (cw.directory && cw.directory.metaFile) {
|
||||
for (const file in PG2ConfMap.sorting) {
|
||||
@ -60,6 +69,14 @@ export class GallerySortingService {
|
||||
return Config.Gallery.defaultPhotoSortingMethod;
|
||||
}
|
||||
|
||||
|
||||
getDefaultGrouping(cw: ContentWrapper): SortingMethod {
|
||||
if (cw.searchResult) {
|
||||
return Config.Gallery.defaultSearchGroupingMethod;
|
||||
}
|
||||
return Config.Gallery.defaultPhotoGroupingMethod;
|
||||
}
|
||||
|
||||
setSorting(sorting: SortingMethod): void {
|
||||
this.sorting.next(sorting);
|
||||
if (this.galleryService.content.value) {
|
||||
@ -204,7 +221,7 @@ export class GallerySortingService {
|
||||
groupFN = (m: MediaDTO) => this.datePipe.transform(m.metadata.creationDate, 'longDate');
|
||||
break;
|
||||
case SortingByTypes.Name:
|
||||
groupFN = (m: MediaDTO) => m.name.at(0).toLowerCase();
|
||||
groupFN = (m: MediaDTO) => m.name.at(0).toUpperCase();
|
||||
break;
|
||||
case SortingByTypes.Rating:
|
||||
groupFN = (m: MediaDTO) => ((m as PhotoDTO).metadata.rating || 0).toString();
|
||||
|
@ -1,6 +1,6 @@
|
||||
<ng-container [ngSwitch]="method">
|
||||
<ng-container *ngSwitchCase="SortingByTypes.Name">
|
||||
<span>A</span>
|
||||
<ng-icon name="ionTextOutline"></ng-icon>
|
||||
</ng-container>
|
||||
<ng-container *ngSwitchCase="SortingByTypes.Rating">
|
||||
<ng-icon name="ionStarOutline"></ng-icon>
|
||||
|
Loading…
x
Reference in New Issue
Block a user