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",
"version": "1.9.4",
"version": "1.9.4-nightly",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "pigallery2",
"version": "1.9.4",
"version": "1.9.4-nightly",
"license": "MIT",
"dependencies": {
"archiver": "5.3.1",

View File

@ -4,6 +4,7 @@ import {SortingMethods} from '../../entities/SortingMethods';
import {UserRoles} from '../../entities/UserDTO';
import {ConfigProperty, SubConfigClass} from 'typeconfig/common';
import {IPrivateConfig} from '../private/PrivateConfig';
import {FromDateSearch, SearchQueryDTO, SearchQueryTypes, TextSearch} from '../../entities/SearchQueryDTO';
export enum MapProviders {
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()
export class NavBarConfig {
@ConfigProperty()
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()

View File

@ -7,6 +7,7 @@ import { ShareService } from './ui/gallery/share.service';
import 'hammerjs';
import { Subscription } from 'rxjs';
import { QueryParams } from '../../common/QueryParams';
import {NavigationService} from './model/navigation.service';
@Component({
selector: 'app-pi-gallery2',
@ -19,6 +20,7 @@ export class AppComponent implements OnInit, OnDestroy {
private router: Router,
private authenticationService: AuthenticationService,
private shareService: ShareService,
private navigation: NavigationService,
private title: Title
) {}
@ -27,12 +29,12 @@ export class AppComponent implements OnInit, OnDestroy {
await this.shareService.wait();
this.subscription = this.authenticationService.user.subscribe(() => {
if (this.authenticationService.isAuthenticated()) {
if (this.isLoginPage()) {
return this.toGallery();
if (this.navigation.isLoginPage()) {
return this.navigation.toDefault();
}
} else {
if (!this.isLoginPage()) {
return this.toLogin();
if (!this.navigation.isLoginPage()) {
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

@ -1,11 +1,14 @@
import { Injectable } from '@angular/core';
import {Injectable} from '@angular/core';
import { Router } from '@angular/router';
import { ShareService } from '../ui/gallery/share.service';
import {Router} from '@angular/router';
import {ShareService} from '../ui/gallery/share.service';
import {Config} from '../../../common/config/public/Config';
import {NavigationLinkTypes} from '../../../common/config/public/ClientConfig';
@Injectable()
export class NavigationService {
constructor(private router: Router, private shareService: ShareService) {}
constructor(private router: Router, private shareService: ShareService) {
}
public isLoginPage(): boolean {
return (
@ -18,14 +21,37 @@ export class NavigationService {
await this.shareService.wait();
if (this.shareService.isSharing()) {
return this.router.navigate(['shareLogin'], {
queryParams: { sk: this.shareService.getSharingKey() },
queryParams: {sk: this.shareService.getSharingKey()},
});
} else {
return this.router.navigate(['login']);
}
}
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> {
console.log('toGallery');
await this.shareService.wait();
if (this.shareService.isSharing()) {
return this.router.navigate(['share', this.shareService.getSharingKey()]);

View File

@ -13,17 +13,25 @@
</button>
<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">
<li class="nav-item">
<a class="nav-link"
[routerLink]="['/gallery']"
[queryParams]="queryService.getParams()" [class.active]="isLinkActive('/gallery')" i18n>Gallery</a>
</li>
<li class="nav-item" *ngIf="isAlbumsAvailable()">
<a class="nav-link" [routerLink]="['/albums']" [class.active]="isLinkActive('/albums')" i18n>Albums</a>
</li>
<li class="nav-item" *ngIf="isFacesAvailable()">
<a class="nav-link" [routerLink]="['/faces']" [class.active]="isLinkActive('/faces')" i18n>Faces</a>
</li>
<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"
[routerLink]="['/gallery']"
[queryParams]="queryService.getParams()" [class.active]="isLinkActive('/gallery')" i18n>Gallery</a>
</li>
<li class="nav-item" *ngIf="link.type === NavigationLinkTypes.url">
<a class="nav-link" [href]="link.url" [class.active]="isLinkActive(link.url)">{{link.name}}</a>
</li>
<li class="nav-item" *ngIf="link.type === NavigationLinkTypes.search">
<a class="nav-link" [routerLink]="['/search', link.SearchQuery | json]" [class.active]="isSearchActive(link.SearchQuery)">{{link.name}}</a>
</li>
</ng-container>
</ul>
<div class="text-lg-end">
<ul class="navbar-nav">

View File

@ -1,11 +1,14 @@
import { Component, ViewEncapsulation } from '@angular/core';
import { Router, 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 { BehaviorSubject } from 'rxjs';
import { NotificationService } from '../../model/notification.service';
import { QueryService } from '../../model/query.service';
import {Component, ViewEncapsulation} from '@angular/core';
import {Router, 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 {BehaviorSubject} from 'rxjs';
import {NotificationService} from '../../model/notification.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({
selector: 'app-frame',
@ -19,6 +22,9 @@ export class FrameComponent {
public readonly authenticationRequired = Config.Client.authenticationRequired;
public readonly title = Config.Client.applicationTitle;
public collapsed = true;
public readonly navbarLinks = Config.Client.Other.NavBar.links;
public readonly NavigationLinkTypes = NavigationLinkTypes;
public readonly stringify = JSON.stringify;
constructor(
private authService: AuthenticationService,
@ -45,6 +51,20 @@ export class FrameComponent {
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 {
this.authService.logout();
}

View File

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