diff --git a/ui/src/app/app.component.html b/ui/src/app/app.component.html index 37c00e4..fa2b788 100644 --- a/ui/src/app/app.component.html +++ b/ui/src/app/app.component.html @@ -4,7 +4,7 @@ MeshCenter -

{{userNode.long_name}} ({{userNode.num}}) snr: {{userNode.snr}}

+

{{(isHandset | async) ? (userNode.short_name) : (userNode.long_name + ' ' + userNode.num + ' ' + userNode.snr)}}

diff --git a/ui/src/app/app.component.ts b/ui/src/app/app.component.ts index 37f630d..95e1aa1 100644 --- a/ui/src/app/app.component.ts +++ b/ui/src/app/app.component.ts @@ -2,6 +2,8 @@ import {Component, OnInit} from '@angular/core'; import {Route, Router} from "@angular/router"; import {NodeDTO} from "./entities/NodeDTO"; import {HttpClient} from "@angular/common/http"; +import {map, Observable} from "rxjs"; +import {BreakpointObserver, Breakpoints} from "@angular/cdk/layout"; @Component({ selector: 'app-root', @@ -10,9 +12,15 @@ import {HttpClient} from "@angular/common/http"; }) export class AppComponent implements OnInit { constructor(private route: Router, - private http: HttpClient) { + private http: HttpClient, + private breakpointObserver: BreakpointObserver) { } + + isHandset: Observable = this.breakpointObserver + .observe([Breakpoints.Handset]) + .pipe(map(result => result.matches)); + ngOnInit() { this.http.get(`api/auth/me`).subscribe( (res) => this.userNode = res as NodeDTO diff --git a/ui/src/app/auth/AuthInterceptor.ts b/ui/src/app/auth/AuthInterceptor.ts index 1e4e14c..f25c4e2 100644 --- a/ui/src/app/auth/AuthInterceptor.ts +++ b/ui/src/app/auth/AuthInterceptor.ts @@ -7,12 +7,13 @@ import { HttpRequest } from "@angular/common/http"; import {Component, Injectable, OnInit, ViewContainerRef} from "@angular/core"; -import {catchError, Observable, startWith, throwError} from "rxjs"; +import {catchError, map, Observable, startWith, throwError} from "rxjs"; import {MatDialog, MatDialogRef} from "@angular/material/dialog"; import {FormControl} from "@angular/forms"; import {NodeMiniDTO} from "../entities/NodeMiniDTO"; import {MatSnackBar} from "@angular/material/snack-bar"; import {D} from "@angular/cdk/keycodes"; +import {BreakpointObserver, Breakpoints} from "@angular/cdk/layout"; @Component({ @@ -124,7 +125,7 @@ export class AuthInterceptor implements HttpInterceptor { catchError((error: HttpErrorResponse) => { if (error.status === 401 && !this.dialogOpened) { this.dialogOpened = true; - const ref = this.dialog.open(AuthDialog, {disableClose: true, width:"30%"}) + const ref = this.dialog.open(AuthDialog, {disableClose: true, panelClass:"width-vw"}) ref.afterClosed().subscribe((res:any) => this.dialogOpened = false) } return throwError(() => error); diff --git a/ui/src/app/components/nodes/nodes-map.component.ts b/ui/src/app/components/nodes/nodes-map.component.ts index 6115605..38791f1 100644 --- a/ui/src/app/components/nodes/nodes-map.component.ts +++ b/ui/src/app/components/nodes/nodes-map.component.ts @@ -4,6 +4,7 @@ import {HttpClient} from "@angular/common/http"; import {NodeDTO} from "../../entities/NodeDTO"; import {Subscription} from "rxjs"; import {DatePipe} from "@angular/common"; +import {numToColor} from "../../utils/Utils"; @Component({ selector: "app-nodes-map", @@ -26,6 +27,8 @@ export class NodesMapComponent implements OnInit { }) nodes: NodeDTO[] = [] + numToColor = numToColor; + constructor(private http: HttpClient, private datepipe: DatePipe) { } @@ -42,7 +45,13 @@ export class NodesMapComponent implements OnInit { () => { this.nodes.filter((node) => node.havePosition).forEach( (node) => { - L.marker(this.convertPosition(node), {icon: this.logo}).bindPopup(`${node.long_name} (${node.short_name})

snr: ${node.snr} hops: ${node.hops_away}

Изменена: ${this.datepipe.transform(node.position.time*1000, 'HH:mm dd.MM.yyyy')}

`).addTo(this.map) + L.marker(this.convertPosition(node), { + icon: this.createCircleIcon({ + color: this.numToColor(node.num, 0), + text: node.short_name}) + }) + .bindPopup(`${node.long_name} (${node.short_name})

snr: ${node.snr} hops: ${node.hops_away}

Изменена: ${this.datepipe.transform(node.position.time*1000, 'HH:mm dd.MM.yyyy')}

`) + .addTo(this.map) } ) } @@ -72,4 +81,24 @@ export class NodesMapComponent implements OnInit { tiles.addTo(this.map) return Subscription.EMPTY; } + + private createCircleIcon(options: { color: string; text: string; size?: number }): L.DivIcon { + const size = options.size || 24; + const html = ` +
${options.text}
+ `; + return L.divIcon({ html, iconSize: [size, size], className: 'l-div-icon' }); + } } diff --git a/ui/src/app/components/nodes/nodes.styles.scss b/ui/src/app/components/nodes/nodes.styles.scss index d2db7ba..d17c657 100644 --- a/ui/src/app/components/nodes/nodes.styles.scss +++ b/ui/src/app/components/nodes/nodes.styles.scss @@ -19,3 +19,8 @@ :host ::ng-deep .leaflet-control-attribution { display: none; } + +.l-div-icon { + border: unset; + background: unset; +} diff --git a/ui/src/app/components/packet/NetworkStatus.component.ts b/ui/src/app/components/packet/NetworkStatus.component.ts index d3e3a70..e66f872 100644 --- a/ui/src/app/components/packet/NetworkStatus.component.ts +++ b/ui/src/app/components/packet/NetworkStatus.component.ts @@ -12,7 +12,7 @@ import {DatePipe} from "@angular/common"; @Component({ selector: "app-network-status", template: ` -
+

Статистика всей сети (желательно нажать ф5 если до этого смотрели другую ноду)

Статистика ноды {{getNumName(NUM)}} в сети

diff --git a/ui/src/styles.scss b/ui/src/styles.scss index b1375a9..8b1c539 100644 --- a/ui/src/styles.scss +++ b/ui/src/styles.scss @@ -1,3 +1,5 @@ +@import "styles/vw-style"; + /* You can add global styles to this file, and also import other style files */ html, body { height: 100%; } diff --git a/ui/src/styles/vw-style.scss b/ui/src/styles/vw-style.scss new file mode 100644 index 0000000..a7d5dc7 --- /dev/null +++ b/ui/src/styles/vw-style.scss @@ -0,0 +1,37 @@ +// +@media (max-width: 600px) { + .width-vw { + width: 100vw; + } +} + +@media (max-width: 960px) { + .width-vw { + width: 100vw; + } +} + +@media (max-width: 1280px) { + .width-vw { + width: 80vw; + } +} + +// +@media (max-width: 600px) { + .width-padding { + padding: 0 0; + } +} + +@media (max-width: 960px) { + .width-padding { + padding: 0 0; + } +} + +@media (max-width: 1280px) { + .width-padding { + padding: 0 10vw; + } +} diff --git a/webExtensions/publicEndpoints.py b/webExtensions/publicEndpoints.py index 7f7ddd8..b676ac4 100644 --- a/webExtensions/publicEndpoints.py +++ b/webExtensions/publicEndpoints.py @@ -67,6 +67,9 @@ class WebExtension: async def grabTile(request:Request, z:int, x:int, y:int): try: img = await self.core.tileManager.grabTile(z, x, y) + headers = { + "Cache-Control": f"public, max-age={86400*7}" + } return Response(content=img, media_type="image/png") except: traceback.print_exc()