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

Creating config for navbar buttons #174 #435, fixes #150

This commit is contained in:
Patrik J. Braun 2022-12-11 00:24:20 +01:00
parent d209816619
commit d65685e592
7 changed files with 120 additions and 60 deletions

4
package-lock.json generated
View File

@ -1,12 +1,12 @@
{ {
"name": "pigallery2", "name": "pigallery2",
"version": "1.9.4", "version": "1.9.4-nightly",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "pigallery2", "name": "pigallery2",
"version": "1.9.4", "version": "1.9.4-nightly",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"archiver": "5.3.1", "archiver": "5.3.1",

View File

@ -4,6 +4,7 @@ import {SortingMethods} from '../../entities/SortingMethods';
import {UserRoles} from '../../entities/UserDTO'; import {UserRoles} from '../../entities/UserDTO';
import {ConfigProperty, SubConfigClass} from 'typeconfig/common'; import {ConfigProperty, SubConfigClass} from 'typeconfig/common';
import {IPrivateConfig} from '../private/PrivateConfig'; import {IPrivateConfig} from '../private/PrivateConfig';
import {FromDateSearch, SearchQueryDTO, SearchQueryTypes, TextSearch} from '../../entities/SearchQueryDTO';
export enum MapProviders { export enum MapProviders {
OpenStreetMap = 1, OpenStreetMap = 1,
@ -130,10 +131,42 @@ export class ClientThumbnailConfig {
} }
} }
export enum NavigationLinkTypes {
gallery = 1, faces, albums, search, url
}
@SubConfigClass()
export class NavigationLinkConfig {
@ConfigProperty({type: NavigationLinkTypes})
type: NavigationLinkTypes = NavigationLinkTypes.gallery;
@ConfigProperty({type: 'string'})
name?: string;
@ConfigProperty({type: 'object'})
SearchQuery?: SearchQueryDTO;
@ConfigProperty({type: 'string'})
url?: string;
constructor(type: NavigationLinkTypes = NavigationLinkTypes.gallery,
name?: string, SearchQuery?: SearchQueryDTO, url?: string) {
this.type = type;
this.name = name;
this.SearchQuery = SearchQuery;
this.url = url;
}
}
@SubConfigClass() @SubConfigClass()
export class NavBarConfig { export class NavBarConfig {
@ConfigProperty() @ConfigProperty()
showItemCount: boolean = true; showItemCount: boolean = true;
@ConfigProperty({arrayType: NavigationLinkConfig, description: 'List of the navigation bar links'})
links: NavigationLinkConfig[] = [
new NavigationLinkConfig(NavigationLinkTypes.gallery),
new NavigationLinkConfig(NavigationLinkTypes.albums),
new NavigationLinkConfig(NavigationLinkTypes.faces),
];
} }
@SubConfigClass() @SubConfigClass()

View File

@ -7,6 +7,7 @@ import { ShareService } from './ui/gallery/share.service';
import 'hammerjs'; import 'hammerjs';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { QueryParams } from '../../common/QueryParams'; import { QueryParams } from '../../common/QueryParams';
import {NavigationService} from './model/navigation.service';
@Component({ @Component({
selector: 'app-pi-gallery2', selector: 'app-pi-gallery2',
@ -19,6 +20,7 @@ export class AppComponent implements OnInit, OnDestroy {
private router: Router, private router: Router,
private authenticationService: AuthenticationService, private authenticationService: AuthenticationService,
private shareService: ShareService, private shareService: ShareService,
private navigation: NavigationService,
private title: Title private title: Title
) {} ) {}
@ -27,12 +29,12 @@ export class AppComponent implements OnInit, OnDestroy {
await this.shareService.wait(); await this.shareService.wait();
this.subscription = this.authenticationService.user.subscribe(() => { this.subscription = this.authenticationService.user.subscribe(() => {
if (this.authenticationService.isAuthenticated()) { if (this.authenticationService.isAuthenticated()) {
if (this.isLoginPage()) { if (this.navigation.isLoginPage()) {
return this.toGallery(); return this.navigation.toDefault();
} }
} else { } else {
if (!this.isLoginPage()) { if (!this.navigation.isLoginPage()) {
return this.toLogin(); return this.navigation.toLogin();
} }
} }
}); });
@ -44,33 +46,4 @@ export class AppComponent implements OnInit, OnDestroy {
} }
} }
private isLoginPage(): boolean {
return (
this.router.isActive('login', true) ||
this.router.isActive('shareLogin', false)
);
}
private async toLogin(): Promise<void> {
if (this.shareService.isSharing()) {
const q: any = {};
q[QueryParams.gallery.sharingKey_query] =
this.shareService.getSharingKey();
await this.router.navigate(['shareLogin'], { queryParams: q });
return;
} else {
await this.router.navigate(['login']);
return;
}
}
private async toGallery(): Promise<void> {
if (this.shareService.isSharing()) {
await this.router.navigate(['share', this.shareService.getSharingKey()]);
return;
} else {
await this.router.navigate(['gallery', '']);
return;
}
}
} }

