diff --git a/src/frontend/app/ui/gallery/lightbox/infopanel/info-panel.lightbox.gallery.component.ts b/src/frontend/app/ui/gallery/lightbox/infopanel/info-panel.lightbox.gallery.component.ts
index d628a87c..0e898ec7 100644
--- a/src/frontend/app/ui/gallery/lightbox/infopanel/info-panel.lightbox.gallery.component.ts
+++ b/src/frontend/app/ui/gallery/lightbox/infopanel/info-panel.lightbox.gallery.component.ts
@@ -11,6 +11,7 @@ import {AuthenticationService} from '../../../../model/network/authentication.se
import {LatLngLiteral, marker, Marker, TileLayer, tileLayer} from 'leaflet';
import {ContentService} from '../../content.service';
import {ThemeService} from '../../../../model/theme.service';
+import { ContentLoaderService } from '../../contentLoader.service';
@Component({
selector: 'app-info-panel',
@@ -31,7 +32,7 @@ export class InfoPanelLightboxComponent implements OnInit, OnChanges {
constructor(
public queryService: QueryService,
- public galleryService: ContentService,
+ public contentLoaderService: ContentLoaderService,
public mapService: MapService,
private authService: AuthenticationService,
private themeService: ThemeService
diff --git a/src/frontend/app/ui/gallery/navigator/navigator.gallery.component.html b/src/frontend/app/ui/gallery/navigator/navigator.gallery.component.html
index ff07397d..bfea1046 100644
--- a/src/frontend/app/ui/gallery/navigator/navigator.gallery.component.html
+++ b/src/frontend/app/ui/gallery/navigator/navigator.gallery.component.html
@@ -13,7 +13,7 @@
-
Searching for:
- {{galleryService.content.value?.searchResult?.searchQuery | searchQuery}}
+ {{contentLoaderService.content.value?.searchResult?.searchQuery | searchQuery}}
diff --git a/src/frontend/app/ui/gallery/navigator/navigator.gallery.component.ts b/src/frontend/app/ui/gallery/navigator/navigator.gallery.component.ts
index c795ab71..e8124aae 100644
--- a/src/frontend/app/ui/gallery/navigator/navigator.gallery.component.ts
+++ b/src/frontend/app/ui/gallery/navigator/navigator.gallery.component.ts
@@ -4,7 +4,6 @@ import {DomSanitizer} from '@angular/platform-browser';
import {UserDTOUtils} from '../../../../../common/entities/UserDTO';
import {AuthenticationService} from '../../../model/network/authentication.service';
import {QueryService} from '../../../model/query.service';
-import {ContentService, ContentWrapperWithError, DirectoryContent,} from '../content.service';
import {Utils} from '../../../../../common/Utils';
import {GroupByTypes, GroupingMethod, SortByDirectionalTypes, SortByTypes} from '../../../../../common/entities/SortingMethods';
import {Config} from '../../../../../common/config/public/Config';
@@ -15,6 +14,7 @@ import {GallerySortingService} from './sorting.service';
import {PageHelper} from '../../../model/page.helper';
import {BsDropdownDirective} from 'ngx-bootstrap/dropdown';
import {FilterService} from '../filter/filter.service';
+import {ContentLoaderService, ContentWrapperWithError, DirectoryContent} from '../contentLoader.service';
@Component({
selector: 'app-gallery-navbar',
@@ -47,7 +47,7 @@ export class GalleryNavigatorComponent {
constructor(
public authService: AuthenticationService,
public queryService: QueryService,
- public galleryService: ContentService,
+ public contentLoaderService: ContentLoaderService,
public filterService: FilterService,
public sortingService: GallerySortingService,
private router: Router,
@@ -57,11 +57,11 @@ export class GalleryNavigatorComponent {
// can't group by random
this.groupingByTypes = Utils.enumToArray(GroupByTypes);
this.RootFolderName = $localize`Home`;
- this.wrappedContent = this.galleryService.content;
+ this.wrappedContent = this.contentLoaderService.content;
this.directoryContent = this.wrappedContent.pipe(
map((c) => (c.directory ? c.directory : c.searchResult))
);
- this.routes = this.galleryService.content.pipe(
+ this.routes = this.contentLoaderService.content.pipe(
map((c) => {
this.parentPath = null;
if (!c.directory) {
@@ -124,15 +124,15 @@ export class GalleryNavigatorComponent {
}
get isDirectory(): boolean {
- return !!this.galleryService.content.value.directory;
+ return !!this.contentLoaderService.content.value.directory;
}
get isSearch(): boolean {
- return !!this.galleryService.content.value.searchResult;
+ return !!this.contentLoaderService.content.value.searchResult;
}
get ItemCount(): number {
- const c = this.galleryService.content.value;
+ const c = this.contentLoaderService.content.value;
return c.directory
? c.directory.mediaCount
: c.searchResult
@@ -142,7 +142,7 @@ export class GalleryNavigatorComponent {
isDefaultSortingAndGrouping(): boolean {
return this.sortingService.isDefaultSortingAndGrouping(
- this.galleryService.content.value
+ this.contentLoaderService.content.value
);
}
@@ -193,7 +193,7 @@ export class GalleryNavigatorComponent {
getDownloadZipLink(): string {
- const c = this.galleryService.content.value;
+ const c = this.contentLoaderService.content.value;
if (!c.directory) {
return null;
}
@@ -212,7 +212,7 @@ export class GalleryNavigatorComponent {
}
getDirectoryFlattenSearchQuery(): string {
- const c = this.galleryService.content.value;
+ const c = this.contentLoaderService.content.value;
if (!c.directory) {
return null;
}
diff --git a/src/frontend/app/ui/gallery/navigator/sorting.service.ts b/src/frontend/app/ui/gallery/navigator/sorting.service.ts
index d72f994e..fa1a00ec 100644
--- a/src/frontend/app/ui/gallery/navigator/sorting.service.ts
+++ b/src/frontend/app/ui/gallery/navigator/sorting.service.ts
@@ -4,9 +4,8 @@ import {NetworkService} from '../../../model/network/network.service';
import {GalleryCacheService} from '../cache.gallery.service';
import {BehaviorSubject, Observable} from 'rxjs';
import {Config} from '../../../../../common/config/public/Config';
-import {GroupingMethod, SortByTypes, SortingMethod} from '../../../../../common/entities/SortingMethods';
+import {GroupByTypes, GroupingMethod, SortByTypes, SortingMethod} from '../../../../../common/entities/SortingMethods';
import {PG2ConfMap} from '../../../../../common/PG2ConfMap';
-import {ContentService, DirectoryContent} from '../content.service';
import {PhotoDTO} from '../../../../../common/entities/PhotoDTO';
import {map, switchMap} from 'rxjs/operators';
import {SeededRandomService} from '../../../model/seededRandom.service';
@@ -14,6 +13,8 @@ import {ContentWrapper} from '../../../../../common/entities/ConentWrapper';
import {SubDirectoryDTO} from '../../../../../common/entities/DirectoryDTO';
import {MediaDTO} from '../../../../../common/entities/MediaDTO';
import {FileDTO} from '../../../../../common/entities/FileDTO';
+import {Utils} from '../../../../../common/Utils';
+import {ContentLoaderService, DirectoryContent} from '../contentLoader.service';
@Injectable()
export class GallerySortingService {
@@ -24,7 +25,7 @@ export class GallerySortingService {
constructor(
private networkService: NetworkService,
private galleryCacheService: GalleryCacheService,
- private galleryService: ContentService,
+ private galleryService: ContentLoaderService,
private rndService: SeededRandomService,
private datePipe: DatePipe
) {
@@ -176,6 +177,38 @@ export class GallerySortingService {
return;
}
+ private getGroupByNameFn(grouping: GroupingMethod) {
+ switch (grouping.method) {
+ case SortByTypes.Date:
+ return (m: MediaDTO) => this.datePipe.transform(m.metadata.creationDate, 'longDate', 'UTC');
+
+ case SortByTypes.Name:
+ return (m: MediaDTO) => m.name.at(0).toUpperCase();
+
+ case SortByTypes.Rating:
+ return (m: MediaDTO) => ((m as PhotoDTO).metadata.rating || 0).toString();
+
+ case SortByTypes.FileSize: {
+ const groups = [0.5, 1, 2, 5, 10, 15, 20, 30, 50, 100, 200, 500, 1000]; // MBs
+ return (m: MediaDTO) => {
+ const mbites = ((m as PhotoDTO).metadata.fileSize || 0) / 1024 / 1024;
+ const i = groups.findIndex((s) => s > mbites);
+ if (i == -1) {
+ return '>' + groups[groups.length - 1] + ' MB';
+ } else if (i == 0) {
+ return '<' + groups[0] + ' MB';
+ }
+ return groups[i - 1] + ' - ' + groups[i] + ' MB';
+ };
+ }
+
+ case SortByTypes.PersonCount:
+ return (m: MediaDTO) => ((m as PhotoDTO).metadata.faces || []).length.toString();
+
+ }
+ return (m: MediaDTO) => '';
+ }
+
public applySorting(
directoryContent: Observable
): Observable {
@@ -243,36 +276,10 @@ export class GallerySortingService {
if (dirContent.media) {
const mCopy = dirContent.media;
this.sortMedia(grouping, mCopy);
- let groupFN = (m: MediaDTO) => '';
- switch (grouping.method) {
- case SortByTypes.Date:
- groupFN = (m: MediaDTO) => this.datePipe.transform(m.metadata.creationDate, 'longDate');
- break;
- case SortByTypes.Name:
- groupFN = (m: MediaDTO) => m.name.at(0).toUpperCase();
- break;
- case SortByTypes.Rating:
- groupFN = (m: MediaDTO) => ((m as PhotoDTO).metadata.rating || 0).toString();
- break;
- case SortByTypes.FileSize: {
- const groups = [0.5, 1, 2, 5, 10, 15, 20, 30, 50]; // MBs
- groupFN = (m: MediaDTO) => {
- const mbites = ((m as PhotoDTO).metadata.fileSize || 0) / 1024 / 1024;
- const i = groups.findIndex((s) => s > mbites);
- if (i == -1) {
- return '>' + groups[groups.length - 1] + ' MB';
- } else if (i == 0) {
- return '<' + groups[0] + ' MB';
- }
- return groups[i - 1] + ' - ' + groups[i] + ' MB';
- };
- }
- break;
- case SortByTypes.PersonCount:
- groupFN = (m: MediaDTO) => ((m as PhotoDTO).metadata.faces || []).length.toString();
- break;
- }
+ const groupFN = this.getGroupByNameFn(grouping);
+
c.mediaGroups = [];
+
for (const m of mCopy) {
const k = groupFN(m);
if (c.mediaGroups.length == 0 || c.mediaGroups[c.mediaGroups.length - 1].name != k) {
@@ -280,7 +287,13 @@ export class GallerySortingService {
}
c.mediaGroups[c.mediaGroups.length - 1].media.push(m);
}
- c.mediaGroups;
+ }
+
+ if (grouping.method === GroupByTypes.Date) {
+ // We do not need the youngest as we group by day. All photos are from the same day
+ c.mediaGroups.forEach(g => {
+ g.date = Utils.makeUTCMidnight(new Date(g.media?.[0]?.metadata?.creationDate));
+ });
}
// sort groups
@@ -300,6 +313,7 @@ export class GallerySortingService {
export interface MediaGroup {
name: string;
+ date?: Date; // used for blog. It allows to chop off blog to smaller pieces
media: MediaDTO[];
}
diff --git a/src/frontend/app/ui/gallery/random-query-builder/random-query-builder.gallery.component.ts b/src/frontend/app/ui/gallery/random-query-builder/random-query-builder.gallery.component.ts
index e6a99add..753c3515 100644
--- a/src/frontend/app/ui/gallery/random-query-builder/random-query-builder.gallery.component.ts
+++ b/src/frontend/app/ui/gallery/random-query-builder/random-query-builder.gallery.component.ts
@@ -15,6 +15,7 @@ import {
import { ActivatedRoute, Params } from '@angular/router';
import { QueryParams } from '../../../../../common/QueryParams';
import { SearchQueryParserService } from '../search/search-query-parser.service';
+import {ContentLoaderService} from '../contentLoader.service';
@Component({
selector: 'app-gallery-random-query-builder',
@@ -36,7 +37,7 @@ export class RandomQueryBuilderGalleryComponent implements OnInit, OnDestroy {
private readonly subscription: Subscription = null;
constructor(
- public galleryService: ContentService,
+ public contentLoaderService: ContentLoaderService,
private notification: NotificationService,
private searchQueryParserService: SearchQueryParserService,
private route: ActivatedRoute,
@@ -65,7 +66,7 @@ export class RandomQueryBuilderGalleryComponent implements OnInit, OnDestroy {
}
ngOnInit(): void {
- this.contentSubscription = this.galleryService.content.subscribe(
+ this.contentSubscription = this.contentLoaderService.content.subscribe(
(content: ContentWrapper) => {
this.enabled = !!content.directory;
if (!this.enabled) {
diff --git a/src/frontend/app/ui/gallery/share/share.gallery.component.ts b/src/frontend/app/ui/gallery/share/share.gallery.component.ts
index 89f874ed..374f213c 100644
--- a/src/frontend/app/ui/gallery/share/share.gallery.component.ts
+++ b/src/frontend/app/ui/gallery/share/share.gallery.component.ts
@@ -12,6 +12,7 @@ import {Subscription} from 'rxjs';
import {UserRoles} from '../../../../../common/entities/UserDTO';
import {AuthenticationService} from '../../../model/network/authentication.service';
import {ClipboardService} from 'ngx-clipboard';
+import {ContentLoaderService} from '../contentLoader.service';
@Component({
selector: 'app-gallery-share',
@@ -51,7 +52,7 @@ export class GalleryShareComponent implements OnInit, OnDestroy {
constructor(
public sharingService: ShareService,
- public galleryService: ContentService,
+ public galleryService: ContentLoaderService,
private notification: NotificationService,
private modalService: BsModalService,
public authService: AuthenticationService,