mirror of
https://github.com/bpatrik/pigallery2.git
synced 2025-05-31 23:09:48 +02:00
bug fixing
This commit is contained in:
parent
7754905c19
commit
f099dc6eb0
@ -4,9 +4,8 @@ import {NextFunction, Request, Response} from "express";
|
|||||||
import {Error, ErrorCodes} from "../../common/entities/Error";
|
import {Error, ErrorCodes} from "../../common/entities/Error";
|
||||||
import {DirectoryDTO} from "../../common/entities/DirectoryDTO";
|
import {DirectoryDTO} from "../../common/entities/DirectoryDTO";
|
||||||
import {ObjectManagerRepository} from "../model/ObjectManagerRepository";
|
import {ObjectManagerRepository} from "../model/ObjectManagerRepository";
|
||||||
import {AutoCompleteItem, SearchTypes} from "../../common/entities/AutoCompleteItem";
|
import {SearchTypes} from "../../common/entities/AutoCompleteItem";
|
||||||
import {ContentWrapper} from "../../common/entities/ConentWrapper";
|
import {ContentWrapper} from "../../common/entities/ConentWrapper";
|
||||||
import {SearchResultDTO} from "../../common/entities/SearchResult";
|
|
||||||
import {PhotoDTO} from "../../common/entities/PhotoDTO";
|
import {PhotoDTO} from "../../common/entities/PhotoDTO";
|
||||||
import {ProjectPath} from "../ProjectPath";
|
import {ProjectPath} from "../ProjectPath";
|
||||||
import {Logger} from "../Logger";
|
import {Logger} from "../Logger";
|
||||||
@ -92,7 +91,7 @@ export class GalleryMWs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static search(req: Request, res: Response, next: NextFunction) {
|
public static async search(req: Request, res: Response, next: NextFunction) {
|
||||||
if (Config.Client.Search.searchEnabled === false) {
|
if (Config.Client.Search.searchEnabled === false) {
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
@ -105,18 +104,21 @@ export class GalleryMWs {
|
|||||||
if (req.query.type) {
|
if (req.query.type) {
|
||||||
type = parseInt(req.query.type);
|
type = parseInt(req.query.type);
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
const result = await ObjectManagerRepository.getInstance().SearchManager.search(req.params.text, type);
|
||||||
|
|
||||||
ObjectManagerRepository.getInstance().SearchManager.search(req.params.text, type, (err, result: SearchResultDTO) => {
|
result.directories.forEach(dir => dir.photos = dir.photos || []);
|
||||||
if (err || !result) {
|
|
||||||
return next(new Error(ErrorCodes.GENERAL_ERROR, err));
|
|
||||||
}
|
|
||||||
req.resultPipe = new ContentWrapper(null, result);
|
req.resultPipe = new ContentWrapper(null, result);
|
||||||
return next();
|
return next();
|
||||||
});
|
} catch (err) {
|
||||||
|
|
||||||
|
Logger.warn(LOG_TAG, "Error during searching", err);
|
||||||
|
console.error(err);
|
||||||
|
return next(new Error(ErrorCodes.GENERAL_ERROR, err));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async instantSearch(req: Request, res: Response, next: NextFunction) {
|
||||||
public static instantSearch(req: Request, res: Response, next: NextFunction) {
|
|
||||||
if (Config.Client.Search.instantSearchEnabled === false) {
|
if (Config.Client.Search.instantSearchEnabled === false) {
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
@ -125,17 +127,20 @@ export class GalleryMWs {
|
|||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await ObjectManagerRepository.getInstance().SearchManager.instantSearch(req.params.text);
|
||||||
|
|
||||||
ObjectManagerRepository.getInstance().SearchManager.instantSearch(req.params.text, (err, result: SearchResultDTO) => {
|
result.directories.forEach(dir => dir.photos = dir.photos || []);
|
||||||
if (err || !result) {
|
|
||||||
return next(new Error(ErrorCodes.GENERAL_ERROR, err));
|
|
||||||
}
|
|
||||||
req.resultPipe = new ContentWrapper(null, result);
|
req.resultPipe = new ContentWrapper(null, result);
|
||||||
return next();
|
return next();
|
||||||
});
|
} catch (err) {
|
||||||
|
Logger.warn(LOG_TAG, "Error during searching", err);
|
||||||
|
console.error(err);
|
||||||
|
return next(new Error(ErrorCodes.GENERAL_ERROR, err));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static autocomplete(req: Request, res: Response, next: NextFunction) {
|
public static async autocomplete(req: Request, res: Response, next: NextFunction) {
|
||||||
if (Config.Client.Search.autocompleteEnabled === false) {
|
if (Config.Client.Search.autocompleteEnabled === false) {
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
@ -143,13 +148,15 @@ export class GalleryMWs {
|
|||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectManagerRepository.getInstance().SearchManager.autocomplete(req.params.text, (err, items: Array<AutoCompleteItem>) => {
|
try {
|
||||||
if (err || !items) {
|
req.resultPipe = await ObjectManagerRepository.getInstance().SearchManager.autocomplete(req.params.text);
|
||||||
return next(new Error(ErrorCodes.GENERAL_ERROR, err));
|
|
||||||
}
|
|
||||||
req.resultPipe = items;
|
|
||||||
return next();
|
return next();
|
||||||
});
|
} catch (err) {
|
||||||
|
Logger.warn(LOG_TAG, "Error during searching", err);
|
||||||
|
console.error(err);
|
||||||
|
return next(new Error(ErrorCodes.GENERAL_ERROR, err));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import {AutoCompleteItem, SearchTypes} from "../../../common/entities/AutoCompleteItem";
|
import {AutoCompleteItem, SearchTypes} from "../../../common/entities/AutoCompleteItem";
|
||||||
import {SearchResultDTO} from "../../../common/entities/SearchResult";
|
import {SearchResultDTO} from "../../../common/entities/SearchResult";
|
||||||
export interface ISearchManager {
|
export interface ISearchManager {
|
||||||
autocomplete(text: string, cb: (error: any, result: Array<AutoCompleteItem>) => void): void;
|
autocomplete(text: string): Promise<AutoCompleteItem[]>;
|
||||||
search(text: string, searchType: SearchTypes, cb: (error: any, result: SearchResultDTO) => void): void;
|
search(text: string, searchType: SearchTypes): Promise<SearchResultDTO>;
|
||||||
instantSearch(text: string, cb: (error: any, result: SearchResultDTO) => void): void;
|
instantSearch(text: string): Promise<SearchResultDTO>;
|
||||||
isSupported(): boolean;
|
isSupported(): boolean;
|
||||||
}
|
}
|
||||||
|
@ -3,22 +3,22 @@ import {ISearchManager} from "../interfaces/ISearchManager";
|
|||||||
import {SearchResultDTO} from "../../../common/entities/SearchResult";
|
import {SearchResultDTO} from "../../../common/entities/SearchResult";
|
||||||
|
|
||||||
export class SearchManager implements ISearchManager {
|
export class SearchManager implements ISearchManager {
|
||||||
|
autocomplete(text: string): Promise<AutoCompleteItem[]> {
|
||||||
|
throw new Error("Method not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
search(text: string, searchType: SearchTypes): Promise<SearchResultDTO> {
|
||||||
|
throw new Error("Method not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
instantSearch(text: string): Promise<SearchResultDTO> {
|
||||||
|
throw new Error("Method not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
isSupported(): boolean {
|
isSupported(): boolean {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
autocomplete(text: string, cb: (error: any, result: Array<AutoCompleteItem>) => void) {
|
|
||||||
throw new Error("not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
search(text: string, searchType: SearchTypes, cb: (error: any, result: SearchResultDTO) => void) {
|
|
||||||
throw new Error("not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
instantSearch(text: string, cb: (error: any, result: SearchResultDTO) => void) {
|
|
||||||
throw new Error("not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,163 +12,157 @@ export class SearchManager implements ISearchManager {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
autocomplete(text: string, cb: (error: any, result: Array<AutoCompleteItem>) => void) {
|
async autocomplete(text: string) {
|
||||||
|
|
||||||
MySQLConnection.getConnection().then(async connection => {
|
const connection = await MySQLConnection.getConnection();
|
||||||
try {
|
|
||||||
let result: Array<AutoCompleteItem> = [];
|
let result: Array<AutoCompleteItem> = [];
|
||||||
let photoRepository = connection.getRepository(PhotoEntity);
|
let photoRepository = connection.getRepository(PhotoEntity);
|
||||||
let directoryRepository = connection.getRepository(DirectoryEntity);
|
let directoryRepository = connection.getRepository(DirectoryEntity);
|
||||||
|
|
||||||
|
|
||||||
(await photoRepository
|
(await photoRepository
|
||||||
.createQueryBuilder('photo')
|
.createQueryBuilder('photo')
|
||||||
.select('DISTINCT(photo.metadataKeywords)')
|
.select('DISTINCT(photo.metadataKeywords)')
|
||||||
.where('photo.metadata.keywords LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
.where('photo.metadata.keywords LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||||
.setLimit(5)
|
.setLimit(5)
|
||||||
.getRawMany())
|
.getRawMany())
|
||||||
.map(r => <Array<string>>JSON.parse(r.metadataKeywords))
|
.map(r => <Array<string>>JSON.parse(r.metadataKeywords))
|
||||||
.forEach(keywords => {
|
.forEach(keywords => {
|
||||||
result = result.concat(this.encapsulateAutoComplete(keywords.filter(k => k.toLowerCase().indexOf(text.toLowerCase()) != -1), SearchTypes.keyword));
|
result = result.concat(this.encapsulateAutoComplete(keywords.filter(k => k.toLowerCase().indexOf(text.toLowerCase()) != -1), SearchTypes.keyword));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
(await photoRepository
|
(await photoRepository
|
||||||
.createQueryBuilder('photo')
|
.createQueryBuilder('photo')
|
||||||
.select('DISTINCT(photo.metadataPositionData)')
|
.select('DISTINCT(photo.metadataPositionData)')
|
||||||
.where('photo.metadata.positionData LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
.where('photo.metadata.positionData LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||||
.setLimit(5)
|
.setLimit(5)
|
||||||
.getRawMany())
|
.getRawMany())
|
||||||
.map(r => <PositionMetaData>JSON.parse(r.metadataPositionData))
|
.map(r => <PositionMetaData>JSON.parse(r.metadataPositionData))
|
||||||
.map(pm => <Array<string>>[pm.city || "", pm.country || "", pm.state || ""])
|
.filter(pm => !!pm)
|
||||||
.forEach(positions => {
|
.map(pm => <Array<string>>[pm.city || "", pm.country || "", pm.state || ""])
|
||||||
result = result.concat(this.encapsulateAutoComplete(positions.filter(p => p.toLowerCase().indexOf(text.toLowerCase()) != -1), SearchTypes.position));
|
.forEach(positions => {
|
||||||
});
|
result = result.concat(this.encapsulateAutoComplete(positions.filter(p => p.toLowerCase().indexOf(text.toLowerCase()) != -1), SearchTypes.position));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
result = result.concat(this.encapsulateAutoComplete((await photoRepository
|
result = result.concat(this.encapsulateAutoComplete((await photoRepository
|
||||||
.createQueryBuilder('photo')
|
.createQueryBuilder('photo')
|
||||||
.select('DISTINCT(photo.name)')
|
.select('DISTINCT(photo.name)')
|
||||||
.where('photo.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
.where('photo.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||||
.setLimit(5)
|
.setLimit(5)
|
||||||
.getRawMany())
|
.getRawMany())
|
||||||
.map(r => r.name), SearchTypes.image));
|
.map(r => r.name), SearchTypes.image));
|
||||||
|
|
||||||
result = result.concat(this.encapsulateAutoComplete((await directoryRepository
|
result = result.concat(this.encapsulateAutoComplete((await directoryRepository
|
||||||
.createQueryBuilder('dir')
|
.createQueryBuilder('dir')
|
||||||
.select('DISTINCT(dir.name)')
|
.select('DISTINCT(dir.name)')
|
||||||
.where('dir.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
.where('dir.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||||
.setLimit(5)
|
.setLimit(5)
|
||||||
.getRawMany())
|
.getRawMany())
|
||||||
.map(r => r.name), SearchTypes.directory));
|
.map(r => r.name), SearchTypes.directory));
|
||||||
|
|
||||||
|
|
||||||
return cb(null, this.autoCompleteItemsUnique(result));
|
return this.autoCompleteItemsUnique(result);
|
||||||
} catch (error) {
|
|
||||||
return cb(error, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
}).catch((error) => {
|
|
||||||
return cb(error, null);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
search(text: string, searchType: SearchTypes, cb: (error: any, result: SearchResultDTO) => void) {
|
async search(text: string, searchType: SearchTypes) {
|
||||||
MySQLConnection.getConnection().then(async connection => {
|
const connection = await MySQLConnection.getConnection();
|
||||||
|
|
||||||
let result: SearchResultDTO = <SearchResultDTO>{
|
let result: SearchResultDTO = <SearchResultDTO>{
|
||||||
searchText: text,
|
searchText: text,
|
||||||
searchType: searchType,
|
searchType: searchType,
|
||||||
directories: [],
|
directories: [],
|
||||||
photos: []
|
photos: []
|
||||||
};
|
};
|
||||||
|
|
||||||
let query = connection
|
let query = connection
|
||||||
.getRepository(PhotoEntity)
|
.getRepository(PhotoEntity)
|
||||||
.createQueryBuilder("photo");
|
.createQueryBuilder("photo")
|
||||||
|
.innerJoinAndSelect("photo.directory", "directory")
|
||||||
|
.orderBy("photo.metadata.creationDate", "ASC");
|
||||||
|
|
||||||
|
|
||||||
if (!searchType || searchType === SearchTypes.image) {
|
if (!searchType || searchType === SearchTypes.directory) {
|
||||||
query.orWhere('photo.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"});
|
query.orWhere('directory.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!searchType || searchType === SearchTypes.image) {
|
||||||
|
query.orWhere('photo.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!searchType || searchType === SearchTypes.position) {
|
||||||
|
query.orWhere('photo.metadata.positionData LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"});
|
||||||
|
}
|
||||||
|
if (!searchType || searchType === SearchTypes.keyword) {
|
||||||
|
query.orWhere('photo.metadata.keywords LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"});
|
||||||
|
}
|
||||||
|
let photos = await query
|
||||||
|
.getMany();
|
||||||
|
|
||||||
|
|
||||||
|
if (photos) {
|
||||||
|
for (let i = 0; i < photos.length; i++) {
|
||||||
|
photos[i].metadata.keywords = <any>JSON.parse(<any>photos[i].metadata.keywords);
|
||||||
|
photos[i].metadata.cameraData = <any>JSON.parse(<any>photos[i].metadata.cameraData);
|
||||||
|
photos[i].metadata.positionData = <any>JSON.parse(<any>photos[i].metadata.positionData);
|
||||||
|
photos[i].metadata.size = <any>JSON.parse(<any>photos[i].metadata.size);
|
||||||
}
|
}
|
||||||
|
result.photos = photos;
|
||||||
|
}
|
||||||
|
|
||||||
if (!searchType || searchType === SearchTypes.position) {
|
result.directories = await connection
|
||||||
query.orWhere('photo.metadata.positionData LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"});
|
.getRepository(DirectoryEntity)
|
||||||
}
|
.createQueryBuilder("dir")
|
||||||
if (!searchType || searchType === SearchTypes.keyword) {
|
.where('dir.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||||
query.orWhere('photo.metadata.keywords LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"});
|
.getMany();
|
||||||
}
|
|
||||||
let photos = await query
|
|
||||||
.innerJoinAndSelect("photo.directory", "directory")
|
|
||||||
.getMany();
|
|
||||||
|
|
||||||
|
|
||||||
if (photos) {
|
return result;
|
||||||
for (let i = 0; i < photos.length; i++) {
|
|
||||||
photos[i].metadata.keywords = <any>JSON.parse(<any>photos[i].metadata.keywords);
|
|
||||||
photos[i].metadata.cameraData = <any>JSON.parse(<any>photos[i].metadata.cameraData);
|
|
||||||
photos[i].metadata.positionData = <any>JSON.parse(<any>photos[i].metadata.positionData);
|
|
||||||
photos[i].metadata.size = <any>JSON.parse(<any>photos[i].metadata.size);
|
|
||||||
}
|
|
||||||
result.photos = photos;
|
|
||||||
}
|
|
||||||
|
|
||||||
result.directories = await connection
|
|
||||||
.getRepository(DirectoryEntity)
|
|
||||||
.createQueryBuilder("dir")
|
|
||||||
.where('dir.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
|
||||||
.getMany();
|
|
||||||
|
|
||||||
|
|
||||||
return cb(null, result);
|
|
||||||
}).catch((error) => {
|
|
||||||
return cb(error, null);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
instantSearch(text: string, cb: (error: any, result: SearchResultDTO) => void) {
|
async instantSearch(text: string) {
|
||||||
MySQLConnection.getConnection().then(async connection => {
|
const connection = await MySQLConnection.getConnection();
|
||||||
|
|
||||||
let result: SearchResultDTO = <SearchResultDTO>{
|
let result: SearchResultDTO = <SearchResultDTO>{
|
||||||
searchText: text,
|
searchText: text,
|
||||||
directories: [],
|
directories: [],
|
||||||
photos: []
|
photos: []
|
||||||
};
|
};
|
||||||
|
|
||||||
let photos = await connection
|
let photos = await connection
|
||||||
.getRepository(PhotoEntity)
|
.getRepository(PhotoEntity)
|
||||||
.createQueryBuilder("photo")
|
.createQueryBuilder("photo")
|
||||||
.where('photo.metadata.keywords LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
.orderBy("photo.metadata.creationDate", "ASC")
|
||||||
.orWhere('photo.metadata.positionData LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
.where('photo.metadata.keywords LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||||
.orWhere('photo.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
.orWhere('photo.metadata.positionData LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||||
.innerJoinAndSelect("photo.directory", "directory")
|
.orWhere('photo.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||||
.setLimit(10)
|
.innerJoinAndSelect("photo.directory", "directory")
|
||||||
.getMany();
|
.setLimit(10)
|
||||||
|
.getMany();
|
||||||
|
|
||||||
|
|
||||||
if (photos) {
|
if (photos) {
|
||||||
for (let i = 0; i < photos.length; i++) {
|
for (let i = 0; i < photos.length; i++) {
|
||||||
photos[i].metadata.keywords = <any>JSON.parse(<any>photos[i].metadata.keywords);
|
photos[i].metadata.keywords = <any>JSON.parse(<any>photos[i].metadata.keywords);
|
||||||
photos[i].metadata.cameraData = <any>JSON.parse(<any>photos[i].metadata.cameraData);
|
photos[i].metadata.cameraData = <any>JSON.parse(<any>photos[i].metadata.cameraData);
|
||||||
photos[i].metadata.positionData = <any>JSON.parse(<any>photos[i].metadata.positionData);
|
photos[i].metadata.positionData = <any>JSON.parse(<any>photos[i].metadata.positionData);
|
||||||
photos[i].metadata.size = <any>JSON.parse(<any>photos[i].metadata.size);
|
photos[i].metadata.size = <any>JSON.parse(<any>photos[i].metadata.size);
|
||||||
}
|
|
||||||
result.photos = photos;
|
|
||||||
}
|
}
|
||||||
|
result.photos = photos;
|
||||||
|
}
|
||||||
|
|
||||||
let directories = await connection
|
let directories = await connection
|
||||||
.getRepository(DirectoryEntity)
|
.getRepository(DirectoryEntity)
|
||||||
.createQueryBuilder("dir")
|
.createQueryBuilder("dir")
|
||||||
.where('dir.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
.where('dir.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||||
.setLimit(10)
|
.setLimit(10)
|
||||||
.getMany();
|
.getMany();
|
||||||
|
|
||||||
result.directories = directories;
|
result.directories = directories;
|
||||||
|
|
||||||
return cb(null, result);
|
return result;
|
||||||
}).catch((error) => {
|
|
||||||
return cb(error, null);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private encapsulateAutoComplete(values: Array<string>, type: SearchTypes) {
|
private encapsulateAutoComplete(values: Array<string>, type: SearchTypes) {
|
||||||
|
@ -9,3 +9,16 @@ export interface DirectoryDTO {
|
|||||||
directories: Array<DirectoryDTO>;
|
directories: Array<DirectoryDTO>;
|
||||||
photos: Array<PhotoDTO>;
|
photos: Array<PhotoDTO>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export module DirectoryUtil {
|
||||||
|
export const addReferences = (dir: DirectoryDTO) => {
|
||||||
|
dir.photos.forEach((photo: PhotoDTO) => {
|
||||||
|
photo.directory = dir;
|
||||||
|
});
|
||||||
|
|
||||||
|
dir.directories.forEach((directory: DirectoryDTO) => {
|
||||||
|
addReferences(directory);
|
||||||
|
directory.parent = dir;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -2,6 +2,8 @@ import {Component, OnInit} from "@angular/core";
|
|||||||
import {AuthenticationService} from "./model/network/authentication.service";
|
import {AuthenticationService} from "./model/network/authentication.service";
|
||||||
import {UserDTO} from "../../common/entities/UserDTO";
|
import {UserDTO} from "../../common/entities/UserDTO";
|
||||||
import {Router} from "@angular/router";
|
import {Router} from "@angular/router";
|
||||||
|
import {Config} from "../../common/config/public/Config";
|
||||||
|
import {Title} from "@angular/platform-browser";
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -11,10 +13,11 @@ import {Router} from "@angular/router";
|
|||||||
})
|
})
|
||||||
export class AppComponent implements OnInit {
|
export class AppComponent implements OnInit {
|
||||||
|
|
||||||
constructor(private _router: Router, private _authenticationService: AuthenticationService) {
|
constructor(private _router: Router, private _authenticationService: AuthenticationService, private _title: Title) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
this._title.setTitle(Config.Client.applicationTitle);
|
||||||
this._authenticationService.user.subscribe((user: UserDTO) => {
|
this._authenticationService.user.subscribe((user: UserDTO) => {
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
if (this._router.isActive('login', true)) {
|
if (this._router.isActive('login', true)) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import {Injectable} from "@angular/core";
|
import {Injectable} from "@angular/core";
|
||||||
import {PhotoDTO} from "../../../common/entities/PhotoDTO";
|
import {PhotoDTO} from "../../../common/entities/PhotoDTO";
|
||||||
import {DirectoryDTO} from "../../../common/entities/DirectoryDTO";
|
import {DirectoryDTO, DirectoryUtil} from "../../../common/entities/DirectoryDTO";
|
||||||
import {Utils} from "../../../common/Utils";
|
import {Utils} from "../../../common/Utils";
|
||||||
import {Config} from "../../../common/config/public/Config";
|
import {Config} from "../../../common/config/public/Config";
|
||||||
|
|
||||||
@ -16,23 +16,7 @@ export class GalleryCacheService {
|
|||||||
if (value != null) {
|
if (value != null) {
|
||||||
let directory: DirectoryDTO = JSON.parse(value);
|
let directory: DirectoryDTO = JSON.parse(value);
|
||||||
|
|
||||||
|
DirectoryUtil.addReferences(directory);
|
||||||
//Add references
|
|
||||||
let addDir = (dir: DirectoryDTO) => {
|
|
||||||
dir.photos.forEach((photo: PhotoDTO) => {
|
|
||||||
photo.directory = dir;
|
|
||||||
});
|
|
||||||
|
|
||||||
dir.directories.forEach((directory: DirectoryDTO) => {
|
|
||||||
addDir(directory);
|
|
||||||
directory.parent = dir;
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
addDir(directory);
|
|
||||||
|
|
||||||
|
|
||||||
return directory;
|
return directory;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -4,4 +4,9 @@ gallery-map {
|
|||||||
display: block;
|
display: block;
|
||||||
height: 80px;
|
height: 80px;
|
||||||
width: 100px;
|
width: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.directories {
|
||||||
|
margin-right: 1px;
|
||||||
|
margin-left: 1px;
|
||||||
|
}
|
||||||
|
@ -14,9 +14,10 @@
|
|||||||
<div body class="container" style="width: 100%; padding:0" *ngIf="_galleryService.content.value.directory">
|
<div body class="container" style="width: 100%; padding:0" *ngIf="_galleryService.content.value.directory">
|
||||||
<gallery-navbar [directory]="_galleryService.content.value.directory"></gallery-navbar>
|
<gallery-navbar [directory]="_galleryService.content.value.directory"></gallery-navbar>
|
||||||
|
|
||||||
<gallery-directory *ngFor="let directory of directories"
|
<div class="directories">
|
||||||
[directory]="directory"></gallery-directory>
|
<gallery-directory *ngFor="let directory of directories"
|
||||||
|
[directory]="directory"></gallery-directory>
|
||||||
|
</div>
|
||||||
<gallery-map *ngIf="isPhotoWithLocation" [photos]="_galleryService.content.value.directory.photos"></gallery-map>
|
<gallery-map *ngIf="isPhotoWithLocation" [photos]="_galleryService.content.value.directory.photos"></gallery-map>
|
||||||
<gallery-grid [photos]="_galleryService.content.value.directory.photos" [lightbox]="lightbox"></gallery-grid>
|
<gallery-grid [photos]="_galleryService.content.value.directory.photos" [lightbox]="lightbox"></gallery-grid>
|
||||||
</div>
|
</div>
|
||||||
@ -31,14 +32,15 @@
|
|||||||
<span *ngSwitchCase="2" class="glyphicon glyphicon-tag"></span>
|
<span *ngSwitchCase="2" class="glyphicon glyphicon-tag"></span>
|
||||||
<span *ngSwitchCase="3" class="glyphicon glyphicon-map-marker"></span>
|
<span *ngSwitchCase="3" class="glyphicon glyphicon-map-marker"></span>
|
||||||
</span>
|
</span>
|
||||||
<strong>{{_galleryService.content.searchResult.searchText}}</strong>
|
<strong>{{_galleryService.content.value.searchResult.searchText}}</strong>
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<gallery-map *ngIf="isPhotoWithLocation" [photos]="_galleryService.content.value.searchResult.photos"></gallery-map>
|
<gallery-map *ngIf="isPhotoWithLocation" [photos]="_galleryService.content.value.searchResult.photos"></gallery-map>
|
||||||
|
|
||||||
<div *ngFor="let directory of directories">
|
<div class="directories">
|
||||||
<gallery-directory *ngIf="directory" [directory]="directory"></gallery-directory>
|
<gallery-directory *ngFor="let directory of directories"
|
||||||
|
[directory]="directory"></gallery-directory>
|
||||||
</div>
|
</div>
|
||||||
<gallery-grid [photos]="_galleryService.content.value.searchResult.photos" [lightbox]="lightbox"></gallery-grid>
|
<gallery-grid [photos]="_galleryService.content.value.searchResult.photos" [lightbox]="lightbox"></gallery-grid>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import {Injectable} from "@angular/core";
|
import {Injectable} from "@angular/core";
|
||||||
import {NetworkService} from "../model/network/network.service";
|
import {NetworkService} from "../model/network/network.service";
|
||||||
import {ContentWrapper} from "../../../common/entities/ConentWrapper";
|
import {ContentWrapper} from "../../../common/entities/ConentWrapper";
|
||||||
import {PhotoDTO} from "../../../common/entities/PhotoDTO";
|
import {DirectoryDTO, DirectoryUtil} from "../../../common/entities/DirectoryDTO";
|
||||||
import {DirectoryDTO} from "../../../common/entities/DirectoryDTO";
|
|
||||||
import {SearchTypes} from "../../../common/entities/AutoCompleteItem";
|
import {SearchTypes} from "../../../common/entities/AutoCompleteItem";
|
||||||
import {GalleryCacheService} from "./cache.gallery.service";
|
import {GalleryCacheService} from "./cache.gallery.service";
|
||||||
import {BehaviorSubject} from "rxjs/BehaviorSubject";
|
import {BehaviorSubject} from "rxjs/BehaviorSubject";
|
||||||
@ -42,6 +41,7 @@ export class GalleryService {
|
|||||||
cw = await this.networkService.getJson<ContentWrapper>("/gallery/content/" + directoryName + "?sk=" + this._shareService.getSharingKey());
|
cw = await this.networkService.getJson<ContentWrapper>("/gallery/content/" + directoryName + "?sk=" + this._shareService.getSharingKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cw == null) {
|
if (cw == null) {
|
||||||
cw = await this.networkService.getJson<ContentWrapper>("/gallery/content/" + directoryName);
|
cw = await this.networkService.getJson<ContentWrapper>("/gallery/content/" + directoryName);
|
||||||
}
|
}
|
||||||
@ -52,20 +52,8 @@ export class GalleryService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Add references
|
|
||||||
let addDir = (dir: DirectoryDTO) => {
|
|
||||||
dir.photos.forEach((photo: PhotoDTO) => {
|
|
||||||
photo.directory = dir;
|
|
||||||
});
|
|
||||||
|
|
||||||
dir.directories.forEach((directory: DirectoryDTO) => {
|
DirectoryUtil.addReferences(cw.directory);
|
||||||
addDir(directory);
|
|
||||||
directory.parent = dir;
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
addDir(cw.directory);
|
|
||||||
|
|
||||||
|
|
||||||
this.lastDirectory = cw.directory;
|
this.lastDirectory = cw.directory;
|
||||||
@ -79,7 +67,7 @@ export class GalleryService {
|
|||||||
//TODO: cache
|
//TODO: cache
|
||||||
public async search(text: string, type?: SearchTypes): Promise<ContentWrapper> {
|
public async search(text: string, type?: SearchTypes): Promise<ContentWrapper> {
|
||||||
clearTimeout(this.searchId);
|
clearTimeout(this.searchId);
|
||||||
if (text === null || text === '') {
|
if (text === null || text === '' || text.trim() == ".") {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,7 +82,7 @@ export class GalleryService {
|
|||||||
|
|
||||||
//TODO: cache (together with normal search)
|
//TODO: cache (together with normal search)
|
||||||
public async instantSearch(text: string): Promise<ContentWrapper> {
|
public async instantSearch(text: string): Promise<ContentWrapper> {
|
||||||
if (text === null || text === '') {
|
if (text === null || text === '' || text.trim() == ".") {
|
||||||
const content = new ContentWrapper();
|
const content = new ContentWrapper();
|
||||||
content.directory = this.lastDirectory;
|
content.directory = this.lastDirectory;
|
||||||
content.searchResult = null;
|
content.searchResult = null;
|
||||||
|
@ -97,6 +97,10 @@ export class GallerySearchComponent {
|
|||||||
if (!Config.Client.Search.autocompleteEnabled) {
|
if (!Config.Client.Search.autocompleteEnabled) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if (searchText.trim() == ".") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (searchText.trim().length > 0) {
|
if (searchText.trim().length > 0) {
|
||||||
try {
|
try {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user