mirror of
https://github.com/bpatrik/pigallery2.git
synced 2025-01-12 04:23:09 +02:00
ui directory refactoring
adding thumbnail loader for faces
This commit is contained in:
parent
5eb69746e5
commit
0d3b8823e4
@ -1,6 +1,8 @@
|
||||
import {NextFunction, Request, Response} from 'express';
|
||||
import {ErrorCodes, ErrorDTO} from '../../common/entities/Error';
|
||||
import {ObjectManagers} from '../model/ObjectManagers';
|
||||
import {PersonDTO} from '../../common/entities/PersonDTO';
|
||||
import {PhotoDTO} from '../../common/entities/PhotoDTO';
|
||||
|
||||
|
||||
const LOG_TAG = '[PersonMWs]';
|
||||
@ -9,8 +11,6 @@ export class PersonMWs {
|
||||
|
||||
|
||||
public static async listPersons(req: Request, res: Response, next: NextFunction) {
|
||||
|
||||
|
||||
try {
|
||||
req.resultPipe = await ObjectManagers.getInstance()
|
||||
.PersonManager.getAll();
|
||||
@ -23,6 +23,43 @@ export class PersonMWs {
|
||||
}
|
||||
|
||||
|
||||
public static async addSamplePhotoForAll(req: Request, res: Response, next: NextFunction) {
|
||||
if (!req.resultPipe) {
|
||||
return next();
|
||||
}
|
||||
try {
|
||||
const persons = (req.resultPipe as PersonWithPhoto[]);
|
||||
for (let i = 0; i < persons.length; i++) {
|
||||
persons[i].samplePhoto = await ObjectManagers.getInstance()
|
||||
.PersonManager.getSamplePhoto(persons[i].name);
|
||||
}
|
||||
req.resultPipe = persons;
|
||||
return next();
|
||||
|
||||
} catch (err) {
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, 'Error during listing the directory', err));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static async removeSamplePhotoForAll(req: Request, res: Response, next: NextFunction) {
|
||||
if (!req.resultPipe) {
|
||||
return next();
|
||||
}
|
||||
try {
|
||||
const persons = (req.resultPipe as PersonWithPhoto[]);
|
||||
for (let i = 0; i < persons.length; i++) {
|
||||
delete persons[i].samplePhoto;
|
||||
}
|
||||
req.resultPipe = persons;
|
||||
return next();
|
||||
|
||||
} catch (err) {
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, 'Error during listing the directory', err));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static async getSamplePhoto(req: Request, res: Response, next: NextFunction) {
|
||||
if (!req.params.name) {
|
||||
return next();
|
||||
@ -44,3 +81,8 @@ export class PersonMWs {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export interface PersonWithPhoto extends PersonDTO {
|
||||
samplePhoto: PhotoDTO;
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ import {RendererInput, ThumbnailSourceType, ThumbnailWorker} from '../../model/t
|
||||
import {MediaDTO} from '../../../common/entities/MediaDTO';
|
||||
import {ITaskExecuter, TaskExecuter} from '../../model/threading/TaskExecuter';
|
||||
import {FaceRegion, PhotoDTO} from '../../../common/entities/PhotoDTO';
|
||||
import {PersonWithPhoto} from '../PersonMWs';
|
||||
|
||||
|
||||
export class ThumbnailGeneratorMWs {
|
||||
@ -73,6 +74,39 @@ export class ThumbnailGeneratorMWs {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static addThumbnailInfoForPersons(req: Request, res: Response, next: NextFunction) {
|
||||
if (!req.resultPipe) {
|
||||
return next();
|
||||
}
|
||||
|
||||
try {
|
||||
const size: number = Config.Client.Thumbnail.personThumbnailSize;
|
||||
|
||||
const persons: PersonWithPhoto[] = req.resultPipe;
|
||||
for (let i = 0; i < persons.length; i++) {
|
||||
|
||||
// load parameters
|
||||
const mediaPath = path.join(ProjectPath.ImageFolder,
|
||||
persons[i].samplePhoto.directory.path,
|
||||
persons[i].samplePhoto.directory.name, persons[i].samplePhoto.name);
|
||||
|
||||
// generate thumbnail path
|
||||
const thPath = path.join(ProjectPath.ThumbnailFolder,
|
||||
ThumbnailGeneratorMWs.generatePersonThumbnailName(mediaPath, persons[i].samplePhoto.metadata.faces[0], size));
|
||||
|
||||
persons[i].readyThumbnail = fs.existsSync(thPath);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
return next(new ErrorDTO(ErrorCodes.SERVER_ERROR, 'error during postprocessing result (adding thumbnail info)', error.toString()));
|
||||
|
||||
}
|
||||
|
||||
return next();
|
||||
|
||||
}
|
||||
|
||||
public static async generatePersonThumbnail(req: Request, res: Response, next: NextFunction) {
|
||||
if (!req.resultPipe) {
|
||||
return next();
|
||||
|
@ -18,4 +18,7 @@ export class PersonEntry implements PersonDTO {
|
||||
|
||||
@OneToMany(type => FaceRegionEntry, faceRegion => faceRegion.person)
|
||||
public faces: FaceRegionEntry[];
|
||||
|
||||
|
||||
readyThumbnail: boolean;
|
||||
}
|
||||
|
@ -15,19 +15,28 @@ export class PersonRouter {
|
||||
|
||||
private static addPersons(app: Express) {
|
||||
app.get(['/api/person'],
|
||||
// common part
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.User),
|
||||
VersionMWs.injectGalleryVersion,
|
||||
|
||||
// specific part
|
||||
PersonMWs.listPersons,
|
||||
PersonMWs.addSamplePhotoForAll,
|
||||
ThumbnailGeneratorMWs.addThumbnailInfoForPersons,
|
||||
PersonMWs.removeSamplePhotoForAll,
|
||||
RenderingMWs.renderResult
|
||||
);
|
||||
}
|
||||
|
||||
private static getPersonThumbnail(app: Express) {
|
||||
app.get(['/api/person/:name/thumbnail'],
|
||||
// common part
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.User),
|
||||
VersionMWs.injectGalleryVersion,
|
||||
|
||||
// specific part
|
||||
PersonMWs.getSamplePhoto,
|
||||
ThumbnailGeneratorMWs.generatePersonThumbnail,
|
||||
RenderingMWs.renderFile
|
||||
|
@ -2,5 +2,21 @@ export interface PersonDTO {
|
||||
id: number;
|
||||
name: string;
|
||||
count: number;
|
||||
readyThumbnail: boolean;
|
||||
}
|
||||
|
||||
|
||||
export class Person implements PersonDTO {
|
||||
count: number;
|
||||
id: number;
|
||||
name: string;
|
||||
readyThumbnail: boolean;
|
||||
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
public static getThumbnailUrl(that: PersonDTO): string {
|
||||
return '/api/person/' + that.name + '/thumbnail';
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import {UserDTO} from '../../common/entities/UserDTO';
|
||||
import {Router} from '@angular/router';
|
||||
import {Config} from '../../common/config/public/Config';
|
||||
import {Title} from '@angular/platform-browser';
|
||||
import {ShareService} from './gallery/share.service';
|
||||
import {ShareService} from './ui/gallery/share.service';
|
||||
import 'hammerjs';
|
||||
import {Subscription} from 'rxjs';
|
||||
|
||||
|
@ -4,80 +4,81 @@ import {FormsModule} from '@angular/forms';
|
||||
import {AppComponent} from './app.component';
|
||||
import {appRoutes} from './app.routing';
|
||||
import {UserService} from './model/network/user.service';
|
||||
import {GalleryService} from './gallery/gallery.service';
|
||||
import {GalleryService} from './ui/gallery/gallery.service';
|
||||
import {NetworkService} from './model/network/network.service';
|
||||
import {GalleryCacheService} from './gallery/cache.gallery.service';
|
||||
import {FullScreenService} from './gallery/fullscreen.service';
|
||||
import {GalleryCacheService} from './ui/gallery/cache.gallery.service';
|
||||
import {FullScreenService} from './ui/gallery/fullscreen.service';
|
||||
import {AuthenticationService} from './model/network/authentication.service';
|
||||
import {UserMangerSettingsComponent} from './settings/usermanager/usermanager.settings.component';
|
||||
import {FrameComponent} from './frame/frame.component';
|
||||
import {UserMangerSettingsComponent} from './ui/settings/usermanager/usermanager.settings.component';
|
||||
import {FrameComponent} from './ui/frame/frame.component';
|
||||
import {YagaModule} from '@yaga/leaflet-ng2';
|
||||
import {GalleryLightboxMediaComponent} from './gallery/lightbox/media/media.lightbox.gallery.component';
|
||||
import {GalleryPhotoLoadingComponent} from './gallery/grid/photo/loading/loading.photo.grid.gallery.component';
|
||||
import {GalleryNavigatorComponent} from './gallery/navigator/navigator.gallery.component';
|
||||
import {GallerySearchComponent} from './gallery/search/search.gallery.component';
|
||||
import {GalleryLightboxComponent} from './gallery/lightbox/lightbox.gallery.component';
|
||||
import {GalleryDirectoryComponent} from './gallery/directory/directory.gallery.component';
|
||||
import {GalleryGridComponent} from './gallery/grid/grid.gallery.component';
|
||||
import {GalleryPhotoComponent} from './gallery/grid/photo/photo.grid.gallery.component';
|
||||
import {LoginComponent} from './login/login.component';
|
||||
import {AdminComponent} from './admin/admin.component';
|
||||
import {GalleryComponent} from './gallery/gallery.component';
|
||||
import {GalleryLightboxMediaComponent} from './ui/gallery/lightbox/media/media.lightbox.gallery.component';
|
||||
import {GalleryPhotoLoadingComponent} from './ui/gallery/grid/photo/loading/loading.photo.grid.gallery.component';
|
||||
import {GalleryNavigatorComponent} from './ui/gallery/navigator/navigator.gallery.component';
|
||||
import {GallerySearchComponent} from './ui/gallery/search/search.gallery.component';
|
||||
import {GalleryLightboxComponent} from './ui/gallery/lightbox/lightbox.gallery.component';
|
||||
import {GalleryDirectoryComponent} from './ui/gallery/directories/directory/directory.gallery.component';
|
||||
import {GalleryGridComponent} from './ui/gallery/grid/grid.gallery.component';
|
||||
import {GalleryPhotoComponent} from './ui/gallery/grid/photo/photo.grid.gallery.component';
|
||||
import {LoginComponent} from './ui/login/login.component';
|
||||
import {AdminComponent} from './ui/admin/admin.component';
|
||||
import {GalleryComponent} from './ui/gallery/gallery.component';
|
||||
import {StringifyRole} from './pipes/StringifyRolePipe';
|
||||
import {GalleryMapComponent} from './gallery/map/map.gallery.component';
|
||||
import {GalleryMapLightboxComponent} from './gallery/map/lightbox/lightbox.map.gallery.component';
|
||||
import {ThumbnailManagerService} from './gallery/thumbnailManager.service';
|
||||
import {OverlayService} from './gallery/overlay.service';
|
||||
import {GalleryMapComponent} from './ui/gallery/map/map.gallery.component';
|
||||
import {GalleryMapLightboxComponent} from './ui/gallery/map/lightbox/lightbox.map.gallery.component';
|
||||
import {ThumbnailManagerService} from './ui/gallery/thumbnailManager.service';
|
||||
import {OverlayService} from './ui/gallery/overlay.service';
|
||||
import {SlimLoadingBarModule} from 'ng2-slim-loading-bar';
|
||||
import {GalleryShareComponent} from './gallery/share/share.gallery.component';
|
||||
import {ShareLoginComponent} from './sharelogin/share-login.component';
|
||||
import {ShareService} from './gallery/share.service';
|
||||
import {GalleryShareComponent} from './ui/gallery/share/share.gallery.component';
|
||||
import {ShareLoginComponent} from './ui/sharelogin/share-login.component';
|
||||
import {ShareService} from './ui/gallery/share.service';
|
||||
import {ModalModule} from 'ngx-bootstrap/modal';
|
||||
import {BsDatepickerModule} from 'ngx-bootstrap/datepicker';
|
||||
import {DatabaseSettingsComponent} from './settings/database/database.settings.component';
|
||||
import {DatabaseSettingsComponent} from './ui/settings/database/database.settings.component';
|
||||
import {ToastrModule} from 'ngx-toastr';
|
||||
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
|
||||
import {NotificationService} from './model/notification.service';
|
||||
import {JwBootstrapSwitchNg2Module} from 'jw-bootstrap-switch-ng2';
|
||||
import {ClipboardModule} from 'ngx-clipboard';
|
||||
import {NavigationService} from './model/navigation.service';
|
||||
import {InfoPanelLightboxComponent} from './gallery/lightbox/infopanel/info-panel.lightbox.gallery.component';
|
||||
import {MapSettingsComponent} from './settings/map/map.settings.component';
|
||||
import {InfoPanelLightboxComponent} from './ui/gallery/lightbox/infopanel/info-panel.lightbox.gallery.component';
|
||||
import {MapSettingsComponent} from './ui/settings/map/map.settings.component';
|
||||
import {TooltipModule} from 'ngx-bootstrap/tooltip';
|
||||
import {BsDropdownModule} from 'ngx-bootstrap/dropdown';
|
||||
import {CollapseModule} from 'ngx-bootstrap/collapse';
|
||||
import {PopoverModule} from 'ngx-bootstrap/popover';
|
||||
import {ThumbnailSettingsComponent} from './settings/thumbnail/thumbanil.settings.component';
|
||||
import {SearchSettingsComponent} from './settings/search/search.settings.component';
|
||||
import {SettingsService} from './settings/settings.service';
|
||||
import {ShareSettingsComponent} from './settings/share/share.settings.component';
|
||||
import {BasicSettingsComponent} from './settings/basic/basic.settings.component';
|
||||
import {OtherSettingsComponent} from './settings/other/other.settings.component';
|
||||
import {ThumbnailSettingsComponent} from './ui/settings/thumbnail/thumbanil.settings.component';
|
||||
import {SearchSettingsComponent} from './ui/settings/search/search.settings.component';
|
||||
import {SettingsService} from './ui/settings/settings.service';
|
||||
import {ShareSettingsComponent} from './ui/settings/share/share.settings.component';
|
||||
import {BasicSettingsComponent} from './ui/settings/basic/basic.settings.component';
|
||||
import {OtherSettingsComponent} from './ui/settings/other/other.settings.component';
|
||||
import {HttpClientModule} from '@angular/common/http';
|
||||
import {DefaultUrlSerializer, UrlSerializer, UrlTree} from '@angular/router';
|
||||
import {IndexingSettingsComponent} from './settings/indexing/indexing.settings.component';
|
||||
import {LanguageComponent} from './language/language.component';
|
||||
import {IndexingSettingsComponent} from './ui/settings/indexing/indexing.settings.component';
|
||||
import {LanguageComponent} from './ui/language/language.component';
|
||||
import {I18n} from '@ngx-translate/i18n-polyfill';
|
||||
import {QueryService} from './model/query.service';
|
||||
import {IconizeSortingMethod} from './pipes/IconizeSortingMethod';
|
||||
import {StringifySortingMethod} from './pipes/StringifySortingMethod';
|
||||
import {RandomQueryBuilderGalleryComponent} from './gallery/random-query-builder/random-query-builder.gallery.component';
|
||||
import {RandomPhotoSettingsComponent} from './settings/random-photo/random-photo.settings.component';
|
||||
import {FixOrientationPipe} from './gallery/FixOrientationPipe';
|
||||
import {VideoSettingsComponent} from './settings/video/video.settings.component';
|
||||
import {RandomQueryBuilderGalleryComponent} from './ui/gallery/random-query-builder/random-query-builder.gallery.component';
|
||||
import {RandomPhotoSettingsComponent} from './ui/settings/random-photo/random-photo.settings.component';
|
||||
import {FixOrientationPipe} from './pipes/FixOrientationPipe';
|
||||
import {VideoSettingsComponent} from './ui/settings/video/video.settings.component';
|
||||
import {DurationPipe} from './pipes/DurationPipe';
|
||||
import {MapService} from './gallery/map/map.service';
|
||||
import {MetaFileSettingsComponent} from './settings/metafiles/metafile.settings.component';
|
||||
import {ThumbnailLoaderService} from './gallery/thumbnailLoader.service';
|
||||
import {MapService} from './ui/gallery/map/map.service';
|
||||
import {MetaFileSettingsComponent} from './ui/settings/metafiles/metafile.settings.component';
|
||||
import {ThumbnailLoaderService} from './ui/gallery/thumbnailLoader.service';
|
||||
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 {DuplicateService} from './ui/duplicates/duplicates.service';
|
||||
import {DuplicateComponent} from './ui/duplicates/duplicates.component';
|
||||
import {DuplicatesPhotoComponent} from './ui/duplicates/photo/photo.duplicates.component';
|
||||
import {SeededRandomService} from './model/seededRandom.service';
|
||||
import {FacesComponent} from './faces/faces.component';
|
||||
import {FacesService} from './faces/faces.service';
|
||||
import {FaceComponent} from './faces/face/face.component';
|
||||
import {FacesComponent} from './ui/faces/faces.component';
|
||||
import {FacesService} from './ui/faces/faces.service';
|
||||
import {FaceComponent} from './ui/faces/face/face.component';
|
||||
import {VersionService} from './model/version.service';
|
||||
import { DirectoriesComponent } from './ui/gallery/directories/directories.component';
|
||||
|
||||
|
||||
@Injectable()
|
||||
@ -111,6 +112,11 @@ declare const require: (path: string) => string;
|
||||
|
||||
export function translationsFactory(locale: string) {
|
||||
locale = locale || 'en'; // default to english if no locale
|
||||
|
||||
// default locale, nothing to translate
|
||||
if (locale === 'en') {
|
||||
return '';
|
||||
}
|
||||
return require(`raw-loader!../translate/messages.${locale}.xlf`);
|
||||
}
|
||||
|
||||
@ -179,7 +185,8 @@ export function translationsFactory(locale: string) {
|
||||
StringifySortingMethod,
|
||||
FixOrientationPipe,
|
||||
DurationPipe,
|
||||
FileSizePipe
|
||||
FileSizePipe,
|
||||
DirectoriesComponent
|
||||
],
|
||||
providers: [
|
||||
{provide: UrlSerializer, useClass: CustomUrlSerializer},
|
||||
|
@ -1,12 +1,12 @@
|
||||
import {ModuleWithProviders} from '@angular/core';
|
||||
import {RouterModule, Routes, UrlMatchResult, UrlSegment} from '@angular/router';
|
||||
import {LoginComponent} from './login/login.component';
|
||||
import {GalleryComponent} from './gallery/gallery.component';
|
||||
import {AdminComponent} from './admin/admin.component';
|
||||
import {ShareLoginComponent} from './sharelogin/share-login.component';
|
||||
import {LoginComponent} from './ui/login/login.component';
|
||||
import {GalleryComponent} from './ui/gallery/gallery.component';
|
||||
import {AdminComponent} from './ui/admin/admin.component';
|
||||
import {ShareLoginComponent} from './ui/sharelogin/share-login.component';
|
||||
import {QueryParams} from '../../common/QueryParams';
|
||||
import {DuplicateComponent} from './duplicates/duplicates.component';
|
||||
import {FacesComponent} from './faces/faces.component';
|
||||
import {DuplicateComponent} from './ui/duplicates/duplicates.component';
|
||||
import {FacesComponent} from './ui/faces/faces.component';
|
||||
|
||||
export function galleryMatcherFunction(
|
||||
segments: UrlSegment[]): UrlMatchResult | null {
|
||||
|
@ -1,31 +0,0 @@
|
||||
import {Component, Input} from '@angular/core';
|
||||
import {RouterLink} from '@angular/router';
|
||||
import {PersonDTO} from '../../../../common/entities/PersonDTO';
|
||||
import {SearchTypes} from '../../../../common/entities/AutoCompleteItem';
|
||||
import {DomSanitizer} from '@angular/platform-browser';
|
||||
|
||||
@Component({
|
||||
selector: 'app-face',
|
||||
templateUrl: './face.component.html',
|
||||
styleUrls: ['./face.component.css'],
|
||||
providers: [RouterLink],
|
||||
})
|
||||
export class FaceComponent {
|
||||
@Input() person: PersonDTO;
|
||||
|
||||
SearchTypes = SearchTypes;
|
||||
|
||||
constructor(private _sanitizer: DomSanitizer) {
|
||||
|
||||
}
|
||||
|
||||
getSanitizedThUrl() {
|
||||
return this._sanitizer.bypassSecurityTrustStyle('url(' +
|
||||
encodeURI('/api/person/' + this.person.name + '/thumbnail')
|
||||
.replace(/\(/g, '%28')
|
||||
.replace(/'/g, '%27')
|
||||
.replace(/\)/g, '%29') + ')');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,21 +0,0 @@
|
||||
import {Component} from '@angular/core';
|
||||
import {FacesService} from './faces.service';
|
||||
import {QueryService} from '../model/query.service';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-faces',
|
||||
templateUrl: './faces.component.html',
|
||||
styleUrls: ['./faces.component.css']
|
||||
})
|
||||
export class FacesComponent {
|
||||
|
||||
|
||||
constructor(public facesService: FacesService,
|
||||
public queryService: QueryService) {
|
||||
this.facesService.getPersons().catch(console.error);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,79 +0,0 @@
|
||||
import {Component, ElementRef, Input, OnDestroy, OnInit, ViewChild} from '@angular/core';
|
||||
import {DomSanitizer} from '@angular/platform-browser';
|
||||
import {DirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
import {RouterLink} from '@angular/router';
|
||||
import {Utils} from '../../../../common/Utils';
|
||||
import {Media} from '../Media';
|
||||
import {Thumbnail, ThumbnailManagerService} from '../thumbnailManager.service';
|
||||
import {PageHelper} from '../../model/page.helper';
|
||||
import {QueryService} from '../../model/query.service';
|
||||
import {PhotoDTO} from '../../../../common/entities/PhotoDTO';
|
||||
import {MediaDTO} from '../../../../common/entities/MediaDTO';
|
||||
|
||||
@Component({
|
||||
selector: 'app-gallery-directory',
|
||||
templateUrl: './directory.gallery.component.html',
|
||||
styleUrls: ['./directory.gallery.component.css'],
|
||||
providers: [RouterLink],
|
||||
})
|
||||
export class GalleryDirectoryComponent implements OnInit, OnDestroy {
|
||||
@Input() directory: DirectoryDTO;
|
||||
@ViewChild('dirContainer') container: ElementRef;
|
||||
thumbnail: Thumbnail = null;
|
||||
|
||||
constructor(private thumbnailService: ThumbnailManagerService,
|
||||
private _sanitizer: DomSanitizer,
|
||||
public queryService: QueryService) {
|
||||
|
||||
}
|
||||
|
||||
size: number = null;
|
||||
|
||||
public get SamplePhoto(): MediaDTO {
|
||||
if (this.directory.media.length > 0) {
|
||||
return this.directory.media[0];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
getSanitizedThUrl() {
|
||||
return this._sanitizer.bypassSecurityTrustStyle('url(' +
|
||||
encodeURI(this.thumbnail.Src)
|
||||
.replace(/\(/g, '%28')
|
||||
.replace(/'/g, '%27')
|
||||
.replace(/\)/g, '%29') + ')');
|
||||
}
|
||||
|
||||
// TODO: implement scroll
|
||||
isInView(): boolean {
|
||||
return document.body.scrollTop < this.container.nativeElement.offsetTop + this.container.nativeElement.clientHeight
|
||||
&& document.body.scrollTop + window.innerHeight > this.container.nativeElement.offsetTop;
|
||||
}
|
||||
|
||||
getDirectoryPath() {
|
||||
return Utils.concatUrls(this.directory.path, this.directory.name);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
if (this.thumbnail != null) {
|
||||
this.thumbnail.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (this.directory.media.length > 0) {
|
||||
this.thumbnail = this.thumbnailService.getThumbnail(new Media(this.SamplePhoto, this.calcSize(), this.calcSize()));
|
||||
}
|
||||
}
|
||||
|
||||
calcSize() {
|
||||
if (this.size == null || PageHelper.isScrollYVisible()) {
|
||||
const size = 220 + 5;
|
||||
const containerWidth = this.container.nativeElement.parentElement.parentElement.clientWidth;
|
||||
this.size = containerWidth / Math.round((containerWidth / size));
|
||||
}
|
||||
return Math.floor(this.size - 5);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
|
||||
import {Router} from '@angular/router';
|
||||
import {ShareService} from '../gallery/share.service';
|
||||
import {ShareService} from '../ui/gallery/share.service';
|
||||
|
||||
@Injectable()
|
||||
export class NavigationService {
|
||||
|
@ -6,7 +6,7 @@ import {AuthenticationService} from './authentication.service';
|
||||
import {NetworkService} from './network.service';
|
||||
import {ErrorDTO} from '../../../../common/entities/Error';
|
||||
import {VersionService} from '../version.service';
|
||||
import {ShareService} from '../../gallery/share.service';
|
||||
import {ShareService} from '../../ui/gallery/share.service';
|
||||
|
||||
class MockUserService {
|
||||
public login(credential: LoginCredential): Promise<UserDTO> {
|
||||
|
@ -8,7 +8,7 @@ import {Config} from '../../../../common/config/public/Config';
|
||||
import {NetworkService} from './network.service';
|
||||
import {ErrorCodes, ErrorDTO} from '../../../../common/entities/Error';
|
||||
import {CookieNames} from '../../../../common/CookieNames';
|
||||
import {ShareService} from '../../gallery/share.service';
|
||||
import {ShareService} from '../../ui/gallery/share.service';
|
||||
|
||||
declare module ServerInject {
|
||||
export let user: UserDTO;
|
||||
|
@ -2,7 +2,6 @@ import {Injectable} from '@angular/core';
|
||||
import {HttpClient, HttpResponse} from '@angular/common/http';
|
||||
import {Message} from '../../../../common/entities/Message';
|
||||
import {SlimLoadingBarService} from 'ng2-slim-loading-bar';
|
||||
import 'rxjs/Rx';
|
||||
import {ErrorCodes, ErrorDTO} from '../../../../common/entities/Error';
|
||||
import {Config} from '../../../../common/config/public/Config';
|
||||
import {Utils} from '../../../../common/Utils';
|
||||
|
@ -4,7 +4,7 @@ import {NetworkService} from './network.service';
|
||||
import {UserService} from './user.service';
|
||||
import {LoginCredential} from '../../../../common/entities/LoginCredential';
|
||||
import {SlimLoadingBarService} from 'ng2-slim-loading-bar';
|
||||
import {ShareService} from '../../gallery/share.service';
|
||||
import {ShareService} from '../../ui/gallery/share.service';
|
||||
import {VersionService} from '../version.service';
|
||||
|
||||
class MockShareService {
|
||||
|
@ -3,7 +3,7 @@ import {LoginCredential} from '../../../../common/entities/LoginCredential';
|
||||
import {NetworkService} from './network.service';
|
||||
import {UserDTO} from '../../../../common/entities/UserDTO';
|
||||
import {Config} from '../../../../common/config/public/Config';
|
||||
import {ShareService} from '../../gallery/share.service';
|
||||
import {ShareService} from '../../ui/gallery/share.service';
|
||||
|
||||
@Injectable()
|
||||
export class UserService {
|
||||
|
@ -1,9 +1,9 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {ShareService} from '../gallery/share.service';
|
||||
import {ShareService} from '../ui/gallery/share.service';
|
||||
import {MediaDTO} from '../../../common/entities/MediaDTO';
|
||||
import {QueryParams} from '../../../common/QueryParams';
|
||||
import {Utils} from '../../../common/Utils';
|
||||
import {GalleryService} from '../gallery/gallery.service';
|
||||
import {GalleryService} from '../ui/gallery/gallery.service';
|
||||
import {Config} from '../../../common/config/public/Config';
|
||||
import {DirectoryDTO} from '../../../common/entities/DirectoryDTO';
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {AuthenticationService} from '../model/network/authentication.service';
|
||||
import {UserRoles} from '../../../common/entities/UserDTO';
|
||||
import {NotificationService} from '../model/notification.service';
|
||||
import {NotificationType} from '../../../common/entities/NotificationDTO';
|
||||
import {NavigationService} from '../model/navigation.service';
|
||||
import {AuthenticationService} from '../../model/network/authentication.service';
|
||||
import {UserRoles} from '../../../../common/entities/UserDTO';
|
||||
import {NotificationService} from '../../model/notification.service';
|
||||
import {NotificationType} from '../../../../common/entities/NotificationDTO';
|
||||
import {NavigationService} from '../../model/navigation.service';
|
||||
import {I18n} from '@ngx-translate/i18n-polyfill';
|
||||
|
||||
@Component({
|
@ -1,12 +1,12 @@
|
||||
import {Component, HostListener, OnDestroy} from '@angular/core';
|
||||
import {DuplicateService} from './duplicates.service';
|
||||
import {Utils} from '../../../common/Utils';
|
||||
import {QueryService} from '../model/query.service';
|
||||
import {DuplicatesDTO} from '../../../common/entities/DuplicatesDTO';
|
||||
import {DirectoryDTO} from '../../../common/entities/DirectoryDTO';
|
||||
import {Utils} from '../../../../common/Utils';
|
||||
import {QueryService} from '../../model/query.service';
|
||||
import {DuplicatesDTO} from '../../../../common/entities/DuplicatesDTO';
|
||||
import {DirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
import {Subscription} from 'rxjs';
|
||||
import {Config} from '../../../common/config/public/Config';
|
||||
import {PageHelper} from '../model/page.helper';
|
||||
import {Config} from '../../../../common/config/public/Config';
|
||||
import {PageHelper} from '../../model/page.helper';
|
||||
|
||||
interface GroupedDuplicate {
|
||||
name: string;
|
@ -1,6 +1,6 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {NetworkService} from '../model/network/network.service';
|
||||
import {DuplicatesDTO} from '../../../common/entities/DuplicatesDTO';
|
||||
import {NetworkService} from '../../model/network/network.service';
|
||||
import {DuplicatesDTO} from '../../../../common/entities/DuplicatesDTO';
|
||||
import {BehaviorSubject} from 'rxjs';
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
import {Component, Input, OnDestroy, OnInit} from '@angular/core';
|
||||
import {MediaDTO} from '../../../../common/entities/MediaDTO';
|
||||
import {MediaDTO} from '../../../../../common/entities/MediaDTO';
|
||||
import {Media} from '../../gallery/Media';
|
||||
import {IconThumbnail, Thumbnail, ThumbnailManagerService} from '../../gallery/thumbnailManager.service';
|
||||
import {PhotoDTO} from '../../../../common/entities/PhotoDTO';
|
||||
import {PhotoDTO} from '../../../../../common/entities/PhotoDTO';
|
||||
import {OrientationTypes} from 'ts-exif-parser';
|
||||
import {MediaIcon} from '../../gallery/MediaIcon';
|
||||
|
@ -4,15 +4,20 @@
|
||||
|
||||
|
||||
<div class="photo-container"
|
||||
[style.width.px]="200"
|
||||
[style.height.px]="200">
|
||||
[style.width.px]="size"
|
||||
[style.height.px]="size">
|
||||
<div class="photo"
|
||||
*ngIf="thumbnail && thumbnail.Available"
|
||||
[style.background-image]="getSanitizedThUrl()"></div>
|
||||
|
||||
|
||||
<span *ngIf="!thumbnail || !thumbnail.Available" class="oi oi-person no-image"
|
||||
aria-hidden="true">
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<!--Info box -->
|
||||
<div #info class="info">
|
||||
<div class="info">
|
||||
<div class="person-name">{{person.name}} ({{person.count}})</div>
|
||||
|
||||
</div>
|
46
frontend/app/ui/faces/face/face.component.ts
Normal file
46
frontend/app/ui/faces/face/face.component.ts
Normal file
@ -0,0 +1,46 @@
|
||||
import {Component, Input, OnDestroy, OnInit} from '@angular/core';
|
||||
import {RouterLink} from '@angular/router';
|
||||
import {PersonDTO} from '../../../../../common/entities/PersonDTO';
|
||||
import {SearchTypes} from '../../../../../common/entities/AutoCompleteItem';
|
||||
import {DomSanitizer} from '@angular/platform-browser';
|
||||
import {PersonThumbnail, ThumbnailManagerService} from '../../gallery/thumbnailManager.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-face',
|
||||
templateUrl: './face.component.html',
|
||||
styleUrls: ['./face.component.css'],
|
||||
providers: [RouterLink],
|
||||
})
|
||||
export class FaceComponent implements OnInit, OnDestroy {
|
||||
@Input() person: PersonDTO;
|
||||
@Input() size: number;
|
||||
|
||||
thumbnail: PersonThumbnail = null;
|
||||
SearchTypes = SearchTypes;
|
||||
|
||||
constructor(private thumbnailService: ThumbnailManagerService,
|
||||
private _sanitizer: DomSanitizer) {
|
||||
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.thumbnail = this.thumbnailService.getPersonThumbnail(this.person);
|
||||
|
||||
}
|
||||
|
||||
getSanitizedThUrl() {
|
||||
return this._sanitizer.bypassSecurityTrustStyle('url(' +
|
||||
encodeURI(this.thumbnail.Src)
|
||||
.replace(/\(/g, '%28')
|
||||
.replace(/'/g, '%27')
|
||||
.replace(/\)/g, '%29') + ')');
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
if (this.thumbnail != null) {
|
||||
this.thumbnail.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
<div body class="container-fluid">
|
||||
<app-face *ngFor="let person of facesService.persons.value"
|
||||
[person]="person"></app-face>
|
||||
[person]="person"
|
||||
[size]="size"></app-face>
|
||||
</div>
|
||||
</app-frame>
|
36
frontend/app/ui/faces/faces.component.ts
Normal file
36
frontend/app/ui/faces/faces.component.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import {Component, ElementRef} from '@angular/core';
|
||||
import {FacesService} from './faces.service';
|
||||
import {QueryService} from '../../model/query.service';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-faces',
|
||||
templateUrl: './faces.component.html',
|
||||
styleUrls: ['./faces.component.css']
|
||||
})
|
||||
export class FacesComponent {
|
||||
|
||||
|
||||
size: number;
|
||||
|
||||
constructor(public facesService: FacesService,
|
||||
public queryService: QueryService,
|
||||
private container: ElementRef) {
|
||||
this.facesService.getPersons().catch(console.error);
|
||||
}
|
||||
|
||||
|
||||
ngOnChanges() {
|
||||
this.updateSize();
|
||||
}
|
||||
|
||||
private updateSize() {
|
||||
const size = 220 + 5;
|
||||
const containerWidth = this.container.nativeElement.parentElement.clientWidth;
|
||||
this.size = (containerWidth / Math.round((containerWidth / size))) - 5;
|
||||
console.log(containerWidth, this.size);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {NetworkService} from '../model/network/network.service';
|
||||
import {NetworkService} from '../../model/network/network.service';
|
||||
import {BehaviorSubject} from 'rxjs';
|
||||
import {PersonDTO} from '../../../common/entities/PersonDTO';
|
||||
import {PersonDTO} from '../../../../common/entities/PersonDTO';
|
||||
|
||||
|
||||
@Injectable()
|
@ -1,11 +1,11 @@
|
||||
import {Component, ViewEncapsulation} from '@angular/core';
|
||||
import {RouterLink} from '@angular/router';
|
||||
import {AuthenticationService} from '../model/network/authentication.service';
|
||||
import {UserDTO, UserRoles} from '../../../common/entities/UserDTO';
|
||||
import {Config} from '../../../common/config/public/Config';
|
||||
import {AuthenticationService} from '../../model/network/authentication.service';
|
||||
import {UserDTO, UserRoles} from '../../../../common/entities/UserDTO';
|
||||
import {Config} from '../../../../common/config/public/Config';
|
||||
import {BehaviorSubject} from 'rxjs';
|
||||
import {NotificationService} from '../model/notification.service';
|
||||
import {QueryService} from '../model/query.service';
|
||||
import {NotificationService} from '../../model/notification.service';
|
||||
import {QueryService} from '../../model/query.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-frame',
|
@ -1,7 +1,7 @@
|
||||
import {Utils} from '../../../common/Utils';
|
||||
import {Utils} from '../../../../common/Utils';
|
||||
import {MediaIcon} from './MediaIcon';
|
||||
import {Config} from '../../../common/config/public/Config';
|
||||
import {MediaDTO} from '../../../common/entities/MediaDTO';
|
||||
import {Config} from '../../../../common/config/public/Config';
|
||||
import {MediaDTO} from '../../../../common/entities/MediaDTO';
|
||||
|
||||
export class Media extends MediaIcon {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import {Utils} from '../../../common/Utils';
|
||||
import {Config} from '../../../common/config/public/Config';
|
||||
import {MediaDTO} from '../../../common/entities/MediaDTO';
|
||||
import {Utils} from '../../../../common/Utils';
|
||||
import {Config} from '../../../../common/config/public/Config';
|
||||
import {MediaDTO} from '../../../../common/entities/MediaDTO';
|
||||
|
||||
export class MediaIcon {
|
||||
|
@ -1,12 +1,12 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {DirectoryDTO} from '../../../common/entities/DirectoryDTO';
|
||||
import {Utils} from '../../../common/Utils';
|
||||
import {Config} from '../../../common/config/public/Config';
|
||||
import {AutoCompleteItem, SearchTypes} from '../../../common/entities/AutoCompleteItem';
|
||||
import {SearchResultDTO} from '../../../common/entities/SearchResultDTO';
|
||||
import {MediaDTO} from '../../../common/entities/MediaDTO';
|
||||
import {SortingMethods} from '../../../common/entities/SortingMethods';
|
||||
import {VersionService} from '../model/version.service';
|
||||
import {DirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
import {Utils} from '../../../../common/Utils';
|
||||
import {Config} from '../../../../common/config/public/Config';
|
||||
import {AutoCompleteItem, SearchTypes} from '../../../../common/entities/AutoCompleteItem';
|
||||
import {SearchResultDTO} from '../../../../common/entities/SearchResultDTO';
|
||||
import {MediaDTO} from '../../../../common/entities/MediaDTO';
|
||||
import {SortingMethods} from '../../../../common/entities/SortingMethods';
|
||||
import {VersionService} from '../../model/version.service';
|
||||
|
||||
interface CacheItem<T> {
|
||||
timestamp: number;
|
@ -0,0 +1,4 @@
|
||||
app-gallery-directory {
|
||||
margin: 2px;
|
||||
display: inline-block;
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
<app-gallery-directory *ngFor="let directory of directories"
|
||||
[directory]="directory"
|
||||
[size]="size"></app-gallery-directory>
|
||||
|
28
frontend/app/ui/gallery/directories/directories.component.ts
Normal file
28
frontend/app/ui/gallery/directories/directories.component.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import {Component, ElementRef, Input, OnChanges, OnInit} from '@angular/core';
|
||||
import {DirectoryDTO} from '../../../../../common/entities/DirectoryDTO';
|
||||
|
||||
@Component({
|
||||
selector: 'app-gallery-directories',
|
||||
templateUrl: './directories.component.html',
|
||||
styleUrls: ['./directories.component.css']
|
||||
})
|
||||
export class DirectoriesComponent implements OnChanges {
|
||||
|
||||
@Input() directories: DirectoryDTO[];
|
||||
size: number;
|
||||
|
||||
constructor(private container: ElementRef) {
|
||||
}
|
||||
|
||||
ngOnChanges() {
|
||||
this.updateSize();
|
||||
}
|
||||
|
||||
private updateSize() {
|
||||
const size = 220 + 5;
|
||||
const containerWidth = this.container.nativeElement.parentElement.clientWidth;
|
||||
this.size = (containerWidth / Math.round((containerWidth / size))) - 5;
|
||||
console.log(containerWidth, this.size);
|
||||
}
|
||||
|
||||
}
|
@ -1,13 +1,13 @@
|
||||
<a #dirContainer class="button btn btn-secondary"
|
||||
<a class="button btn btn-secondary"
|
||||
[routerLink]="['/gallery', getDirectoryPath()]"
|
||||
[queryParams]="queryService.getParams()"
|
||||
style="display: inline-block;">
|
||||
|
||||
|
||||
<div class="photo-container"
|
||||
[style.width.px]="calcSize()"
|
||||
[style.height.px]="calcSize()">
|
||||
<div [ngClass]="'photo ' + (SamplePhoto ? 'photo-orientation-'+SamplePhoto.metadata.orientation : '')"
|
||||
[style.width.px]="size"
|
||||
[style.height.px]="size">
|
||||
<div [ngClass]="'photo photo-orientation-'+Orientation"
|
||||
*ngIf="thumbnail && thumbnail.Available"
|
||||
[style.background-image]="getSanitizedThUrl()"></div>
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
</span>
|
||||
</div>
|
||||
<!--Info box -->
|
||||
<div #info class="info">
|
||||
<div class="info">
|
||||
<div class="directory-name">{{directory.name}}</div>
|
||||
|
||||
</div>
|
@ -0,0 +1,84 @@
|
||||
import {Component, Input, OnDestroy, OnInit} from '@angular/core';
|
||||
import {DomSanitizer} from '@angular/platform-browser';
|
||||
import {DirectoryDTO} from '../../../../../../common/entities/DirectoryDTO';
|
||||
import {RouterLink} from '@angular/router';
|
||||
import {Utils} from '../../../../../../common/Utils';
|
||||
import {Media} from '../../Media';
|
||||
import {Thumbnail, ThumbnailManagerService} from '../../thumbnailManager.service';
|
||||
import {QueryService} from '../../../../model/query.service';
|
||||
import {MediaDTO} from '../../../../../../common/entities/MediaDTO';
|
||||
import {PhotoDTO} from '../../../../../../common/entities/PhotoDTO';
|
||||
import {OrientationTypes} from 'ts-exif-parser';
|
||||
|
||||
@Component({
|
||||
selector: 'app-gallery-directory',
|
||||
templateUrl: './directory.gallery.component.html',
|
||||
styleUrls: ['./directory.gallery.component.css'],
|
||||
providers: [RouterLink],
|
||||
})
|
||||
export class GalleryDirectoryComponent implements OnInit, OnDestroy {
|
||||
@Input() directory: DirectoryDTO;
|
||||
@Input() size: number;
|
||||
// @ViewChild('dirContainer') container: ElementRef;
|
||||
thumbnail: Thumbnail = null;
|
||||
|
||||
constructor(private thumbnailService: ThumbnailManagerService,
|
||||
private _sanitizer: DomSanitizer,
|
||||
public queryService: QueryService) {
|
||||
|
||||
}
|
||||
|
||||
public get SamplePhoto(): MediaDTO {
|
||||
if (this.directory.media.length > 0) {
|
||||
return this.directory.media[0];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public get Orientation(): OrientationTypes {
|
||||
return (this.SamplePhoto && (this.SamplePhoto as PhotoDTO).metadata.orientation)
|
||||
|| OrientationTypes.TOP_LEFT;
|
||||
}
|
||||
|
||||
getSanitizedThUrl() {
|
||||
return this._sanitizer.bypassSecurityTrustStyle('url(' +
|
||||
encodeURI(this.thumbnail.Src)
|
||||
.replace(/\(/g, '%28')
|
||||
.replace(/'/g, '%27')
|
||||
.replace(/\)/g, '%29') + ')');
|
||||
}
|
||||
|
||||
// TODO: implement scroll
|
||||
/* isInView(): boolean {
|
||||
return document.body.scrollTop < this.container.nativeElement.offsetTop + this.container.nativeElement.clientHeight
|
||||
&& document.body.scrollTop + window.innerHeight > this.container.nativeElement.offsetTop;
|
||||
}*/
|
||||
|
||||
getDirectoryPath() {
|
||||
return Utils.concatUrls(this.directory.path, this.directory.name);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
if (this.thumbnail != null) {
|
||||
this.thumbnail.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (this.directory.media.length > 0) {
|
||||
this.thumbnail = this.thumbnailService.getThumbnail(new Media(this.SamplePhoto, this.size, this.size));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
calcSize() {
|
||||
if (this.size == null || PageHelper.isScrollYVisible()) {
|
||||
const size = 220 + 5;
|
||||
const containerWidth = this.container.nativeElement.parentElement.parentElement.clientWidth;
|
||||
this.size = containerWidth / Math.round((containerWidth / size));
|
||||
}
|
||||
return Math.floor(this.size - 5);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {Event} from '../../../common/event/Event';
|
||||
import {Event} from '../../../../common/event/Event';
|
||||
|
||||
declare const document: {
|
||||
fullscreenElement: any;
|
@ -11,10 +11,6 @@ app-gallery-map {
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
app-gallery-directory {
|
||||
margin: 2px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
margin-top: 50px;
|
@ -30,10 +30,8 @@
|
||||
<div body class="container-fluid" style="width: 100%; padding:0" *ngIf="_galleryService.content.value.directory">
|
||||
<app-gallery-navbar [directory]="_galleryService.content.value.directory"></app-gallery-navbar>
|
||||
|
||||
<div class="directories">
|
||||
<app-gallery-directory *ngFor="let directory of directories"
|
||||
[directory]="directory"></app-gallery-directory>
|
||||
</div>
|
||||
<app-gallery-directories class="directories" [directories]="directories"></app-gallery-directories>
|
||||
|
||||
<app-gallery-map *ngIf="isPhotoWithLocation && mapEnabled"
|
||||
[photos]="_galleryService.content.value.directory.media"
|
||||
[metaFiles]="_galleryService.content.value.directory.metaFile"></app-gallery-map>
|
||||
@ -52,10 +50,8 @@
|
||||
[photos]="_galleryService.content.value.searchResult.media"
|
||||
[metaFiles]="_galleryService.content.value.searchResult.metaFile"></app-gallery-map>
|
||||
|
||||
<div class="directories">
|
||||
<app-gallery-directory *ngFor="let directory of directories"
|
||||
[directory]="directory"></app-gallery-directory>
|
||||
</div>
|
||||
<app-gallery-directories class="directories" [directories]="directories"></app-gallery-directories>
|
||||
|
||||
<app-gallery-grid [media]="_galleryService.content.value.searchResult.media"
|
||||
[lightbox]="lightbox"></app-gallery-grid>
|
||||
</div>
|
@ -1,22 +1,22 @@
|
||||
import {Component, OnDestroy, OnInit, ViewChild} from '@angular/core';
|
||||
import {AuthenticationService} from '../model/network/authentication.service';
|
||||
import {AuthenticationService} from '../../model/network/authentication.service';
|
||||
import {ActivatedRoute, Params, Router} from '@angular/router';
|
||||
import {GalleryService} from './gallery.service';
|
||||
import {GalleryGridComponent} from './grid/grid.gallery.component';
|
||||
import {SearchTypes} from '../../../common/entities/AutoCompleteItem';
|
||||
import {Config} from '../../../common/config/public/Config';
|
||||
import {DirectoryDTO} from '../../../common/entities/DirectoryDTO';
|
||||
import {SearchResultDTO} from '../../../common/entities/SearchResultDTO';
|
||||
import {SearchTypes} from '../../../../common/entities/AutoCompleteItem';
|
||||
import {Config} from '../../../../common/config/public/Config';
|
||||
import {DirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
import {SearchResultDTO} from '../../../../common/entities/SearchResultDTO';
|
||||
import {ShareService} from './share.service';
|
||||
import {NavigationService} from '../model/navigation.service';
|
||||
import {UserRoles} from '../../../common/entities/UserDTO';
|
||||
import {NavigationService} from '../../model/navigation.service';
|
||||
import {UserRoles} from '../../../../common/entities/UserDTO';
|
||||
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';
|
||||
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',
|
||||
@ -142,10 +142,6 @@ export class GalleryComponent implements OnInit, OnDestroy {
|
||||
};
|
||||
|
||||
private onContentChange = (content: ContentWrapper) => {
|
||||
const ascdirSorter = (a: DirectoryDTO, b: DirectoryDTO) => {
|
||||
return a.name.localeCompare(b.name);
|
||||
};
|
||||
|
||||
const tmp = <DirectoryDTO | SearchResultDTO>(content.searchResult || content.directory || {
|
||||
directories: [],
|
||||
media: []
|
@ -1,16 +1,16 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {NetworkService} from '../model/network/network.service';
|
||||
import {ContentWrapper} from '../../../common/entities/ConentWrapper';
|
||||
import {DirectoryDTO} from '../../../common/entities/DirectoryDTO';
|
||||
import {SearchTypes} from '../../../common/entities/AutoCompleteItem';
|
||||
import {NetworkService} from '../../model/network/network.service';
|
||||
import {ContentWrapper} from '../../../../common/entities/ConentWrapper';
|
||||
import {DirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
import {SearchTypes} from '../../../../common/entities/AutoCompleteItem';
|
||||
import {GalleryCacheService} from './cache.gallery.service';
|
||||
import {BehaviorSubject} from 'rxjs';
|
||||
import {SharingDTO} from '../../../common/entities/SharingDTO';
|
||||
import {Config} from '../../../common/config/public/Config';
|
||||
import {SharingDTO} from '../../../../common/entities/SharingDTO';
|
||||
import {Config} from '../../../../common/config/public/Config';
|
||||
import {ShareService} from './share.service';
|
||||
import {NavigationService} from '../model/navigation.service';
|
||||
import {SortingMethods} from '../../../common/entities/SortingMethods';
|
||||
import {QueryParams} from '../../../common/QueryParams';
|
||||
import {NavigationService} from '../../model/navigation.service';
|
||||
import {SortingMethods} from '../../../../common/entities/SortingMethods';
|
||||
import {QueryParams} from '../../../../common/QueryParams';
|
||||
|
||||
|
||||
@Injectable()
|
@ -1,8 +1,8 @@
|
||||
import {Media} from '../Media';
|
||||
import {MediaDTO} from '../../../../common/entities/MediaDTO';
|
||||
import {MediaDTO} from '../../../../../common/entities/MediaDTO';
|
||||
import {OrientationTypes} from 'ts-exif-parser';
|
||||
import {PhotoDTO} from '../../../../common/entities/PhotoDTO';
|
||||
import {VideoDTO} from '../../../../common/entities/VideoDTO';
|
||||
import {PhotoDTO} from '../../../../../common/entities/PhotoDTO';
|
||||
import {VideoDTO} from '../../../../../common/entities/VideoDTO';
|
||||
|
||||
export class GridMedia extends Media {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {PhotoDTO} from '../../../../common/entities/PhotoDTO';
|
||||
import {MediaDTO} from '../../../../common/entities/MediaDTO';
|
||||
import {PhotoDTO} from '../../../../../common/entities/PhotoDTO';
|
||||
import {MediaDTO} from '../../../../../common/entities/MediaDTO';
|
||||
|
||||
export class GridRowBuilder {
|
||||
|
@ -12,22 +12,22 @@ import {
|
||||
ViewChild,
|
||||
ViewChildren
|
||||
} from '@angular/core';
|
||||
import {PhotoDTO} from '../../../../common/entities/PhotoDTO';
|
||||
import {PhotoDTO} from '../../../../../common/entities/PhotoDTO';
|
||||
import {GridRowBuilder} from './GridRowBuilder';
|
||||
import {GalleryLightboxComponent} from '../lightbox/lightbox.gallery.component';
|
||||
import {GridMedia} from './GridMedia';
|
||||
import {GalleryPhotoComponent} from './photo/photo.grid.gallery.component';
|
||||
import {OverlayService} from '../overlay.service';
|
||||
import {Config} from '../../../../common/config/public/Config';
|
||||
import {PageHelper} from '../../model/page.helper';
|
||||
import {Config} from '../../../../../common/config/public/Config';
|
||||
import {PageHelper} from '../../../model/page.helper';
|
||||
import {Subscription} from 'rxjs';
|
||||
import {ActivatedRoute, Params, Router} from '@angular/router';
|
||||
import {QueryService} from '../../model/query.service';
|
||||
import {QueryService} from '../../../model/query.service';
|
||||
import {GalleryService} from '../gallery.service';
|
||||
import {SortingMethods} from '../../../../common/entities/SortingMethods';
|
||||
import {MediaDTO} from '../../../../common/entities/MediaDTO';
|
||||
import {QueryParams} from '../../../../common/QueryParams';
|
||||
import {SeededRandomService} from '../../model/seededRandom.service';
|
||||
import {SortingMethods} from '../../../../../common/entities/SortingMethods';
|
||||
import {MediaDTO} from '../../../../../common/entities/MediaDTO';
|
||||
import {QueryParams} from '../../../../../common/QueryParams';
|
||||
import {SeededRandomService} from '../../../model/seededRandom.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-gallery-grid',
|
@ -1,12 +1,12 @@
|
||||
import {Component, ElementRef, Input, OnDestroy, OnInit, ViewChild} from '@angular/core';
|
||||
import {Dimension, IRenderable} from '../../../model/IRenderable';
|
||||
import {Dimension, IRenderable} from '../../../../model/IRenderable';
|
||||
import {GridMedia} from '../GridMedia';
|
||||
import {SearchTypes} from '../../../../../common/entities/AutoCompleteItem';
|
||||
import {SearchTypes} from '../../../../../../common/entities/AutoCompleteItem';
|
||||
import {RouterLink} from '@angular/router';
|
||||
import {Thumbnail, ThumbnailManagerService} from '../../thumbnailManager.service';
|
||||
import {Config} from '../../../../../common/config/public/Config';
|
||||
import {PageHelper} from '../../../model/page.helper';
|
||||
import {PhotoDTO, PhotoMetadata} from '../../../../../common/entities/PhotoDTO';
|
||||
import {Config} from '../../../../../../common/config/public/Config';
|
||||
import {PageHelper} from '../../../../model/page.helper';
|
||||
import {PhotoDTO, PhotoMetadata} from '../../../../../../common/entities/PhotoDTO';
|
||||
|
||||
@Component({
|
||||
selector: 'app-gallery-grid-photo',
|
@ -1,10 +1,10 @@
|
||||
import {Component, EventEmitter, Input, Output} from '@angular/core';
|
||||
import {CameraMetadata, PhotoDTO, PositionMetaData} from '../../../../../common/entities/PhotoDTO';
|
||||
import {Config} from '../../../../../common/config/public/Config';
|
||||
import {MediaDTO} from '../../../../../common/entities/MediaDTO';
|
||||
import {VideoDTO, VideoMetadata} from '../../../../../common/entities/VideoDTO';
|
||||
import {Utils} from '../../../../../common/Utils';
|
||||
import {QueryService} from '../../../model/query.service';
|
||||
import {CameraMetadata, PhotoDTO, PositionMetaData} from '../../../../../../common/entities/PhotoDTO';
|
||||
import {Config} from '../../../../../../common/config/public/Config';
|
||||
import {MediaDTO} from '../../../../../../common/entities/MediaDTO';
|
||||
import {VideoDTO, VideoMetadata} from '../../../../../../common/entities/VideoDTO';
|
||||
import {Utils} from '../../../../../../common/Utils';
|
||||
import {QueryService} from '../../../../model/query.service';
|
||||
import {MapService} from '../../map/map.service';
|
||||
|
||||
@Component({
|
@ -9,7 +9,7 @@ import {
|
||||
ViewChild
|
||||
} from '@angular/core';
|
||||
import {GalleryPhotoComponent} from '../grid/photo/photo.grid.gallery.component';
|
||||
import {Dimension} from '../../model/IRenderable';
|
||||
import {Dimension} from '../../../model/IRenderable';
|
||||
import {FullScreenService} from '../fullscreen.service';
|
||||
import {OverlayService} from '../overlay.service';
|
||||
import {animate, AnimationBuilder, AnimationPlayer, style} from '@angular/animations';
|
||||
@ -17,12 +17,12 @@ import {GalleryLightboxMediaComponent} from './media/media.lightbox.gallery.comp
|
||||
import {Observable, Subscription, timer} from 'rxjs';
|
||||
import {filter} from 'rxjs/operators';
|
||||
import {ActivatedRoute, Params, Router} from '@angular/router';
|
||||
import {PageHelper} from '../../model/page.helper';
|
||||
import {QueryService} from '../../model/query.service';
|
||||
import {MediaDTO} from '../../../../common/entities/MediaDTO';
|
||||
import {QueryParams} from '../../../../common/QueryParams';
|
||||
import {PageHelper} from '../../../model/page.helper';
|
||||
import {QueryService} from '../../../model/query.service';
|
||||
import {MediaDTO} from '../../../../../common/entities/MediaDTO';
|
||||
import {QueryParams} from '../../../../../common/QueryParams';
|
||||
import {GalleryService} from '../gallery.service';
|
||||
import {PhotoDTO} from '../../../../common/entities/PhotoDTO';
|
||||
import {PhotoDTO} from '../../../../../common/entities/PhotoDTO';
|
||||
|
||||
export enum LightboxStates {
|
||||
Open = 1,
|
@ -1,7 +1,7 @@
|
||||
import {Component, ElementRef, Input, Output, OnChanges, ViewChild} from '@angular/core';
|
||||
import {GridMedia} from '../../grid/GridMedia';
|
||||
import {FixOrientationPipe} from '../../FixOrientationPipe';
|
||||
import {MediaDTO} from '../../../../../common/entities/MediaDTO';
|
||||
import {FixOrientationPipe} from '../../../../pipes/FixOrientationPipe';
|
||||
import {MediaDTO} from '../../../../../../common/entities/MediaDTO';
|
||||
import {DomSanitizer, SafeStyle} from '@angular/platform-browser';
|
||||
|
||||
@Component({
|
@ -1,20 +1,20 @@
|
||||
import {Component, ElementRef, HostListener, Input, OnChanges, ViewChild, AfterViewInit} from '@angular/core';
|
||||
import {PhotoDTO} from '../../../../../common/entities/PhotoDTO';
|
||||
import {Dimension} from '../../../model/IRenderable';
|
||||
import {PhotoDTO} from '../../../../../../common/entities/PhotoDTO';
|
||||
import {Dimension} from '../../../../model/IRenderable';
|
||||
import {FullScreenService} from '../../fullscreen.service';
|
||||
import {IconThumbnail, Thumbnail, ThumbnailManagerService} from '../../thumbnailManager.service';
|
||||
import {MediaIcon} from '../../MediaIcon';
|
||||
import {Media} from '../../Media';
|
||||
import {PageHelper} from '../../../model/page.helper';
|
||||
import {PageHelper} from '../../../../model/page.helper';
|
||||
import {OrientationTypes} from 'ts-exif-parser';
|
||||
import {MediaDTO} from '../../../../../common/entities/MediaDTO';
|
||||
import {FileDTO} from '../../../../../common/entities/FileDTO';
|
||||
import {Utils} from '../../../../../common/Utils';
|
||||
import {Config} from '../../../../../common/config/public/Config';
|
||||
import {MediaDTO} from '../../../../../../common/entities/MediaDTO';
|
||||
import {FileDTO} from '../../../../../../common/entities/FileDTO';
|
||||
import {Utils} from '../../../../../../common/Utils';
|
||||
import {Config} from '../../../../../../common/config/public/Config';
|
||||
import {MapService} from '../map.service';
|
||||
import {LatLng, Point} from 'leaflet';
|
||||
import {MapComponent} from '@yaga/leaflet-ng2';
|
||||
import {FixOrientationPipe} from '../../FixOrientationPipe';
|
||||
import {FixOrientationPipe} from '../../../../pipes/FixOrientationPipe';
|
||||
|
||||
@Component({
|
||||
selector: 'app-gallery-map-lightbox',
|
@ -1,8 +1,8 @@
|
||||
import {Component, ElementRef, Input, OnChanges, ViewChild, AfterViewInit} from '@angular/core';
|
||||
import {PhotoDTO} from '../../../../common/entities/PhotoDTO';
|
||||
import {Dimension, IRenderable} from '../../model/IRenderable';
|
||||
import {PhotoDTO} from '../../../../../common/entities/PhotoDTO';
|
||||
import {Dimension, IRenderable} from '../../../model/IRenderable';
|
||||
import {GalleryMapLightboxComponent} from './lightbox/lightbox.map.gallery.component';
|
||||
import {FileDTO} from '../../../../common/entities/FileDTO';
|
||||
import {FileDTO} from '../../../../../common/entities/FileDTO';
|
||||
import {MapService} from './map.service';
|
||||
import {MapComponent} from '@yaga/leaflet-ng2';
|
||||
|
@ -1,9 +1,9 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {NetworkService} from '../../model/network/network.service';
|
||||
import {FileDTO} from '../../../../common/entities/FileDTO';
|
||||
import {Utils} from '../../../../common/Utils';
|
||||
import {Config} from '../../../../common/config/public/Config';
|
||||
import {ClientConfig} from '../../../../common/config/public/ConfigClass';
|
||||
import {NetworkService} from '../../../model/network/network.service';
|
||||
import {FileDTO} from '../../../../../common/entities/FileDTO';
|
||||
import {Utils} from '../../../../../common/Utils';
|
||||
import {Config} from '../../../../../common/config/public/Config';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ConfigClass';
|
||||
|
||||
@Injectable()
|
||||
export class MapService {
|
@ -1,16 +1,16 @@
|
||||
import {Component, HostListener, Input, OnChanges} from '@angular/core';
|
||||
import {DirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
import {DirectoryDTO} from '../../../../../common/entities/DirectoryDTO';
|
||||
import {Router, RouterLink} from '@angular/router';
|
||||
import {UserDTO} from '../../../../common/entities/UserDTO';
|
||||
import {AuthenticationService} from '../../model/network/authentication.service';
|
||||
import {UserDTO} from '../../../../../common/entities/UserDTO';
|
||||
import {AuthenticationService} from '../../../model/network/authentication.service';
|
||||
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';
|
||||
import {Config} from '../../../../common/config/public/Config';
|
||||
import {SearchResultDTO} from '../../../../common/entities/SearchResultDTO';
|
||||
import {SearchTypes} from '../../../../common/entities/AutoCompleteItem';
|
||||
import {Utils} from '../../../../../common/Utils';
|
||||
import {SortingMethods} from '../../../../../common/entities/SortingMethods';
|
||||
import {Config} from '../../../../../common/config/public/Config';
|
||||
import {SearchResultDTO} from '../../../../../common/entities/SearchResultDTO';
|
||||
import {SearchTypes} from '../../../../../common/entities/AutoCompleteItem';
|
||||
|
||||
@Component({
|
||||
selector: 'app-gallery-navbar',
|
@ -1,6 +1,6 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {Event} from '../../../common/event/Event';
|
||||
import {PageHelper} from '../model/page.helper';
|
||||
import {Event} from '../../../../common/event/Event';
|
||||
import {PageHelper} from '../../model/page.helper';
|
||||
|
||||
@Injectable()
|
||||
export class OverlayService {
|
@ -1,15 +1,15 @@
|
||||
import {Component, OnDestroy, OnInit, TemplateRef} from '@angular/core';
|
||||
import {Utils} from '../../../../common/Utils';
|
||||
import {Utils} from '../../../../../common/Utils';
|
||||
import {GalleryService} from '../gallery.service';
|
||||
import {ContentWrapper} from '../../../../common/entities/ConentWrapper';
|
||||
import {Config} from '../../../../common/config/public/Config';
|
||||
import {NotificationService} from '../../model/notification.service';
|
||||
import {DirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
import {ContentWrapper} from '../../../../../common/entities/ConentWrapper';
|
||||
import {Config} from '../../../../../common/config/public/Config';
|
||||
import {NotificationService} from '../../../model/notification.service';
|
||||
import {DirectoryDTO} from '../../../../../common/entities/DirectoryDTO';
|
||||
import {I18n} from '@ngx-translate/i18n-polyfill';
|
||||
import {BsModalService} from 'ngx-bootstrap/modal';
|
||||
import {BsModalRef} from 'ngx-bootstrap/modal/bs-modal-ref.service';
|
||||
import {OrientationType, RandomQueryDTO} from '../../../../common/entities/RandomQueryDTO';
|
||||
import {NetworkService} from '../../model/network/network.service';
|
||||
import {OrientationType, RandomQueryDTO} from '../../../../../common/entities/RandomQueryDTO';
|
||||
import {NetworkService} from '../../../model/network/network.service';
|
||||
import {Subscription} from 'rxjs';
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {NetworkService} from '../../model/network/network.service';
|
||||
import {AutoCompleteItem} from '../../../../common/entities/AutoCompleteItem';
|
||||
import {NetworkService} from '../../../model/network/network.service';
|
||||
import {AutoCompleteItem} from '../../../../../common/entities/AutoCompleteItem';
|
||||
import {GalleryCacheService} from '../cache.gallery.service';
|
||||
|
||||
@Injectable()
|
@ -1,12 +1,12 @@
|
||||
import {Component, OnDestroy} from '@angular/core';
|
||||
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 {GalleryService} from '../gallery.service';
|
||||
import {Subscription} from 'rxjs';
|
||||
import {Config} from '../../../../common/config/public/Config';
|
||||
import {NavigationService} from '../../model/navigation.service';
|
||||
import {QueryParams} from '../../../../common/QueryParams';
|
||||
import {Config} from '../../../../../common/config/public/Config';
|
||||
import {NavigationService} from '../../../model/navigation.service';
|
||||
import {QueryParams} from '../../../../../common/QueryParams';
|
||||
|
||||
@Component({
|
||||
selector: 'app-gallery-search',
|
@ -1,10 +1,10 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {NetworkService} from '../model/network/network.service';
|
||||
import {CreateSharingDTO, SharingDTO} from '../../../common/entities/SharingDTO';
|
||||
import {NetworkService} from '../../model/network/network.service';
|
||||
import {CreateSharingDTO, SharingDTO} from '../../../../common/entities/SharingDTO';
|
||||
import {Router, RoutesRecognized} from '@angular/router';
|
||||
import {BehaviorSubject, Observable} from 'rxjs';
|
||||
import {QueryParams} from '../../../common/QueryParams';
|
||||
import {UserDTO} from '../../../common/entities/UserDTO';
|
||||
import {QueryParams} from '../../../../common/QueryParams';
|
||||
import {UserDTO} from '../../../../common/entities/UserDTO';
|
||||
|
||||
@Injectable()
|
||||
export class ShareService {
|
@ -1,12 +1,12 @@
|
||||
import {Component, OnDestroy, OnInit, TemplateRef} from '@angular/core';
|
||||
import {Utils} from '../../../../common/Utils';
|
||||
import {Utils} from '../../../../../common/Utils';
|
||||
import {ShareService} from '../share.service';
|
||||
import {GalleryService} from '../gallery.service';
|
||||
import {ContentWrapper} from '../../../../common/entities/ConentWrapper';
|
||||
import {SharingDTO} from '../../../../common/entities/SharingDTO';
|
||||
import {Config} from '../../../../common/config/public/Config';
|
||||
import {NotificationService} from '../../model/notification.service';
|
||||
import {DirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
import {ContentWrapper} from '../../../../../common/entities/ConentWrapper';
|
||||
import {SharingDTO} from '../../../../../common/entities/SharingDTO';
|
||||
import {Config} from '../../../../../common/config/public/Config';
|
||||
import {NotificationService} from '../../../model/notification.service';
|
||||
import {DirectoryDTO} from '../../../../../common/entities/DirectoryDTO';
|
||||
import {I18n} from '@ngx-translate/i18n-polyfill';
|
||||
import {BsModalService} from 'ngx-bootstrap/modal';
|
||||
import {BsModalRef} from 'ngx-bootstrap/modal/bs-modal-ref.service';
|
@ -2,9 +2,8 @@ import {Injectable} from '@angular/core';
|
||||
import {GalleryCacheService} from './cache.gallery.service';
|
||||
import {Media} from './Media';
|
||||
import {MediaIcon} from './MediaIcon';
|
||||
import {PhotoDTO} from '../../../common/entities/PhotoDTO';
|
||||
import {Config} from '../../../common/config/public/Config';
|
||||
import {MediaDTO} from '../../../common/entities/MediaDTO';
|
||||
import {Config} from '../../../../common/config/public/Config';
|
||||
import {Person, PersonDTO} from '../../../../common/entities/PersonDTO';
|
||||
|
||||
export enum ThumbnailLoadingPriority {
|
||||
extraHigh = 4, high = 3, medium = 2, low = 1
|
||||
@ -36,7 +35,6 @@ export class ThumbnailLoaderService {
|
||||
const curImg = new Image();
|
||||
curImg.onload = () => {
|
||||
task.onLoaded();
|
||||
this.galleryCacheService.mediaUpdated(task.media);
|
||||
task.taskEntities.forEach((te: ThumbnailTaskEntity) => te.listener.onLoad());
|
||||
|
||||
this.taskReady(task);
|
||||
@ -74,73 +72,71 @@ export class ThumbnailLoaderService {
|
||||
|
||||
}
|
||||
|
||||
loadIcon(photo: MediaIcon, priority: ThumbnailLoadingPriority, listener: ThumbnailLoadingListener): ThumbnailTaskEntity {
|
||||
let thTask: ThumbnailTask = null;
|
||||
// is image already qued?
|
||||
for (let i = 0; i < this.que.length; i++) {
|
||||
if (this.que[i].path === photo.getIconPath()) {
|
||||
thTask = this.que[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (thTask == null) {
|
||||
thTask = {
|
||||
media: photo.media,
|
||||
inProgress: false,
|
||||
taskEntities: [],
|
||||
onLoaded: () => {
|
||||
photo.iconLoaded();
|
||||
},
|
||||
path: photo.getIconPath()
|
||||
};
|
||||
this.que.push(thTask);
|
||||
}
|
||||
|
||||
const thumbnailTaskEntity = {priority: priority, listener: listener, parentTask: thTask};
|
||||
thTask.taskEntities.push(thumbnailTaskEntity);
|
||||
if (thTask.inProgress === true) {
|
||||
listener.onStartedLoading();
|
||||
}
|
||||
loadIcon(media: MediaIcon, priority: ThumbnailLoadingPriority, listener: ThumbnailLoadingListener): ThumbnailTaskEntity {
|
||||
|
||||
|
||||
setTimeout(this.run, 0);
|
||||
return thumbnailTaskEntity;
|
||||
return this.load(media.getIconPath(),
|
||||
() => {
|
||||
media.iconLoaded();
|
||||
this.galleryCacheService.mediaUpdated(media.media);
|
||||
},
|
||||
priority,
|
||||
listener);
|
||||
}
|
||||
|
||||
loadImage(media: Media, priority: ThumbnailLoadingPriority, listener: ThumbnailLoadingListener): ThumbnailTaskEntity {
|
||||
|
||||
return this.load(media.getThumbnailPath(),
|
||||
() => {
|
||||
media.thumbnailLoaded();
|
||||
this.galleryCacheService.mediaUpdated(media.media);
|
||||
},
|
||||
priority,
|
||||
listener);
|
||||
}
|
||||
|
||||
loadPersonThumbnail(person: PersonDTO, priority: ThumbnailLoadingPriority, listener: ThumbnailLoadingListener): ThumbnailTaskEntity {
|
||||
|
||||
return this.load(Person.getThumbnailUrl(person),
|
||||
() => {
|
||||
},
|
||||
priority,
|
||||
listener);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private load(path: string,
|
||||
onLoaded: () => void,
|
||||
priority: ThumbnailLoadingPriority,
|
||||
listener: ThumbnailLoadingListener): ThumbnailTaskEntity {
|
||||
let thTask: ThumbnailTask = null;
|
||||
// is image already qued?
|
||||
// is image already queued?
|
||||
for (let i = 0; i < this.que.length; i++) {
|
||||
if (this.que[i].path === media.getThumbnailPath()) {
|
||||
if (this.que[i].path === path) {
|
||||
thTask = this.que[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (thTask == null) {
|
||||
thTask = {
|
||||
media: media.media,
|
||||
inProgress: false,
|
||||
taskEntities: [],
|
||||
onLoaded: () => {
|
||||
media.thumbnailLoaded();
|
||||
},
|
||||
path: media.getThumbnailPath()
|
||||
onLoaded: onLoaded,
|
||||
path: path
|
||||
};
|
||||
this.que.push(thTask);
|
||||
}
|
||||
|
||||
const thumbnailTaskEntity = {priority: priority, listener: listener, parentTask: thTask};
|
||||
|
||||
// add to poolTask
|
||||
thTask.taskEntities.push(thumbnailTaskEntity);
|
||||
if (thTask.inProgress === true) {
|
||||
listener.onStartedLoading();
|
||||
}
|
||||
|
||||
|
||||
setTimeout(this.run, 0);
|
||||
return thumbnailTaskEntity;
|
||||
|
||||
}
|
||||
|
||||
private getNextTask(): ThumbnailTask {
|
||||
@ -194,10 +190,9 @@ export interface ThumbnailTaskEntity {
|
||||
}
|
||||
|
||||
interface ThumbnailTask {
|
||||
media: MediaDTO;
|
||||
inProgress: boolean;
|
||||
taskEntities: Array<ThumbnailTaskEntity>;
|
||||
path: string;
|
||||
onLoaded: Function;
|
||||
onLoaded: () => void;
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ import {Injectable} from '@angular/core';
|
||||
import {ThumbnailLoaderService, ThumbnailLoadingListener, ThumbnailLoadingPriority, ThumbnailTaskEntity} from './thumbnailLoader.service';
|
||||
import {Media} from './Media';
|
||||
import {MediaIcon} from './MediaIcon';
|
||||
import {Person, PersonDTO} from '../../../../common/entities/PersonDTO';
|
||||
|
||||
|
||||
@Injectable()
|
||||
@ -19,18 +20,22 @@ export class ThumbnailManagerService {
|
||||
return new Thumbnail(photo, this.thumbnailLoader, false);
|
||||
}
|
||||
|
||||
|
||||
public getIcon(photo: MediaIcon) {
|
||||
return new IconThumbnail(photo, this.thumbnailLoader);
|
||||
}
|
||||
|
||||
|
||||
public getPersonThumbnail(person: PersonDTO): PersonThumbnail {
|
||||
return new PersonThumbnail(person, this.thumbnailLoader);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export abstract class ThumbnailBase {
|
||||
|
||||
public loading = false;
|
||||
protected available = false;
|
||||
protected src: string = null;
|
||||
public loading = false;
|
||||
protected error = false;
|
||||
protected onLoad: Function = null;
|
||||
protected thumbnailTask: ThumbnailTaskEntity = null;
|
||||
@ -71,6 +76,64 @@ export abstract class ThumbnailBase {
|
||||
}
|
||||
|
||||
|
||||
export class PersonThumbnail extends ThumbnailBase {
|
||||
|
||||
constructor(private person: PersonDTO, thumbnailService: ThumbnailLoaderService) {
|
||||
super(thumbnailService);
|
||||
this.src = '';
|
||||
this.error = false;
|
||||
if (this.person.readyThumbnail) {
|
||||
this.src = Person.getThumbnailUrl(person);
|
||||
this.available = true;
|
||||
if (this.onLoad) {
|
||||
this.onLoad();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
|
||||
const listener: ThumbnailLoadingListener = {
|
||||
onStartedLoading: () => { // onLoadStarted
|
||||
this.loading = true;
|
||||
},
|
||||
onLoad: () => {// onLoaded
|
||||
this.src = Person.getThumbnailUrl(person);
|
||||
if (this.onLoad) {
|
||||
this.onLoad();
|
||||
}
|
||||
this.available = true;
|
||||
this.loading = false;
|
||||
this.thumbnailTask = null;
|
||||
},
|
||||
onError: () => {// onError
|
||||
this.thumbnailTask = null;
|
||||
this.loading = false;
|
||||
this.error = true;
|
||||
}
|
||||
};
|
||||
this.thumbnailTask = this.thumbnailService.loadPersonThumbnail(person, ThumbnailLoadingPriority.high, listener);
|
||||
|
||||
|
||||
}, 0);
|
||||
|
||||
}
|
||||
|
||||
set Visible(visible: boolean) {
|
||||
if (!this.thumbnailTask) {
|
||||
return;
|
||||
}
|
||||
if (visible === true) {
|
||||
this.thumbnailTask.priority = ThumbnailLoadingPriority.high;
|
||||
} else {
|
||||
this.thumbnailTask.priority = ThumbnailLoadingPriority.medium;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
export class IconThumbnail extends ThumbnailBase {
|
||||
|
||||
constructor(private media: MediaIcon, thumbnailService: ThumbnailLoaderService) {
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user