Skip to content

Commit

Permalink
adding randomized sorting
Browse files Browse the repository at this point in the history
  • Loading branch information
bpatrik committed Jan 27, 2019
1 parent 38a99b1 commit a613373
Show file tree
Hide file tree
Showing 8 changed files with 152 additions and 95 deletions.
2 changes: 1 addition & 1 deletion common/entities/SortingMethods.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export enum SortingMethods {
ascName = 1, descName = 2, ascDate = 3, descDate = 4
ascName = 1, descName = 2, ascDate = 3, descDate = 4, random = 5
}
2 changes: 2 additions & 0 deletions frontend/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ import {FileSizePipe} from './pipes/FileSizePipe';
import {DuplicateService} from './duplicates/duplicates.service';
import {DuplicateComponent} from './duplicates/duplicates.component';
import {DuplicatesPhotoComponent} from './duplicates/photo/photo.duplicates.component';
import {SeededRandomService} from './model/seededRandom.service';


@Injectable()
Expand Down Expand Up @@ -189,6 +190,7 @@ export function translationsFactory(locale: string) {
FullScreenService,
NavigationService,
SettingsService,
SeededRandomService,
OverlayService,
QueryService,
DuplicateService,
Expand Down
105 changes: 61 additions & 44 deletions frontend/app/gallery/gallery.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ import {SearchResultDTO} from '../../../common/entities/SearchResultDTO';
import {ShareService} from './share.service';
import {NavigationService} from '../model/navigation.service';
import {UserRoles} from '../../../common/entities/UserDTO';
import {interval, Subscription, Observable} from 'rxjs';
import {interval, Observable, Subscription} from 'rxjs';
import {ContentWrapper} from '../../../common/entities/ConentWrapper';
import {PageHelper} from '../model/page.helper';
import {SortingMethods} from '../../../common/entities/SortingMethods';
import {PhotoDTO} from '../../../common/entities/PhotoDTO';
import {QueryParams} from '../../../common/QueryParams';
import {SeededRandomService} from '../model/seededRandom.service';

@Component({
selector: 'app-gallery',
Expand All @@ -32,23 +33,24 @@ export class GalleryComponent implements OnInit, OnDestroy {

public directories: DirectoryDTO[] = [];
public isPhotoWithLocation = false;
public countDown: { day: number, hour: number, minute: number, second: number } = null;
public mapEnabled = true;
readonly SearchTypes: typeof SearchTypes;
private $counter: Observable<number>;
private subscription: { [key: string]: Subscription } = {
content: null,
route: null,
timer: null,
sorting: null
};
public countDown: { day: number, hour: number, minute: number, second: number } = null;
public mapEnabled = true;
readonly SearchTypes: typeof SearchTypes;

constructor(public _galleryService: GalleryService,
private _authService: AuthenticationService,
private _router: Router,
private shareService: ShareService,
private _route: ActivatedRoute,
private _navigation: NavigationService) {
private _navigation: NavigationService,
private rndService: SeededRandomService) {
this.mapEnabled = Config.Client.Map.enabled;
this.SearchTypes = SearchTypes;

Expand All @@ -70,6 +72,46 @@ export class GalleryComponent implements OnInit, OnDestroy {
this.countDown.second = t % 60;
}

ngOnDestroy() {
if (this.subscription.content !== null) {
this.subscription.content.unsubscribe();
}
if (this.subscription.route !== null) {
this.subscription.route.unsubscribe();
}
if (this.subscription.timer !== null) {
this.subscription.timer.unsubscribe();
}
if (this.subscription.sorting !== null) {
this.subscription.sorting.unsubscribe();
}
}

async ngOnInit() {
await this.shareService.wait();
if (!this._authService.isAuthenticated() &&
(!this.shareService.isSharing() ||
(this.shareService.isSharing() && Config.Client.Sharing.passwordProtected === true))) {

return this._navigation.toLogin();
}
this.showSearchBar = Config.Client.Search.enabled && this._authService.isAuthorized(UserRoles.Guest);
this.showShare = Config.Client.Sharing.enabled && this._authService.isAuthorized(UserRoles.User);
this.showRandomPhotoBuilder = Config.Client.RandomPhoto.enabled && this._authService.isAuthorized(UserRoles.Guest);
this.subscription.content = this._galleryService.content.subscribe(this.onContentChange);
this.subscription.route = this._route.params.subscribe(this.onRoute);

if (this.shareService.isSharing()) {
this.$counter = interval(1000);
this.subscription.timer = this.$counter.subscribe((x) => this.updateTimer(x));
}

this.subscription.sorting = this._galleryService.sorting.subscribe(() => {
this.sortDirectories();
});

}

private onRoute = async (params: Params) => {
const searchText = params[QueryParams.gallery.searchText];
if (searchText && searchText !== '') {
Expand Down Expand Up @@ -100,21 +142,6 @@ export class GalleryComponent implements OnInit, OnDestroy {

};

ngOnDestroy() {
if (this.subscription.content !== null) {
this.subscription.content.unsubscribe();
}
if (this.subscription.route !== null) {
this.subscription.route.unsubscribe();
}
if (this.subscription.timer !== null) {
this.subscription.timer.unsubscribe();
}
if (this.subscription.sorting !== null) {
this.subscription.sorting.unsubscribe();
}
}

private onContentChange = (content: ContentWrapper) => {
const ascdirSorter = (a: DirectoryDTO, b: DirectoryDTO) => {
return a.name.localeCompare(b.name);
Expand Down Expand Up @@ -169,33 +196,23 @@ export class GalleryComponent implements OnInit, OnDestroy {
return 0;
});
break;
}

}

async ngOnInit() {
await this.shareService.wait();
if (!this._authService.isAuthenticated() &&
(!this.shareService.isSharing() ||
(this.shareService.isSharing() && Config.Client.Sharing.passwordProtected === true))) {

return this._navigation.toLogin();
}
this.showSearchBar = Config.Client.Search.enabled && this._authService.isAuthorized(UserRoles.Guest);
this.showShare = Config.Client.Sharing.enabled && this._authService.isAuthorized(UserRoles.User);
this.showRandomPhotoBuilder = Config.Client.RandomPhoto.enabled && this._authService.isAuthorized(UserRoles.Guest);
this.subscription.content = this._galleryService.content.subscribe(this.onContentChange);
this.subscription.route = this._route.params.subscribe(this.onRoute);
case SortingMethods.random:
this.rndService.setSeed(this.directories.length);
this.directories.sort((a: DirectoryDTO, b: DirectoryDTO) => {
if (a.name.toLowerCase() < b.name.toLowerCase()) {
return 1;
}
if (a.name.toLowerCase() > b.name.toLowerCase()) {
return -1;
}
return 0;
}).sort(() => {
return this.rndService.get() - 0.5;
});
break;

if (this.shareService.isSharing()) {
this.$counter = interval(1000);
this.subscription.timer = this.$counter.subscribe((x) => this.updateTimer(x));
}

this.subscription.sorting = this._galleryService.sorting.subscribe(() => {
this.sortDirectories();
});

}

}
Expand Down
106 changes: 57 additions & 49 deletions frontend/app/gallery/grid/grid.gallery.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import {
Input,
OnChanges,
OnDestroy,
OnInit,
QueryList,
ViewChild,
ViewChildren,
OnInit
ViewChildren
} from '@angular/core';
import {PhotoDTO} from '../../../../common/entities/PhotoDTO';
import {GridRowBuilder} from './GridRowBuilder';
Expand All @@ -27,7 +27,7 @@ import {GalleryService} from '../gallery.service';
import {SortingMethods} from '../../../../common/entities/SortingMethods';
import {MediaDTO} from '../../../../common/entities/MediaDTO';
import {QueryParams} from '../../../../common/QueryParams';
import {Media} from '../Media';
import {SeededRandomService} from '../../model/seededRandom.service';

@Component({
selector: 'app-gallery-grid',
Expand All @@ -38,24 +38,13 @@ export class GalleryGridComponent implements OnChanges, OnInit, AfterViewInit, O

@ViewChild('gridContainer') gridContainer: ElementRef;
@ViewChildren(GalleryPhotoComponent) gridPhotoQL: QueryList<GalleryPhotoComponent>;
private scrollListenerPhotos: GalleryPhotoComponent[] = [];

@Input() media: MediaDTO[];
@Input() lightbox: GalleryLightboxComponent;

photosToRender: Array<GridMedia> = [];
containerWidth = 0;
screenHeight = 0;

public IMAGE_MARGIN = 2;
private TARGET_COL_COUNT = 5;
private MIN_ROW_COUNT = 2;
private MAX_ROW_COUNT = 5;

private onScrollFired = false;
private helperTime: number = null;
isAfterViewInit = false;
private renderedPhotoIndex = 0;
subscriptions: {
route: Subscription,
sorting: Subscription
Expand All @@ -64,13 +53,21 @@ export class GalleryGridComponent implements OnChanges, OnInit, AfterViewInit, O
sorting: null
};
delayedRenderUpToPhoto: string = null;
private scrollListenerPhotos: GalleryPhotoComponent[] = [];
private TARGET_COL_COUNT = 5;
private MIN_ROW_COUNT = 2;
private MAX_ROW_COUNT = 5;
private onScrollFired = false;
private helperTime: number = null;
private renderedPhotoIndex = 0;

constructor(private overlayService: OverlayService,
private changeDetector: ChangeDetectorRef,
public queryService: QueryService,
private router: Router,
public galleryService: GalleryService,
private route: ActivatedRoute) {
private route: ActivatedRoute,
private rndService: SeededRandomService) {
}

ngOnInit() {
Expand Down Expand Up @@ -159,17 +156,6 @@ export class GalleryGridComponent implements OnChanges, OnInit, AfterViewInit, O
this.isAfterViewInit = true;
}


private renderUpToMedia(mediaStringId: string) {
const index = this.media.findIndex(p => this.queryService.getMediaStringId(p) === mediaStringId);
if (index === -1) {
this.router.navigate([], {queryParams: this.queryService.getParams()});
return;
}
while (this.renderedPhotoIndex < index && this.renderARow()) {
}
}

public renderARow(): number {
if (this.renderedPhotoIndex >= this.media.length
|| this.containerWidth === 0) {
Expand Down Expand Up @@ -204,6 +190,37 @@ export class GalleryGridComponent implements OnChanges, OnInit, AfterViewInit, O
return rowHeight;
}

@HostListener('window:scroll')
onScroll() {
if (!this.onScrollFired &&
// should we trigger this at all?
(this.renderedPhotoIndex < this.media.length || this.scrollListenerPhotos.length > 0)) {
window.requestAnimationFrame(() => {
this.renderPhotos();

if (Config.Client.Other.enableOnScrollThumbnailPrioritising === true) {
this.scrollListenerPhotos.forEach((pc: GalleryPhotoComponent) => {
pc.onScroll();
});
this.scrollListenerPhotos = this.scrollListenerPhotos.filter(pc => pc.ScrollListener);
}

this.onScrollFired = false;
});
this.onScrollFired = true;
}
}

private renderUpToMedia(mediaStringId: string) {
const index = this.media.findIndex(p => this.queryService.getMediaStringId(p) === mediaStringId);
if (index === -1) {
this.router.navigate([], {queryParams: this.queryService.getParams()});
return;
}
while (this.renderedPhotoIndex < index && this.renderARow()) {
}
}

private clearRenderedPhotos() {
this.photosToRender = [];
this.renderedPhotoIndex = 0;
Expand Down Expand Up @@ -244,6 +261,20 @@ export class GalleryGridComponent implements OnChanges, OnInit, AfterViewInit, O
return b.metadata.creationDate - a.metadata.creationDate;
});
break;
case SortingMethods.random:
this.rndService.setSeed(this.media.length);
this.media.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;
}).sort(() => {
return this.rndService.get() - 0.5;
});
break;
}


Expand Down Expand Up @@ -281,7 +312,6 @@ export class GalleryGridComponent implements OnChanges, OnInit, AfterViewInit, O

}


/**
* 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
Expand All @@ -294,28 +324,6 @@ export class GalleryGridComponent implements OnChanges, OnInit, AfterViewInit, O
|| (document.body.clientHeight + offset) * 0.85 < window.innerHeight;
}


@HostListener('window:scroll')
onScroll() {
if (!this.onScrollFired &&
// should we trigger this at all?
(this.renderedPhotoIndex < this.media.length || this.scrollListenerPhotos.length > 0)) {
window.requestAnimationFrame(() => {
this.renderPhotos();

if (Config.Client.Other.enableOnScrollThumbnailPrioritising === true) {
this.scrollListenerPhotos.forEach((pc: GalleryPhotoComponent) => {
pc.onScroll();
});
this.scrollListenerPhotos = this.scrollListenerPhotos.filter(pc => pc.ScrollListener);
}

this.onScrollFired = false;
});
this.onScrollFired = true;
}
}

private renderPhotos(numberOfPhotos: number = 0) {
if (this.containerWidth === 0 ||
this.renderedPhotoIndex >= this.media.length ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ ol {
}

.dropdown-menu {
min-width: 16rem;
min-width: 10rem;
}

.row {
Expand Down

0 comments on commit a613373

Please sign in to comment.