changes
This commit is contained in:
10
package.json
10
package.json
@@ -18,19 +18,9 @@
|
|||||||
"@angular/platform-browser": "^15.0.0",
|
"@angular/platform-browser": "^15.0.0",
|
||||||
"@angular/platform-browser-dynamic": "^15.0.0",
|
"@angular/platform-browser-dynamic": "^15.0.0",
|
||||||
"@angular/router": "^15.0.0",
|
"@angular/router": "^15.0.0",
|
||||||
"angularx-qrcode": "^15.0.1",
|
|
||||||
"daisyui": "^2.49.0",
|
"daisyui": "^2.49.0",
|
||||||
"deepl": "^1.0.13",
|
|
||||||
"geolib": "^3.3.3",
|
|
||||||
"nodemon": "^2.0.22",
|
|
||||||
"os-browserify": "^0.3.0",
|
|
||||||
"path-browserify": "^1.0.1",
|
|
||||||
"qrcode": "^1.5.3",
|
|
||||||
"rxjs": "~7.5.0",
|
"rxjs": "~7.5.0",
|
||||||
"sharp": "^0.32.0",
|
|
||||||
"stream-browserify": "^3.0.0",
|
|
||||||
"tslib": "^2.3.0",
|
"tslib": "^2.3.0",
|
||||||
"util": "^0.12.5",
|
|
||||||
"zone.js": "~0.12.0"
|
"zone.js": "~0.12.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -2,14 +2,12 @@ import {NgModule} from '@angular/core';
|
|||||||
import {RouterModule} from '@angular/router';
|
import {RouterModule} from '@angular/router';
|
||||||
import {HomeComponent} from './home/home.component';
|
import {HomeComponent} from './home/home.component';
|
||||||
import {DetailComponent} from "./detail/detail.component";
|
import {DetailComponent} from "./detail/detail.component";
|
||||||
import {ListComponent} from "./list/list.component";
|
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [RouterModule.forRoot([
|
imports: [RouterModule.forRoot([
|
||||||
{path: 'home', component: HomeComponent},
|
{path: 'home', component: HomeComponent},
|
||||||
{path: 'location/:location', component: ListComponent},
|
{path: 'detail', component: DetailComponent},
|
||||||
{path: 'location/:location/:id', component: DetailComponent},
|
|
||||||
{path: '**', redirectTo: 'home'}
|
{path: '**', redirectTo: 'home'}
|
||||||
])],
|
])],
|
||||||
exports: [RouterModule],
|
exports: [RouterModule],
|
||||||
|
|||||||
35
src/app/app.component.spec.ts
Normal file
35
src/app/app.component.spec.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
import { RouterTestingModule } from '@angular/router/testing';
|
||||||
|
import { AppComponent } from './app.component';
|
||||||
|
|
||||||
|
describe('AppComponent', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [
|
||||||
|
RouterTestingModule
|
||||||
|
],
|
||||||
|
declarations: [
|
||||||
|
AppComponent
|
||||||
|
],
|
||||||
|
}).compileComponents();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create the app', () => {
|
||||||
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
|
const app = fixture.componentInstance;
|
||||||
|
expect(app).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should have as title 'm-152'`, () => {
|
||||||
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
|
const app = fixture.componentInstance;
|
||||||
|
expect(app.title).toEqual('m-152');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render title', () => {
|
||||||
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
|
fixture.detectChanges();
|
||||||
|
const compiled = fixture.nativeElement as HTMLElement;
|
||||||
|
expect(compiled.querySelector('.content span')?.textContent).toContain('m-152 app is running!');
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -6,23 +6,17 @@ import { AppComponent } from './app.component';
|
|||||||
import { HomeComponent } from './home/home.component';
|
import { HomeComponent } from './home/home.component';
|
||||||
import { ListComponent } from './list/list.component';
|
import { ListComponent } from './list/list.component';
|
||||||
import { DetailComponent } from './detail/detail.component';
|
import { DetailComponent } from './detail/detail.component';
|
||||||
import {FormsModule} from "@angular/forms";
|
|
||||||
import { HttpClientModule} from "@angular/common/http";
|
|
||||||
import { SafePipe } from './pipes/safe.pipe';
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
HomeComponent,
|
HomeComponent,
|
||||||
ListComponent,
|
ListComponent,
|
||||||
DetailComponent,
|
DetailComponent
|
||||||
SafePipe,
|
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
AppRoutingModule,
|
AppRoutingModule
|
||||||
FormsModule,
|
|
||||||
HttpClientModule,
|
|
||||||
],
|
],
|
||||||
providers: [],
|
providers: [],
|
||||||
bootstrap: [AppComponent]
|
bootstrap: [AppComponent]
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
.titolo {
|
|
||||||
font-size: 1.5em;
|
|
||||||
font-weight: bold;
|
|
||||||
margin-bottom: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
margin: 1em;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,24 +1 @@
|
|||||||
<div>
|
<p>detail works!</p>
|
||||||
<h1 class="titolo">{{test.name}}</h1>
|
|
||||||
<p>{{test.description}}</p>
|
|
||||||
<p ng-model="showNav" *ngIf="showNav">Distanza: {{distance}}</p>
|
|
||||||
<div id="nav" ng-model="showNav" *ngIf="showNav">
|
|
||||||
<iframe
|
|
||||||
width="500"
|
|
||||||
height="300"
|
|
||||||
frameborder="0" style="border:0"
|
|
||||||
referrerpolicy="no-referrer-when-downgrade"
|
|
||||||
[src]='embed | safe '
|
|
||||||
allowfullscreen>
|
|
||||||
</iframe>
|
|
||||||
</div>
|
|
||||||
<button (click)="generateQR()">
|
|
||||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="17.334" height="23.4863">
|
|
||||||
<g>
|
|
||||||
<rect height="23.4863" opacity="0" width="17.334" x="0" y="0"/>
|
|
||||||
<path d="M3.06641 22.041L14.2676 22.041C16.3086 22.041 17.334 21.0254 17.334 19.0137L17.334 9.26758C17.334 7.25586 16.3086 6.24023 14.2676 6.24023L11.543 6.24023L11.543 7.8125L14.2383 7.8125C15.2051 7.8125 15.7617 8.33984 15.7617 9.35547L15.7617 18.9258C15.7617 19.9414 15.2051 20.4688 14.2383 20.4688L3.08594 20.4688C2.10938 20.4688 1.57227 19.9414 1.57227 18.9258L1.57227 9.35547C1.57227 8.33984 2.10938 7.8125 3.08594 7.8125L5.79102 7.8125L5.79102 6.24023L3.06641 6.24023C1.02539 6.24023 0 7.25586 0 9.26758L0 19.0137C0 21.0254 1.02539 22.041 3.06641 22.041ZM8.66211 14.3945C9.08203 14.3945 9.44336 14.043 9.44336 13.6328L9.44336 3.60352L9.38477 2.13867L10.0391 2.83203L11.5234 4.41406C11.6602 4.57031 11.8555 4.64844 12.0508 4.64844C12.4512 4.64844 12.7637 4.35547 12.7637 3.95508C12.7637 3.75 12.6758 3.59375 12.5293 3.44727L9.22852 0.263672C9.0332 0.0683594 8.86719 0 8.66211 0C8.4668 0 8.30078 0.0683594 8.0957 0.263672L4.79492 3.44727C4.64844 3.59375 4.57031 3.75 4.57031 3.95508C4.57031 4.35547 4.86328 4.64844 5.27344 4.64844C5.45898 4.64844 5.67383 4.57031 5.81055 4.41406L7.28516 2.83203L7.94922 2.13867L7.89062 3.60352L7.89062 13.6328C7.89062 14.043 8.24219 14.3945 8.66211 14.3945Z" fill="#000000"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
<img src="assets/testDetail/img.png" alt="qr">
|
|
||||||
</div>
|
|
||||||
|
|||||||
23
src/app/detail/detail.component.spec.ts
Normal file
23
src/app/detail/detail.component.spec.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { DetailComponent } from './detail.component';
|
||||||
|
|
||||||
|
describe('DetailComponent', () => {
|
||||||
|
let component: DetailComponent;
|
||||||
|
let fixture: ComponentFixture<DetailComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
declarations: [ DetailComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(DetailComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,123 +1,10 @@
|
|||||||
import {Component, OnInit} from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import {ActivatedRoute} from "@angular/router";
|
|
||||||
import {positionService} from "../service/position.service";
|
|
||||||
import { getDistance } from 'geolib';
|
|
||||||
// @ts-ignore
|
|
||||||
import * as sharp from 'sharp';
|
|
||||||
import * as qrcode from 'qrcode';
|
|
||||||
import * as canvas from 'canvas';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-detail',
|
selector: 'app-detail',
|
||||||
templateUrl: './detail.component.html',
|
templateUrl: './detail.component.html',
|
||||||
styleUrls: ['./detail.component.css']
|
styleUrls: ['./detail.component.css']
|
||||||
})
|
})
|
||||||
export class DetailComponent implements OnInit {
|
export class DetailComponent {
|
||||||
private location: string | undefined;
|
|
||||||
private id: number | undefined;
|
|
||||||
|
|
||||||
private URLParams: any;
|
|
||||||
|
|
||||||
test = {
|
|
||||||
name: 'SPAI',
|
|
||||||
cordinates: '46.15187077044123,8.799829438699243',
|
|
||||||
lat: 46.15187077044123,
|
|
||||||
lng: 8.799829438699243,
|
|
||||||
description: "Lorem ipsum"
|
|
||||||
}
|
|
||||||
|
|
||||||
embed = `https://www.google.com/maps/embed/v1/place?key=AIzaSyBJL4FWmG032BG6KXxTb4faxpO_ccyaP3o&q=${this.test.lat},${this.test.lng}`
|
|
||||||
|
|
||||||
cord: any;
|
|
||||||
|
|
||||||
showNav = true;
|
|
||||||
distance: number | undefined;
|
|
||||||
displayedDistance = 0;
|
|
||||||
|
|
||||||
constructor(private route: ActivatedRoute , private positionService: positionService) {}
|
|
||||||
|
|
||||||
async ngOnInit(){
|
|
||||||
this.URLParams = this.route.snapshot.url.slice(-2).map(segment => segment.path);
|
|
||||||
console.log(this.URLParams); // ["lugnao", "1"]
|
|
||||||
console.log("getting your location: wait...");
|
|
||||||
this.cord = await this.positionService.getLocation();
|
|
||||||
console.log("location: ", this.cord);
|
|
||||||
this.checkDistanceTimer();
|
|
||||||
}
|
|
||||||
|
|
||||||
checkDistanceTimer() {
|
|
||||||
//set interval
|
|
||||||
let intervalID = setInterval(() => {
|
|
||||||
if (this.showNav) {
|
|
||||||
this.distance = this.positionService.getDistanceBetweenCoordinates(this.cord.lat, this.cord.lon, this.test.lat, this.test.lng);
|
|
||||||
console.log(this.distance);
|
|
||||||
if (this.distance == 0) {
|
|
||||||
this.showNav = false;
|
|
||||||
this.displayedDistance = Math.round(this.distance * 100) / 100;
|
|
||||||
}
|
|
||||||
if (this.distance < 0.05) {
|
|
||||||
this.showNav = false;
|
|
||||||
clearInterval(intervalID);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
clearInterval(intervalID);
|
|
||||||
}
|
|
||||||
}, 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
async generateQRCodeImage(url: string): Promise<Buffer> {
|
|
||||||
// Crea il QR code
|
|
||||||
const qrCode = await qrcode.toDataURL(url, { errorCorrectionLevel: "H" });
|
|
||||||
|
|
||||||
// Crea il canvas
|
|
||||||
const canvasInstance = canvas.createCanvas(300, 300);
|
|
||||||
const ctx = canvasInstance.getContext("2d");
|
|
||||||
|
|
||||||
// Carica il QR code nell'immagine
|
|
||||||
const qrCodeImage = await canvas.loadImage(qrCode);
|
|
||||||
|
|
||||||
// Disegna il QR code nell'immagine
|
|
||||||
ctx.drawImage(qrCodeImage, 0, 0, 300, 300);
|
|
||||||
|
|
||||||
// Ritorna l'immagine come buffer
|
|
||||||
return canvasInstance.toBuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*generateQR() {
|
|
||||||
console.log("generating QR code");
|
|
||||||
let url = `http://localhost:4200/location/${this.URLParams[0]}/${this.URLParams[1]}`;
|
|
||||||
//this.addQRCodeToImage(url, `assets/testDetail/img.png`, `assets/images/${url}.png`);
|
|
||||||
console.log(url)
|
|
||||||
}*/
|
|
||||||
|
|
||||||
/*async addQRCodeToImage(url: string, imagePath: string, outputPath: string): Promise<void> {
|
|
||||||
// Generate QR code
|
|
||||||
const qrCode = await qrcode.toBuffer(url);
|
|
||||||
|
|
||||||
// Load input image using Sharp
|
|
||||||
const image = sharp(imagePath);
|
|
||||||
|
|
||||||
// Get input image dimensions
|
|
||||||
const { width, height } = await image.metadata();
|
|
||||||
|
|
||||||
// Resize QR code to 25% of input image height
|
|
||||||
const qrCodeHeight = Math.round(height * 0.25);
|
|
||||||
const qrCodeBuffer = await sharp(qrCode)
|
|
||||||
.resize(qrCodeHeight, qrCodeHeight)
|
|
||||||
.toBuffer();
|
|
||||||
|
|
||||||
// Composite QR code onto input image at bottom-right corner
|
|
||||||
await image.composite([
|
|
||||||
{
|
|
||||||
input: qrCodeBuffer,
|
|
||||||
gravity: 'southeast',
|
|
||||||
top: height - qrCodeHeight,
|
|
||||||
left: width - qrCodeHeight,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Save output image to file
|
|
||||||
await image.toFile(outputPath);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,52 +1,6 @@
|
|||||||
.search {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
flex-direction: column;
|
|
||||||
position: absolute;
|
|
||||||
top: 35%;
|
|
||||||
left: 50%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
}
|
|
||||||
|
|
||||||
input{
|
input{
|
||||||
|
width: 40%;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
#list {
|
|
||||||
position: absolute;
|
|
||||||
top: 46%;
|
|
||||||
left: 44%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
align-content: center;
|
|
||||||
margin-top: 10px;
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#list > li {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.inputElements{
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
align-content: center;
|
|
||||||
gap: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bg-image {
|
|
||||||
background-image: url('src/assets/img/mountains.png');
|
|
||||||
background-size: cover;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: center center;
|
|
||||||
height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
#translate{
|
|
||||||
margin: 100px 10px 10px 10px;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,58 +1,2 @@
|
|||||||
<div [ngClass]="{'background-color': backgroundColor}">
|
<input type="text" placeholder="Type here" class="input input-bordered input-primary w-full max-w-xs" />
|
||||||
|
|
||||||
<div class="alert alert-warning shadow-lg" *ngIf="allert">
|
|
||||||
<div>
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="stroke-current flex-shrink-0 h-6 w-6" fill="none"
|
|
||||||
viewBox="0 0 24 24">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
||||||
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/>
|
|
||||||
</svg>
|
|
||||||
<span>{{translations.alertMessage}}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="dropdown dropdown-hover">
|
|
||||||
<label tabindex="0" class="btn m-1 bg-black border-neutral text-base-100">{{translations.translate}}</label>
|
|
||||||
<ul tabindex="0" class="dropdown-content menu p-2 shadow rounded-box w-52">
|
|
||||||
<li (click)="switchLanguage('DE')"><a>DE</a></li>
|
|
||||||
<li (click)="switchLanguage('FR')"><a>FR</a></li>
|
|
||||||
<li (click)="switchLanguage('IT')"><a>IT</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="bg-image">
|
|
||||||
<div class="search">
|
|
||||||
|
|
||||||
<div class="inputElements">
|
|
||||||
<input #myInput type="text" [(ngModel)]="luogoSelezionato" (keyup)="cercaLuogo(myInput.value)"
|
|
||||||
(keydown)="selezionaSuggerimento($event)" placeholder="{{translations.searchPlaceholder}}"
|
|
||||||
class="input input-bordered input-primary btn-wide">
|
|
||||||
|
|
||||||
<button
|
|
||||||
class="btn gap-2 border-primary bg-primary text-secondary hover:bg-secondary hover:text-primary hover:border-primary"
|
|
||||||
(click)="onSearch()">
|
|
||||||
{{translations.searchButton}}
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path
|
|
||||||
d="M18.125,15.804l-4.038-4.037c0.675-1.079,1.012-2.308,1.01-3.534C15.089,4.62,12.199,1.75,8.584,1.75C4.815,1.75,1.982,4.726,2,8.286c0.021,3.577,2.908,6.549,6.578,6.549c1.241,0,2.417-0.347,3.44-0.985l4.032,4.026c0.167,0.166,0.43,0.166,0.596,0l1.479-1.478C18.292,16.234,18.292,15.968,18.125,15.804 M8.578,13.99c-3.198,0-5.716-2.593-5.733-5.71c-0.017-3.084,2.438-5.686,5.74-5.686c3.197,0,5.625,2.493,5.64,5.624C14.242,11.548,11.621,13.99,8.578,13.99 M16.349,16.981l-3.637-3.635c0.131-0.11,0.721-0.695,0.876-0.884l3.642,3.639L16.349,16.981z"></path>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<ng-container *ngIf="locationsPopup | async as locations;">
|
|
||||||
<ul *ngIf="locations.length > 0" class="menu bg-base-200 p-2 rounded-box" id="list"
|
|
||||||
[style.width.px]="myInput.offsetWidth">
|
|
||||||
|
|
||||||
<li class="menu-title">
|
|
||||||
<span>{{translations.menuPlaces}}</span>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li *ngFor="let luogo of locations" (click)="luogoSelezionato=luogo.location; cercaLuogo(luogo.location)">
|
|
||||||
{{luogo.location}}
|
|
||||||
</li>
|
|
||||||
|
|
||||||
</ul>
|
|
||||||
</ng-container>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|||||||
23
src/app/home/home.component.spec.ts
Normal file
23
src/app/home/home.component.spec.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { HomeComponent } from './home.component';
|
||||||
|
|
||||||
|
describe('HomeComponent', () => {
|
||||||
|
let component: HomeComponent;
|
||||||
|
let fixture: ComponentFixture<HomeComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
declarations: [ HomeComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(HomeComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,139 +1,10 @@
|
|||||||
import {AfterViewInit, Component, ElementRef, OnDestroy, OnInit, ViewChild} from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import {BehaviorSubject, distinctUntilChanged, fromEvent, Observable, Subject, Subscription} from "rxjs";
|
|
||||||
import {ReadjsonService} from "../service/readjson.service";
|
|
||||||
import {Locations} from "../interface/data";
|
|
||||||
import {Router} from "@angular/router";
|
|
||||||
import { TranslateService } from '../service/translate.service';
|
|
||||||
import {ReadTranslateJsonService} from "../service/readTranslateJsonService";
|
|
||||||
import {homeTranslations} from "../interface/translations";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-home',
|
selector: 'app-home',
|
||||||
templateUrl: './home.component.html',
|
templateUrl: './home.component.html',
|
||||||
styleUrls: ['./home.component.css']
|
styleUrls: ['./home.component.css']
|
||||||
})
|
})
|
||||||
export class HomeComponent implements OnInit, AfterViewInit, OnDestroy {
|
export class HomeComponent {
|
||||||
@ViewChild('myInput') myInput?: ElementRef;
|
|
||||||
|
|
||||||
public locationsPopup: Subject<Locations[]> = new Subject<Locations[]>()
|
|
||||||
|
|
||||||
subs: Subscription[] = [];
|
|
||||||
backgroundColor: string | undefined;
|
|
||||||
locations: Locations[] = [];
|
|
||||||
allert: boolean = false;
|
|
||||||
locationsFiltrati: Locations[] = [];
|
|
||||||
luogoSelezionato: string = '';
|
|
||||||
suggerimentoAttivo: boolean = false;
|
|
||||||
suggerimento: string = '';
|
|
||||||
completamento: string = '';
|
|
||||||
translations: homeTranslations = {} as homeTranslations;
|
|
||||||
|
|
||||||
|
|
||||||
constructor(private readjsonService: ReadjsonService, private router: Router, private translateService: TranslateService, private readTranslationJsonService: ReadTranslateJsonService) {
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.translations = this.readTranslationJsonService.getHomeTranslations();
|
|
||||||
console.log("translations loaded", this.translations)
|
|
||||||
|
|
||||||
this.readjsonService.getLocations().subscribe(data => {
|
|
||||||
for (let i = 0; i < data.length; i++) {
|
|
||||||
this.locations.push(<Locations>data[i])
|
|
||||||
console.log(data[i])
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
this.allert = false;
|
|
||||||
console.log("home init");
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnDestroy() {
|
|
||||||
this.subs.forEach(sub => sub.unsubscribe())
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ngAfterViewInit() {
|
|
||||||
|
|
||||||
if (this.locations != undefined) {
|
|
||||||
fromEvent(this.myInput?.nativeElement, 'focus').pipe(
|
|
||||||
// debounceTime(500), decommentarlo se bisogna fare una chiamata http
|
|
||||||
distinctUntilChanged()
|
|
||||||
).subscribe((val: any) => {
|
|
||||||
this.locationsPopup.next(this.locations.filter(l => l.location.toLowerCase().startsWith(val.target.value.toLowerCase())))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fromEvent(this.myInput?.nativeElement, 'input')
|
|
||||||
.pipe(
|
|
||||||
// debounceTime(500), decommentarlo se bisogna fare una chiamata http
|
|
||||||
distinctUntilChanged()
|
|
||||||
).subscribe((val: any) => {
|
|
||||||
this.locationsPopup.next(this.locations.filter(l => l.location.toLowerCase().startsWith(val.target.value.toLowerCase())))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
cercaLuogo(locations: string) {
|
|
||||||
setTimeout(() => {
|
|
||||||
}, 1000);
|
|
||||||
this.locationsFiltrati = this.locations.filter((l: Locations) => l.location.toLowerCase().startsWith(locations.toLowerCase()));
|
|
||||||
if (this.locationsFiltrati.length > 0) {
|
|
||||||
this.suggerimentoAttivo = true;
|
|
||||||
this.suggerimento = this.locationsFiltrati[0].location;
|
|
||||||
this.completamento = stringDifference(locations, this.suggerimento);
|
|
||||||
} else {
|
|
||||||
this.suggerimentoAttivo = false;
|
|
||||||
this.suggerimento = '';
|
|
||||||
}
|
|
||||||
this.myInput?.nativeElement.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
selezionaSuggerimento(event: KeyboardEvent) {
|
|
||||||
if (event.key === 'Tab' || event.key === 'Enter') {
|
|
||||||
if (this.suggerimentoAttivo) {
|
|
||||||
this.luogoSelezionato = this.suggerimento;
|
|
||||||
this.suggerimentoAttivo = false;
|
|
||||||
this.suggerimento = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
luoghiNear() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
onSearch(): void {
|
|
||||||
if (this.luogoSelezionato === '') {
|
|
||||||
this.allert = true;
|
|
||||||
setTimeout(() => {
|
|
||||||
this.allert = false;
|
|
||||||
}, 3000);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
const nomeLocation = encodeURIComponent(this.luogoSelezionato);
|
|
||||||
this.router.navigate(['/location', nomeLocation]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async switchLanguage(lang: string) {
|
|
||||||
this.translations.translate = await this.translateService.getData(this.translations.translate, lang);
|
|
||||||
this.translations.menuPlaces = await this.translateService.getData(this.translations.menuPlaces, lang);
|
|
||||||
this.translations.alertMessage = await this.translateService.getData(this.translations.alertMessage, lang);
|
|
||||||
this.translations.searchPlaceholder = await this.translateService.getData(this.translations.searchPlaceholder, lang);
|
|
||||||
this.translations.searchButton = await this.translateService.getData(this.translations.searchButton, lang);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function stringDifference(str1: string, str2: string): string {
|
|
||||||
let diff = '';
|
|
||||||
for (let i = 0; i < str2.length; i++) {
|
|
||||||
if (str1[i] !== str2[i]) {
|
|
||||||
diff += str2[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return diff;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,37 +1 @@
|
|||||||
<div class="dropdown dropdown-hover">
|
<p>list works!</p>
|
||||||
<label tabindex="0" class="btn m-1 bg-black border-neutral text-base-100">{{translations.translate}}</label>
|
|
||||||
<ul tabindex="0" class="dropdown-content menu p-2 shadow rounded-box w-52">
|
|
||||||
<li (click)="switchLanguage('DE')"><a>DE</a></li>
|
|
||||||
<li (click)="switchLanguage('FR')"><a>FR</a></li>
|
|
||||||
<li (click)="switchLanguage('IT')"><a>IT</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="isNear">
|
|
||||||
<h1>
|
|
||||||
{{translations.locationName}}{{locationParams}}
|
|
||||||
</h1>
|
|
||||||
<div *ngFor="let locations of locations, let i = index">
|
|
||||||
<h3>
|
|
||||||
<a class="link link-primary" href="location/{{locations.location}}">{{locations.location}}</a>
|
|
||||||
</h3>
|
|
||||||
<div *ngIf="distance[i]">
|
|
||||||
<h4>{{translations.distance}}{{distance[i]}} km</h4>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div *ngIf="!isNear && location && location.waypoints">
|
|
||||||
<h1>
|
|
||||||
{{location.location}}
|
|
||||||
</h1>
|
|
||||||
<div *ngFor="let waypoinst of location.waypoints, let i = index">
|
|
||||||
<h3>
|
|
||||||
<a class="link link-primary" href="location/{{location.location}}/{{waypoinst.id}}"> {{waypoinst.name}}</a>
|
|
||||||
</h3>
|
|
||||||
<div *ngIf="distance[i]">
|
|
||||||
<h4>{{translations.distance}}{{distance[i]}} km</h4>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|||||||
23
src/app/list/list.component.spec.ts
Normal file
23
src/app/list/list.component.spec.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ListComponent } from './list.component';
|
||||||
|
|
||||||
|
describe('ListComponent', () => {
|
||||||
|
let component: ListComponent;
|
||||||
|
let fixture: ComponentFixture<ListComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
declarations: [ ListComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(ListComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,114 +1,10 @@
|
|||||||
import {Component, OnInit, SimpleChanges, OnChanges} from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import {Locations} from "../interface/data";
|
|
||||||
import {ReadjsonService} from "../service/readjson.service";
|
|
||||||
import {ActivatedRoute} from "@angular/router";
|
|
||||||
import {positionService} from "../service/position.service";
|
|
||||||
import {listTranslations} from "../interface/translations";
|
|
||||||
import {TranslateService} from "../service/translate.service";
|
|
||||||
import {ReadTranslateJsonService} from "../service/readTranslateJsonService";
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-list',
|
selector: 'app-list',
|
||||||
templateUrl: './list.component.html',
|
templateUrl: './list.component.html',
|
||||||
styleUrls: ['./list.component.css']
|
styleUrls: ['./list.component.css']
|
||||||
})
|
})
|
||||||
export class ListComponent implements OnInit, OnChanges {
|
export class ListComponent {
|
||||||
locationParams: string | undefined
|
|
||||||
locations: Partial<Locations>[] | undefined;
|
|
||||||
location: Partial<Locations> | undefined;
|
|
||||||
|
|
||||||
positionCord: any;
|
|
||||||
|
|
||||||
isNear: boolean = true;
|
|
||||||
|
|
||||||
distance: number[] = [];
|
|
||||||
|
|
||||||
translations: listTranslations = {} as listTranslations
|
|
||||||
|
|
||||||
constructor(private route: ActivatedRoute, private readjsonService: ReadjsonService, private positionService: positionService, private translateService: TranslateService, private readTranslationJsonService: ReadTranslateJsonService) {
|
|
||||||
}
|
|
||||||
|
|
||||||
async ngOnInit() {
|
|
||||||
this.translations = this.readTranslationJsonService.getListTransaltions();
|
|
||||||
this.route.params.subscribe(params => {
|
|
||||||
this.locationParams = params['location'];
|
|
||||||
});
|
|
||||||
this.readjsonService.getLocations().subscribe(locations => {
|
|
||||||
this.locations = locations;
|
|
||||||
if (this.locationParams != null) {
|
|
||||||
this.readjsonService.getLocation(this.locationParams ?? "").subscribe(async location => {
|
|
||||||
this.location = location;
|
|
||||||
this.readjsonService.getWaypoints(this.locationParams ?? "").subscribe(waypoints => {
|
|
||||||
if (this.location) {
|
|
||||||
this.location.waypoints = waypoints ?? []
|
|
||||||
}
|
|
||||||
});
|
|
||||||
await this.checkDataPopulated();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.getPosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges) {
|
|
||||||
if (changes['positionCord'] && (changes['positionCord'])) {
|
|
||||||
console.log("onChanges")
|
|
||||||
this.setDistance();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private checkDataPopulated(): void {
|
|
||||||
if (this.locations && this.location) {
|
|
||||||
console.log("Dati popolati correttamente:", this.locations, this.location);
|
|
||||||
for (let i = 0; i < this.locations.length; i++) {
|
|
||||||
if (this.locations[i].location === this.locationParams) {
|
|
||||||
this.location = this.locations[i];
|
|
||||||
console.log("Location trovata:", this.location);
|
|
||||||
this.isNear = false;
|
|
||||||
this.setDistance();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private setDistance(): void {
|
|
||||||
if (this.locations && this.location){
|
|
||||||
if (this.isNear){
|
|
||||||
console.log("location lenght " + this.locations.length);
|
|
||||||
for (let i = 0; i < this.locations.length; i++) {
|
|
||||||
console.log("for"+i);
|
|
||||||
console.log("lat" + this.locations[i].lat);
|
|
||||||
this.distance.push(this.positionService.getDistanceBetweenCoordinates(this.locations[i].lat, this.locations[i].lon, this.positionCord.lat, this.positionCord.lon));
|
|
||||||
}
|
|
||||||
} else{
|
|
||||||
if (this.location?.waypoints) {
|
|
||||||
console.log("waypoints lenght " + this.location.waypoints.length);
|
|
||||||
for (let i = 0; i < this.location.waypoints.length; i++) {
|
|
||||||
console.log("for"+i);
|
|
||||||
console.log("lat" + this.location.waypoints[i].lat);
|
|
||||||
this.distance.push(this.positionService.getDistanceBetweenCoordinates(this.location.waypoints[i].lat, this.location.waypoints[i].lon, this.positionCord.lat, this.positionCord.lon));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log("ciao" + this.distance[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
getPosition(): any {
|
|
||||||
setInterval(async () => {
|
|
||||||
this.positionCord = await this.positionService.getLocation();
|
|
||||||
this.setDistance();
|
|
||||||
}, 2000);
|
|
||||||
}
|
|
||||||
|
|
||||||
async switchLanguage(lang: string) {
|
|
||||||
this.translations.translate = await this.translateService.getData(this.translations.translate, lang);
|
|
||||||
this.translations.distance = await this.translateService.getData(this.translations.distance, lang);
|
|
||||||
this.translations.locationName = await this.translateService.getData(this.translations.locationName, lang);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
src/assets/mountains.png
Normal file
BIN
src/assets/mountains.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 198 KiB |
@@ -2,7 +2,3 @@
|
|||||||
@tailwind base;
|
@tailwind base;
|
||||||
@tailwind components;
|
@tailwind components;
|
||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
|
|
||||||
body{
|
|
||||||
overflow-y: hidden;
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user