1
0
mirror of https://github.com/xuthus83/pigallery2.git synced 2024-11-03 21:04:03 +08:00

design bug fix (search and settings badge)

This commit is contained in:
Patrik J. Braun 2018-11-24 14:21:46 +01:00
parent 48aaf54c7d
commit 930c1a2933
8 changed files with 50 additions and 22 deletions

View File

@ -138,6 +138,7 @@ apt-get install build-essential libkrb5-dev gcc g++
* Random photo url * Random photo url
* You can generate an url that returns a random photo from your gallery. You can use this feature to develop 3rd party applications, like: changing desktop background * You can generate an url that returns a random photo from your gallery. You can use this feature to develop 3rd party applications, like: changing desktop background
* video support * video support
* uses ffmpeg and ffprobe to generate video thumbnails
* **Markdown based blogging support** - `future plan` * **Markdown based blogging support** - `future plan`
* you can write some note in the blog.md for every directory * you can write some note in the blog.md for every directory
* bug free :) - `In progress` * bug free :) - `In progress`

View File

@ -5,6 +5,7 @@ import {SQLConnection} from './SQLConnection';
import {PhotoEntity} from './enitites/PhotoEntity'; import {PhotoEntity} from './enitites/PhotoEntity';
import {DirectoryEntity} from './enitites/DirectoryEntity'; import {DirectoryEntity} from './enitites/DirectoryEntity';
import {MediaEntity} from './enitites/MediaEntity'; import {MediaEntity} from './enitites/MediaEntity';
import {VideoEntity} from './enitites/VideoEntity';
export class SearchManager implements ISearchManager { export class SearchManager implements ISearchManager {
@ -27,6 +28,7 @@ export class SearchManager implements ISearchManager {
let result: AutoCompleteItem[] = []; let result: AutoCompleteItem[] = [];
const photoRepository = connection.getRepository(PhotoEntity); const photoRepository = connection.getRepository(PhotoEntity);
const videoRepository = connection.getRepository(VideoEntity);
const mediaRepository = connection.getRepository(MediaEntity); const mediaRepository = connection.getRepository(MediaEntity);
const directoryRepository = connection.getRepository(DirectoryEntity); const directoryRepository = connection.getRepository(DirectoryEntity);
@ -60,13 +62,21 @@ export class SearchManager implements ISearchManager {
.filter(p => p.toLowerCase().indexOf(text.toLowerCase()) !== -1), SearchTypes.position)); .filter(p => p.toLowerCase().indexOf(text.toLowerCase()) !== -1), SearchTypes.position));
}); });
result = result.concat(this.encapsulateAutoComplete((await mediaRepository result = result.concat(this.encapsulateAutoComplete((await photoRepository
.createQueryBuilder('media') .createQueryBuilder('media')
.select('DISTINCT(media.name)') .select('DISTINCT(media.name)')
.where('media.name LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}) .where('media.name LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'})
.limit(5) .limit(5)
.getRawMany()) .getRawMany())
.map(r => r.name), SearchTypes.image)); .map(r => r.name), SearchTypes.photo));
result = result.concat(this.encapsulateAutoComplete((await videoRepository
.createQueryBuilder('media')
.select('DISTINCT(media.name)')
.where('media.name LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'})
.limit(5)
.getRawMany())
.map(r => r.name), SearchTypes.video));
result = result.concat(this.encapsulateAutoComplete((await directoryRepository result = result.concat(this.encapsulateAutoComplete((await directoryRepository
.createQueryBuilder('dir') .createQueryBuilder('dir')
@ -91,9 +101,15 @@ export class SearchManager implements ISearchManager {
resultOverflow: false resultOverflow: false
}; };
const query = connection let repostiroy = connection.getRepository(MediaEntity);
.getRepository(MediaEntity)
.createQueryBuilder('media') if (searchType === SearchTypes.photo) {
repostiroy = connection.getRepository(PhotoEntity);
} else if (searchType === SearchTypes.video) {
repostiroy = connection.getRepository(VideoEntity);
}
const query = repostiroy.createQueryBuilder('media')
.innerJoinAndSelect('media.directory', 'directory') .innerJoinAndSelect('media.directory', 'directory')
.orderBy('media.metadata.creationDate', 'ASC'); .orderBy('media.metadata.creationDate', 'ASC');
@ -102,7 +118,7 @@ export class SearchManager implements ISearchManager {
query.orWhere('directory.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) { if (!searchType || searchType === SearchTypes.photo || searchType === SearchTypes.video) {
query.orWhere('media.name LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}); query.orWhere('media.name LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'});
} }
@ -173,7 +189,7 @@ export class SearchManager implements ISearchManager {
return result; return result;
} }
private encapsulateAutoComplete(values: Array<string>, type: SearchTypes): Array<AutoCompleteItem> { private encapsulateAutoComplete(values: string[], type: SearchTypes): Array<AutoCompleteItem> {
const res = []; const res = [];
values.forEach((value) => { values.forEach((value) => {
res.push(new AutoCompleteItem(value, type)); res.push(new AutoCompleteItem(value, type));

View File

@ -2,7 +2,8 @@ export enum SearchTypes {
directory = 1, directory = 1,
keyword = 2, keyword = 2,
position = 3, position = 3,
image = 4 photo = 4,
video = 5
} }
export class AutoCompleteItem { export class AutoCompleteItem {

View File

@ -55,10 +55,9 @@ ng2-slim-loading-bar {
} }
} }
.badge { .navbar-badge {
margin-left: -5px; border-radius: 1rem !important;
padding: 0; margin-left: -10px;
background-color: transparent;
} }
app-language { app-language {
@ -71,12 +70,16 @@ app-language {
} }
a.dropdown-item { a.dropdown-item {
padding:0.3rem 1.0rem 0.3rem 0.8rem; padding: 0.3rem 1.0rem 0.3rem 0.8rem;
} }
a.dropdown-item span{ a.dropdown-item span {
padding-right: 0.8rem; padding-right: 0.8rem;
} }
a.dropdown-item span.badge {
padding: 0.25em 0.4em 0.25rem 0;
margin-left: -0.8rem;
}

View File

@ -28,7 +28,7 @@
type="button" class="btn btn-dark dropdown-toggle" type="button" class="btn btn-dark dropdown-toggle"
aria-controls="dropdown-basic"> aria-controls="dropdown-basic">
<span class="oi oi-menu"></span> <span class="oi oi-menu"></span>
<span *ngIf="isAdmin() && notificationService.notifications.length>0" class="badge">{{notificationService.notifications.length}}</span> <span *ngIf="isAdmin() && notificationService.notifications.length>0" class="navbar-badge badge badge-warning">{{notificationService.notifications.length}}</span>
</button> </button>
<ul id="dropdown-basic" *dropdownMenu <ul id="dropdown-basic" *dropdownMenu

View File

@ -54,3 +54,7 @@ app-gallery-directory {
-webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg); -webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
} }
} }
.search-type{
margin-left: 5px;
}

View File

@ -8,7 +8,8 @@
: {{countDown.day}} : {{countDown.day}}
<ng-container i18n>days</ng-container> <ng-container i18n>days</ng-container>
, ,
{{("0"+countDown.hour).slice(-2)}}:{{("0"+countDown.minute).slice(-2)}}:{{("0"+countDown.second).slice(-2)}} {{("0" + countDown.hour).slice(-2)}}:{{("0" + countDown.minute).slice(-2)}}
:{{("0" + countDown.second).slice(-2)}}
</span> </span>
</li> </li>
<li class="nav-item" *ngIf="showSearchBar"> <li class="nav-item" *ngIf="showSearchBar">
@ -21,7 +22,7 @@
<ng-container navbar-menu> <ng-container navbar-menu>
<li role="menuitem" *ngIf="showRandomPhotoBuilder"> <li role="menuitem" *ngIf="showRandomPhotoBuilder">
<app-gallery-random-query-builder ></app-gallery-random-query-builder> <app-gallery-random-query-builder></app-gallery-random-query-builder>
</li> </li>
</ng-container> </ng-container>
@ -47,13 +48,14 @@
<ol class="breadcrumb"> <ol class="breadcrumb">
<li class="active"> <li class="active">
<ng-container i18n>Searching for:</ng-container> <ng-container i18n>Searching for:</ng-container>
<span [ngSwitch]="_galleryService.content.value.searchResult.searchType"> <span class="search-type" [ngSwitch]="_galleryService.content.value.searchResult.searchType">
<span *ngSwitchCase="SearchTypes.image" class="oi oi-image"></span> <span *ngSwitchCase="SearchTypes.photo" class="oi oi-image"></span>
<span *ngSwitchCase="SearchTypes.video" class="oi oi-video"></span>
<span *ngSwitchCase="SearchTypes.directory" class="oi oi-folder"></span> <span *ngSwitchCase="SearchTypes.directory" class="oi oi-folder"></span>
<span *ngSwitchCase="SearchTypes.keyword" class="oi oi-tag"></span> <span *ngSwitchCase="SearchTypes.keyword" class="oi oi-tag"></span>
<span *ngSwitchCase="SearchTypes.position" class="oi oi-map-marker"></span> <span *ngSwitchCase="SearchTypes.position" class="oi oi-map-marker"></span>
</span> </span>
<strong>{{_galleryService.content.value.searchResult.searchText}}</strong> <strong> {{_galleryService.content.value.searchResult.searchText}}</strong>
</li> </li>
</ol> </ol>

View File

@ -21,7 +21,8 @@
<div class="autocomplete-item" *ngFor="let item of autoCompleteItems"> <div class="autocomplete-item" *ngFor="let item of autoCompleteItems">
<a [routerLink]="['/search', item.text, {type: SearchTypes[item.type]}]"> <a [routerLink]="['/search', item.text, {type: SearchTypes[item.type]}]">
<span [ngSwitch]="item.type"> <span [ngSwitch]="item.type">
<span *ngSwitchCase="SearchTypes.image" class="oi oi-image"></span> <span *ngSwitchCase="SearchTypes.photo" class="oi oi-image"></span>
<span *ngSwitchCase="SearchTypes.video" class="oi oi-video"></span>
<span *ngSwitchCase="SearchTypes.directory" class="oi oi-folder"></span> <span *ngSwitchCase="SearchTypes.directory" class="oi oi-folder"></span>
<span *ngSwitchCase="SearchTypes.keyword" class="oi oi-tag"></span> <span *ngSwitchCase="SearchTypes.keyword" class="oi oi-tag"></span>
<span *ngSwitchCase="SearchTypes.position" class="oi oi-map-marker"></span> <span *ngSwitchCase="SearchTypes.position" class="oi oi-map-marker"></span>