mirror of
https://github.com/bpatrik/pigallery2.git
synced 2025-01-10 04:07:35 +02:00
This commit is contained in:
parent
70119241e1
commit
44978f8b53
@ -181,6 +181,8 @@ export class UserConfig {
|
||||
role: UserRoles = UserRoles.User;
|
||||
|
||||
@ConfigProperty<string, ServerConfig, TAGS>({
|
||||
type: 'string',
|
||||
constraint: {assert: (val: string, config) => !!val, assertReason: 'Password cant be empty'},
|
||||
tags:
|
||||
{
|
||||
name: $localize`Password`,
|
||||
|
@ -237,6 +237,14 @@ export class MapLayers {
|
||||
description: $localize`Url of a map layer.`,
|
||||
})
|
||||
url: string = '';
|
||||
@ConfigProperty({
|
||||
tags:
|
||||
{
|
||||
priority: ConfigPriority.advanced,
|
||||
},
|
||||
description: $localize`Sets if the layer is dark (used as default in the dark mode).`,
|
||||
})
|
||||
darkLayer: boolean = false;
|
||||
}
|
||||
|
||||
@SubConfigClass({tags: {client: true}, softReadonly: true})
|
||||
|
@ -91,15 +91,15 @@
|
||||
<div class="dropdown-item bg-transparent">
|
||||
<button class="btn w-100 btn-secondary" (click)="themeService.toggleMode()">
|
||||
<ng-container [ngSwitch]="themeService.mode">
|
||||
<ng-container *ngSwitchCase="ThemeMode.light">
|
||||
<ng-container *ngSwitchCase="ThemeModes.light">
|
||||
<span class="oi oi-sun"></span>
|
||||
<ng-container i18n>Light</ng-container>
|
||||
</ng-container>
|
||||
<ng-container *ngSwitchCase="ThemeMode.dark">
|
||||
<ng-container *ngSwitchCase="ThemeModes.dark">
|
||||
<span class="oi oi-moon"></span>
|
||||
<ng-container i18n>Dark</ng-container>
|
||||
</ng-container>
|
||||
<ng-container *ngSwitchCase="ThemeMode.auto">
|
||||
<ng-container *ngSwitchCase="ThemeModes.auto">
|
||||
<span class="oi oi-moon"></span>
|
||||
<span class="oi oi-sun" style="margin-left: -0.8rem"></span>
|
||||
<ng-container i18n>Auto</ng-container>
|
||||
|
@ -6,13 +6,13 @@ 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 {NavigationLinkTypes, ThemeModes} from '../../../../common/config/public/ClientConfig';
|
||||
import {SearchQueryDTO} from '../../../../common/entities/SearchQueryDTO';
|
||||
import {Utils} from '../../../../common/Utils';
|
||||
import {PageHelper} from '../../model/page.helper';
|
||||
import {BsDropdownDirective} from 'ngx-bootstrap/dropdown';
|
||||
import {LanguageComponent} from '../language/language.component';
|
||||
import {ThemeMode, ThemeService} from '../../model/theme.service';
|
||||
import {ThemeService} from '../../model/theme.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-frame',
|
||||
@ -46,7 +46,7 @@ export class FrameComponent {
|
||||
@ViewChild('dropdown', {static: true}) dropdown: BsDropdownDirective;
|
||||
@ViewChild('languageSelector', {static: true}) languageSelector: LanguageComponent;
|
||||
|
||||
ThemeMode = ThemeMode;
|
||||
ThemeModes = ThemeModes;
|
||||
|
||||
constructor(
|
||||
private authService: AuthenticationService,
|
||||
|
@ -10,6 +10,7 @@ import {SearchQueryTypes, TextSearch, TextSearchQueryMatchTypes,} from '../../..
|
||||
import {AuthenticationService} from '../../../../model/network/authentication.service';
|
||||
import {LatLngLiteral, marker, Marker, TileLayer, tileLayer} from 'leaflet';
|
||||
import {ContentService} from '../../content.service';
|
||||
import {ThemeService} from '../../../../model/theme.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-info-panel',
|
||||
@ -32,13 +33,20 @@ export class InfoPanelLightboxComponent implements OnInit, OnChanges {
|
||||
public queryService: QueryService,
|
||||
public galleryService: ContentService,
|
||||
public mapService: MapService,
|
||||
private authService: AuthenticationService
|
||||
private authService: AuthenticationService,
|
||||
private themeService: ThemeService
|
||||
) {
|
||||
this.mapEnabled = Config.Map.enabled;
|
||||
this.searchEnabled = this.authService.canSearch();
|
||||
this.baseLayer = tileLayer(mapService.MapLayer, {
|
||||
attribution: mapService.ShortAttributions,
|
||||
});
|
||||
if (this.themeService.darkMode.value) {
|
||||
this.baseLayer = tileLayer(mapService.DarkMapLayer.url, {
|
||||
attribution: mapService.ShortAttributions,
|
||||
});
|
||||
} else {
|
||||
this.baseLayer = tileLayer(mapService.MapLayer.url, {
|
||||
attribution: mapService.ShortAttributions,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
get FullPath(): string {
|
||||
|
@ -1,20 +1,8 @@
|
||||
import {
|
||||
Component,
|
||||
ElementRef,
|
||||
HostListener,
|
||||
Input,
|
||||
OnChanges,
|
||||
ViewChild,
|
||||
} from '@angular/core';
|
||||
import {Component, ElementRef, HostListener, Input, OnChanges, ViewChild,} from '@angular/core';
|
||||
import {PhotoDTO} from '../../../../../../common/entities/PhotoDTO';
|
||||
import {Dimension} from '../../../../model/IRenderable';
|
||||
import {FullScreenService} from '../../fullscreen.service';
|
||||
import {
|
||||
IconThumbnail,
|
||||
Thumbnail,
|
||||
ThumbnailBase,
|
||||
ThumbnailManagerService,
|
||||
} from '../../thumbnailManager.service';
|
||||
import {IconThumbnail, Thumbnail, ThumbnailBase, ThumbnailManagerService,} from '../../thumbnailManager.service';
|
||||
import {MediaIcon} from '../../MediaIcon';
|
||||
import {Media} from '../../Media';
|
||||
import {PageHelper} from '../../../../model/page.helper';
|
||||
@ -40,8 +28,10 @@ import {
|
||||
Point,
|
||||
polyline,
|
||||
tileLayer,
|
||||
TileLayer
|
||||
} from 'leaflet';
|
||||
import {LeafletControlLayersConfig} from '@asymmetrik/ngx-leaflet';
|
||||
import {ThemeService} from '../../../../model/theme.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-gallery-map-lightbox',
|
||||
@ -73,6 +63,8 @@ export class GalleryMapLightboxComponent implements OnChanges {
|
||||
maxZoom: 2,
|
||||
center: latLng(0, 0),
|
||||
};
|
||||
defLayer: TileLayer;
|
||||
darkLayer: TileLayer;
|
||||
private smallIconSize = new Point(
|
||||
Config.Media.Thumbnail.iconSize * 0.75,
|
||||
Config.Media.Thumbnail.iconSize * 0.75
|
||||
@ -122,7 +114,8 @@ export class GalleryMapLightboxComponent implements OnChanges {
|
||||
constructor(
|
||||
public fullScreenService: FullScreenService,
|
||||
private thumbnailService: ThumbnailManagerService,
|
||||
public mapService: MapService
|
||||
public mapService: MapService,
|
||||
private themeService: ThemeService
|
||||
) {
|
||||
this.mapOptions.layers = [
|
||||
this.mapLayersControlOption.overlays.Photos,
|
||||
@ -131,19 +124,43 @@ export class GalleryMapLightboxComponent implements OnChanges {
|
||||
for (let i = 0; i < mapService.Layers.length; ++i) {
|
||||
const l = mapService.Layers[i];
|
||||
const tl = tileLayer(l.url, {attribution: mapService.Attributions});
|
||||
if (i === 0) {
|
||||
this.mapOptions.layers.push(tl);
|
||||
if (l.url === mapService.MapLayer.url) {
|
||||
this.defLayer = tl;
|
||||
}
|
||||
if (l.url === mapService.DarkMapLayer.url) {
|
||||
this.darkLayer = tl;
|
||||
}
|
||||
this.mapLayersControlOption.baseLayers[l.name] = tl;
|
||||
}
|
||||
if (!this.defLayer || !this.darkLayer) {
|
||||
throw new Error('Cant find default or dark layer');
|
||||
}
|
||||
this.mapOptions.layers.push(this.themeService.darkMode.value ? this.darkLayer : this.defLayer);
|
||||
|
||||
this.mapLayerControl = control.layers(
|
||||
this.mapLayersControlOption.baseLayers,
|
||||
this.mapLayersControlOption.overlays,
|
||||
{position: 'bottomright'}
|
||||
);
|
||||
|
||||
// update map theme on dark theme
|
||||
this.themeService.darkMode.subscribe(this.selectBaseLayer);
|
||||
}
|
||||
|
||||
private selectBaseLayer = () => {
|
||||
if (!this.leafletMap) {
|
||||
return;
|
||||
}
|
||||
if (this.leafletMap.hasLayer(this.defLayer) && this.themeService.darkMode.value) {
|
||||
this.leafletMap.removeLayer(this.defLayer);
|
||||
this.leafletMap.addLayer(this.darkLayer);
|
||||
}
|
||||
if (this.leafletMap.hasLayer(this.darkLayer) && !this.themeService.darkMode.value) {
|
||||
this.leafletMap.removeLayer(this.darkLayer);
|
||||
this.leafletMap.addLayer(this.defLayer);
|
||||
}
|
||||
};
|
||||
|
||||
private static getScreenWidth(): number {
|
||||
return window.innerWidth;
|
||||
}
|
||||
|
@ -1,24 +1,12 @@
|
||||
import {
|
||||
Component,
|
||||
ElementRef,
|
||||
Input,
|
||||
OnChanges,
|
||||
ViewChild,
|
||||
} from '@angular/core';
|
||||
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 { MapService } from './map.service';
|
||||
import { Config } from '../../../../../common/config/public/Config';
|
||||
import {
|
||||
LatLngLiteral,
|
||||
Map,
|
||||
MapOptions,
|
||||
Marker,
|
||||
marker,
|
||||
tileLayer,
|
||||
} from 'leaflet';
|
||||
import {Component, ElementRef, Input, OnChanges, ViewChild,} from '@angular/core';
|
||||
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 {MapService} from './map.service';
|
||||
import {Config} from '../../../../../common/config/public/Config';
|
||||
import {LatLngLiteral, Map, MapOptions, Marker, marker, tileLayer, TileLayer} from 'leaflet';
|
||||
import {ThemeService} from '../../../model/theme.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-gallery-map',
|
||||
@ -28,11 +16,12 @@ import {
|
||||
export class GalleryMapComponent implements OnChanges, IRenderable {
|
||||
@Input() photos: PhotoDTO[];
|
||||
@Input() gpxFiles: FileDTO[];
|
||||
@ViewChild(GalleryMapLightboxComponent, { static: false })
|
||||
@ViewChild(GalleryMapLightboxComponent, {static: false})
|
||||
mapLightbox: GalleryMapLightboxComponent;
|
||||
@ViewChild('map', { static: false }) mapElement: ElementRef;
|
||||
@ViewChild('map', {static: false}) mapElement: ElementRef;
|
||||
|
||||
leafletMap: Map;
|
||||
layers: { light: TileLayer, dark: TileLayer };
|
||||
|
||||
options: MapOptions = {
|
||||
zoomControl: false,
|
||||
@ -46,12 +35,46 @@ export class GalleryMapComponent implements OnChanges, IRenderable {
|
||||
};
|
||||
markerLayer: Marker[] = [];
|
||||
|
||||
constructor(public mapService: MapService) {
|
||||
this.options.layers = [
|
||||
tileLayer(mapService.MapLayer, {
|
||||
attribution: mapService.ShortAttributions,
|
||||
constructor(public mapService: MapService,
|
||||
private themeService: ThemeService) {
|
||||
this.initThemeModes();
|
||||
}
|
||||
|
||||
initThemeModes() {
|
||||
this.layers = {
|
||||
'light': tileLayer(this.mapService.MapLayer.url, {
|
||||
attribution: this.mapService.ShortAttributions,
|
||||
}),
|
||||
];
|
||||
'dark':
|
||||
tileLayer(this.mapService.DarkMapLayer.url, {
|
||||
attribution: this.mapService.ShortAttributions,
|
||||
})
|
||||
};
|
||||
if (this.themeService.darkMode.value) {
|
||||
this.options.layers = [this.layers.dark];
|
||||
} else {
|
||||
this.options.layers = [this.layers.light];
|
||||
}
|
||||
// update map theme on dark theme
|
||||
this.themeService.darkMode.subscribe((isDark) => {
|
||||
if (!this.leafletMap) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isDark) {
|
||||
if (this.leafletMap.hasLayer(this.layers.dark)) {
|
||||
return;
|
||||
}
|
||||
this.leafletMap.removeLayer(this.layers.light);
|
||||
this.leafletMap.addLayer(this.layers.dark);
|
||||
} else {
|
||||
if (this.leafletMap.hasLayer(this.layers.light)) {
|
||||
return;
|
||||
}
|
||||
this.leafletMap.removeLayer(this.layers.dark);
|
||||
this.leafletMap.addLayer(this.layers.light);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onMapReady(map: Map): void {
|
||||
|
@ -3,18 +3,16 @@ 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 {
|
||||
MapLayers,
|
||||
MapProviders,
|
||||
} from '../../../../../common/config/public/ClientConfig';
|
||||
import {MapLayers, MapProviders,} from '../../../../../common/config/public/ClientConfig';
|
||||
import {LatLngLiteral} from 'leaflet';
|
||||
|
||||
@Injectable()
|
||||
export class MapService {
|
||||
private static readonly OSMLAYERS = [
|
||||
private static readonly OSMLAYERS: MapLayers[] = [
|
||||
{
|
||||
name: 'street',
|
||||
url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||||
darkLayer: false
|
||||
},
|
||||
];
|
||||
private static MAPBOXLAYERS: MapLayers[] = [];
|
||||
@ -22,22 +20,32 @@ export class MapService {
|
||||
constructor(private networkService: NetworkService) {
|
||||
MapService.MAPBOXLAYERS = [
|
||||
{
|
||||
name: 'street',
|
||||
name: $localize`street`,
|
||||
url:
|
||||
'https://api.mapbox.com/styles/v1/mapbox/streets-v11/tiles/256/{z}/{x}/{y}?access_token=' +
|
||||
'https://api.mapbox.com/styles/v1/mapbox/streets-v12/tiles/256/{z}/{x}/{y}?access_token=' +
|
||||
Config.Map.mapboxAccessToken,
|
||||
darkLayer: false
|
||||
},
|
||||
{
|
||||
name: 'satellite',
|
||||
name: $localize`satellite`,
|
||||
url:
|
||||
'https://api.mapbox.com/styles/v1/mapbox/satellite-v9/tiles/256/{z}/{x}/{y}?access_token=' +
|
||||
Config.Map.mapboxAccessToken,
|
||||
darkLayer: false
|
||||
},
|
||||
{
|
||||
name: 'hybrid',
|
||||
name: $localize`hybrid`,
|
||||
url:
|
||||
'https://api.mapbox.com/styles/v1/mapbox/satellite-streets-v11/tiles/256/{z}/{x}/{y}?access_token=' +
|
||||
'https://api.mapbox.com/styles/v1/mapbox/satellite-streets-v12/tiles/256/{z}/{x}/{y}?access_token=' +
|
||||
Config.Map.mapboxAccessToken,
|
||||
darkLayer: false
|
||||
},
|
||||
{
|
||||
name: $localize`dark`,
|
||||
url:
|
||||
'https://api.mapbox.com/styles/v1/mapbox/navigation-night-v1/tiles/256/{z}/{x}/{y}?access_token=' +
|
||||
Config.Map.mapboxAccessToken,
|
||||
darkLayer: true
|
||||
},
|
||||
];
|
||||
}
|
||||
@ -71,11 +79,15 @@ export class MapService {
|
||||
return '';
|
||||
}
|
||||
|
||||
public get MapLayer(): string {
|
||||
return this.Layers[0].url;
|
||||
public get MapLayer(): MapLayers {
|
||||
return (this.Layers.find(ml => !ml.darkLayer) || this.Layers[0]);
|
||||
}
|
||||
|
||||
public get Layers(): { name: string; url: string }[] {
|
||||
public get DarkMapLayer(): MapLayers {
|
||||
return (this.Layers.find(ml => ml.darkLayer) || this.MapLayer);
|
||||
}
|
||||
|
||||
public get Layers(): MapLayers[] {
|
||||
switch (Config.Map.mapProvider) {
|
||||
case MapProviders.Custom:
|
||||
return Config.Map.customLayers;
|
||||
|
@ -203,7 +203,7 @@ export class TemplateComponent implements OnInit, OnChanges, OnDestroy, ISetting
|
||||
}
|
||||
|
||||
|
||||
return ( !forcedVisibility &&
|
||||
return (!forcedVisibility &&
|
||||
Utils.equalsFilter(state.value, state.default,
|
||||
['__propPath', '__created', '__prototype', '__rootConfig']) &&
|
||||
Utils.equalsFilter(state.original, state.default,
|
||||
@ -316,6 +316,11 @@ export class TemplateComponent implements OnInit, OnChanges, OnDestroy, ISetting
|
||||
return s[a].tags?.priority - s[b].tags?.priority;
|
||||
}
|
||||
|
||||
if (a === 'enabled' && b !== 'enabled') {
|
||||
return -1;
|
||||
} else if (b === 'enabled') {
|
||||
return 1;
|
||||
}
|
||||
return (s[a].tags?.name as string || a).localeCompare(s[b].tags?.name || b);
|
||||
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user