View File

@ -2,10 +2,13 @@ import { Injectable } from '@angular/core';
import {Router} from '@angular/router'; import {Router} from '@angular/router';
import {ShareService} from '../ui/gallery/share.service'; import {ShareService} from '../ui/gallery/share.service';
import {Config} from '../../../common/config/public/Config';
import {NavigationLinkTypes} from '../../../common/config/public/ClientConfig';
@Injectable() @Injectable()
export class NavigationService { export class NavigationService {
constructor(private router: Router, private shareService: ShareService) {} constructor(private router: Router, private shareService: ShareService) {
}
public isLoginPage(): boolean { public isLoginPage(): boolean {
return ( return (
@ -25,7 +28,30 @@ export class NavigationService {
} }
} }
public async toDefault(): Promise<boolean> {
await this.shareService.wait();
if (this.shareService.isSharing()) {
return this.router.navigate(['share', this.shareService.getSharingKey()]);
} else {
if (Config.Client.Other.NavBar.links && Config.Client.Other.NavBar.links.length > 0) {
switch (Config.Client.Other.NavBar.links[0].type) {
case NavigationLinkTypes.gallery:
return this.router.navigate(['gallery', '']);
case NavigationLinkTypes.albums:
return this.router.navigate(['albums', '']);
case NavigationLinkTypes.faces:
return this.router.navigate(['faces', '']);
case NavigationLinkTypes.search:
return this.router.navigate(['search', JSON.stringify(Config.Client.Other.NavBar.links[0].SearchQuery)]);
}
}
return this.router.navigate(['gallery', '']);
}
}
public async toGallery(): Promise<boolean> { public async toGallery(): Promise<boolean> {
console.log('toGallery');
await this.shareService.wait(); await this.shareService.wait();
if (this.shareService.isSharing()) { if (this.shareService.isSharing()) {
return this.router.navigate(['share', this.shareService.getSharingKey()]); return this.router.navigate(['share', this.shareService.getSharingKey()]);

View File

@ -13,17 +13,25 @@
</button> </button>
<div class="collapse navbar-collapse text-center" id="navbarCollapse" [collapse]="collapsed"> <div class="collapse navbar-collapse text-center" id="navbarCollapse" [collapse]="collapsed">
<ul class="navbar-nav me-auto mb-2 mb-md-0 text-lg-start"> <ul class="navbar-nav me-auto mb-2 mb-md-0 text-lg-start">
<li class="nav-item"> <ng-container *ngFor="let link of navbarLinks">
<li class="nav-item" *ngIf="link.type === NavigationLinkTypes.albums && isAlbumsAvailable()">
<a class="nav-link" [routerLink]="['/albums']" [class.active]="isLinkActive('/albums')" i18n>Albums</a>
</li>
<li class="nav-item" *ngIf="link.type === NavigationLinkTypes.faces && isFacesAvailable()">
<a class="nav-link" [routerLink]="['/faces']" [class.active]="isLinkActive('/faces')" i18n>Faces</a>
</li>
<li class="nav-item" *ngIf="link.type === NavigationLinkTypes.gallery">
<a class="nav-link" <a class="nav-link"
[routerLink]="['/gallery']" [routerLink]="['/gallery']"
[queryParams]="queryService.getParams()" [class.active]="isLinkActive('/gallery')" i18n>Gallery</a> [queryParams]="queryService.getParams()" [class.active]="isLinkActive('/gallery')" i18n>Gallery</a>
</li> </li>
<li class="nav-item" *ngIf="isAlbumsAvailable()"> <li class="nav-item" *ngIf="link.type === NavigationLinkTypes.url">
<a class="nav-link" [routerLink]="['/albums']" [class.active]="isLinkActive('/albums')" i18n>Albums</a> <a class="nav-link" [href]="link.url" [class.active]="isLinkActive(link.url)">{{link.name}}</a>
</li> </li>
<li class="nav-item" *ngIf="isFacesAvailable()"> <li class="nav-item" *ngIf="link.type === NavigationLinkTypes.search">
<a class="nav-link" [routerLink]="['/faces']" [class.active]="isLinkActive('/faces')" i18n>Faces</a> <a class="nav-link" [routerLink]="['/search', link.SearchQuery | json]" [class.active]="isSearchActive(link.SearchQuery)">{{link.name}}</a>
</li> </li>
</ng-container>
</ul> </ul>
<div class="text-lg-end"> <div class="text-lg-end">
<ul class="navbar-nav"> <ul class="navbar-nav">

View File

@ -6,6 +6,9 @@ import { Config } from '../../../../common/config/public/Config';
import {BehaviorSubject} from 'rxjs'; import {BehaviorSubject} from 'rxjs';
import {NotificationService} from '../../model/notification.service'; import {NotificationService} from '../../model/notification.service';
import {QueryService} from '../../model/query.service'; import {QueryService} from '../../model/query.service';
import {NavigationLinkTypes} from '../../../../common/config/public/ClientConfig';
import {SearchQueryDTO} from '../../../../common/entities/SearchQueryDTO';
import {Utils} from '../../../../common/Utils';
@Component({ @Component({
selector: 'app-frame', selector: 'app-frame',
@ -19,6 +22,9 @@ export class FrameComponent {
public readonly authenticationRequired = Config.Client.authenticationRequired; public readonly authenticationRequired = Config.Client.authenticationRequired;
public readonly title = Config.Client.applicationTitle; public readonly title = Config.Client.applicationTitle;
public collapsed = true; public collapsed = true;
public readonly navbarLinks = Config.Client.Other.NavBar.links;
public readonly NavigationLinkTypes = NavigationLinkTypes;
public readonly stringify = JSON.stringify;
constructor( constructor(
private authService: AuthenticationService, private authService: AuthenticationService,
@ -45,6 +51,20 @@ export class FrameComponent {
return this.router.url.startsWith(url); return this.router.url.startsWith(url);
} }
isSearchActive(searchQuery: SearchQueryDTO): boolean {
if (!this.router.url.startsWith('/search')) {
return false;
}
try {
const rawUrl = this.router.url.substring('/search/'.length);
const sq = JSON.parse(decodeURIComponent(rawUrl)) as SearchQueryDTO;
return sq.type == searchQuery.type && Utils.equalsFilter(sq, searchQuery);
} catch (e) {
// ignored
}
return false;
}
logout(): void { logout(): void {
this.authService.logout(); this.authService.logout();
} }

View File

@ -26,7 +26,7 @@ export class LoginComponent implements OnInit {
ngOnInit(): void { ngOnInit(): void {
if (this.authService.isAuthenticated()) { if (this.authService.isAuthenticated()) {
this.navigation.toGallery(); this.navigation.toDefault();
} }
} }