Added Translations

This commit is contained in:
grata
2023-04-18 09:43:00 +02:00
parent e5b9e20f32
commit 3ebba88398
9 changed files with 156 additions and 102 deletions

92
package-lock.json generated
View File

@@ -18,6 +18,7 @@
"@angular/router": "^15.0.0",
"angularx-qrcode": "^15.0.1",
"daisyui": "^2.49.0",
"deepl": "^1.0.13",
"qrcode": "^1.5.1",
"rxjs": "~7.5.0",
"tslib": "^2.3.0",
@@ -28,7 +29,6 @@
"@angular/cli": "~15.0.4",
"@angular/compiler-cli": "^15.0.0",
"@types/jasmine": "~4.3.0",
"@types/qrcode": "^1.5.0",
"jasmine-core": "~4.5.0",
"karma": "~6.4.0",
"karma-chrome-launcher": "~3.1.0",
@@ -2853,6 +2853,18 @@
"webpack": "^5.54.0"
}
},
"node_modules/@ngx-translate/core": {
"version": "14.0.0",
"resolved": "https://registry.npmjs.org/@ngx-translate/core/-/core-14.0.0.tgz",
"integrity": "sha512-UevdwNCXMRCdJv//0kC8h2eSfmi02r29xeE8E9gJ1Al4D4jEJ7eiLPdjslTMc21oJNGguqqWeEVjf64SFtvw2w==",
"dependencies": {
"tslib": "^2.3.0"
},
"peerDependencies": {
"@angular/core": ">=13.0.0",
"rxjs": "^6.5.3 || ^7.4.0"
}
},
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -3302,15 +3314,6 @@
"integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
"dev": true
},
"node_modules/@types/qrcode": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@types/qrcode/-/qrcode-1.5.0.tgz",
"integrity": "sha512-x5ilHXRxUPIMfjtM+1vf/GPTRWZ81nqscursm5gMznJeK9M0YnZ1c3bEvRLQ0zSSgedLx1J6MGL231ObQGGhaA==",
"dev": true,
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/qrcode": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@types/qrcode/-/qrcode-1.5.0.tgz",
@@ -3885,6 +3888,14 @@
"postcss": "^8.1.0"
}
},
"node_modules/axios": {
"version": "0.21.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
"dependencies": {
"follow-redirects": "^1.14.0"
}
},
"node_modules/babel-loader": {
"version": "9.1.2",
"resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.2.tgz",
@@ -4989,6 +5000,15 @@
"node": ">=0.10.0"
}
},
"node_modules/deepl": {
"version": "1.0.13",
"resolved": "https://registry.npmjs.org/deepl/-/deepl-1.0.13.tgz",
"integrity": "sha512-ieaHKo+Y2u1jTpbX3SkhFGaOLgXB20gYoLqPhqtjxr612GC9wSMUqrHIfhvQzpevTVcI6H4kgElXActg3DHnqg==",
"dependencies": {
"axios": "^0.21.1",
"querystring": "^0.2.0"
}
},
"node_modules/default-gateway": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz",
@@ -5839,7 +5859,6 @@
"version": "1.15.2",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
"dev": true,
"funding": [
{
"type": "individual",
@@ -9707,6 +9726,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/querystring": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz",
"integrity": "sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==",
"deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.",
"engines": {
"node": ">=0.4.x"
}
},
"node_modules/queue-microtask": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@@ -13874,6 +13902,14 @@
"dev": true,
"requires": {}
},
"@ngx-translate/core": {
"version": "14.0.0",
"resolved": "https://registry.npmjs.org/@ngx-translate/core/-/core-14.0.0.tgz",
"integrity": "sha512-UevdwNCXMRCdJv//0kC8h2eSfmi02r29xeE8E9gJ1Al4D4jEJ7eiLPdjslTMc21oJNGguqqWeEVjf64SFtvw2w==",
"requires": {
"tslib": "^2.3.0"
}
},
"@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -14235,15 +14271,6 @@
"integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
"dev": true
},
"@types/qrcode": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@types/qrcode/-/qrcode-1.5.0.tgz",
"integrity": "sha512-x5ilHXRxUPIMfjtM+1vf/GPTRWZ81nqscursm5gMznJeK9M0YnZ1c3bEvRLQ0zSSgedLx1J6MGL231ObQGGhaA==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/qrcode": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@types/qrcode/-/qrcode-1.5.0.tgz",
@@ -14722,6 +14749,14 @@
"postcss-value-parser": "^4.2.0"
}
},
"axios": {
"version": "0.21.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
"requires": {
"follow-redirects": "^1.14.0"
}
},
"babel-loader": {
"version": "9.1.2",
"resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.2.tgz",
@@ -15551,6 +15586,15 @@
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
"integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA=="
},
"deepl": {
"version": "1.0.13",
"resolved": "https://registry.npmjs.org/deepl/-/deepl-1.0.13.tgz",
"integrity": "sha512-ieaHKo+Y2u1jTpbX3SkhFGaOLgXB20gYoLqPhqtjxr612GC9wSMUqrHIfhvQzpevTVcI6H4kgElXActg3DHnqg==",
"requires": {
"axios": "^0.21.1",
"querystring": "^0.2.0"
}
},
"default-gateway": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz",
@@ -16231,8 +16275,7 @@
"follow-redirects": {
"version": "1.15.2",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
"dev": true
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA=="
},
"forwarded": {
"version": "0.2.0",
@@ -19126,6 +19169,11 @@
"side-channel": "^1.0.4"
}
},
"querystring": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz",
"integrity": "sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg=="
},
"queue-microtask": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",

View File

@@ -22,7 +22,7 @@ import { SafePipe } from './pipes/safe.pipe';
BrowserModule,
AppRoutingModule,
FormsModule,
HttpClientModule
HttpClientModule,
],
providers: [],
bootstrap: [AppComponent]

View File

@@ -7,27 +7,31 @@
<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>Enter a location!!</span>
<span>{{translations.alertMessage}}</span>
</div>
</div>
<button class="btn btn-outline btn-primary" id="translate" (click)="translate()">Traduci</button>
<div class="dropdown dropdown-hover">
<label tabindex="0" class="btn m-1">{{translations.translate}}</label>
<ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 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="canvas nuvola">
<canvas #myCanvas width="100vw" class="canvas"></canvas>
</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="Type here"
(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()">
Search
{{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>
@@ -41,7 +45,7 @@
[style.width.px]="myInput.offsetWidth">
<li class="menu-title">
<span>Places</span>
<span>{{translations.menuPlaces}}</span>
</li>
<li *ngFor="let luogo of locations" (click)="luogoSelezionato=luogo.location; cercaLuogo(luogo.location)">
@@ -49,7 +53,7 @@
</li>
<li class="menu-title">
<span>Near</span>
<span>{{translations.menuNear}}</span>
</li>
<li *ngFor="let luogo of luoghiNear()">

View File

@@ -1,16 +1,13 @@
import {AfterViewInit, Component, ElementRef, OnDestroy, OnInit, ViewChild} from '@angular/core';
import {distinctUntilChanged, fromEvent, Observable, Subject, Subscription} from "rxjs";
import {BehaviorSubject, distinctUntilChanged, fromEvent, Observable, Subject, Subscription} from "rxjs";
import {ReadjsonService} from "../service/readjson.service";
import {Locations} from "../interface/data";
import * as QRCode from 'qrcode';
import {Router} from "@angular/router";
import {DeepLService} from "../service/deepL.service";
import { TranslateService } from '../service/translate.service';
import {ReadTranslateJsonService} from "../service/readTranslateJsonService";
import {translations} from "../interface/translations";
interface Luogo {
location: string;
lat: number;
lon: number;
}
@Component({
selector: 'app-home',
@@ -19,37 +16,39 @@ interface Luogo {
})
export class HomeComponent implements OnInit, AfterViewInit, OnDestroy {
@ViewChild('myInput') myInput?: ElementRef;
@ViewChild('myCanvas') myCanvas?: ElementRef<HTMLCanvasElement>;
public locationsPopup: Subject<Locations[]> = new Subject<Locations[]>()
subs: Subscription[] = [];
backgroundColor: string | undefined;
qrCodeImage: string | undefined;
locations: Locations[] = [];
allert: boolean = false;
locationsFiltrati: Locations[] = [];
luogoSelezionato: string = '';
suggerimentoAttivo: boolean = false;
suggerimento: string = '';
completamento: string = 'ciao';
completamento: string = '';
input: string = 'How are you?';
output: string = '';
translations: translations = {} as translations;
constructor(private readjsonService: ReadjsonService, private router: Router, private deepLService: DeepLService) {
constructor(private readjsonService: ReadjsonService, private router: Router, private translateService: TranslateService, private readTranslationJsonService: ReadTranslateJsonService) {
}
ngOnInit(): void {
this.translations = this.readTranslationJsonService.getData();
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");
//this.subs.push(this.readjsonService.getLocation("Lugano").subscribe(val => console.log(val)))
}
ngOnDestroy() {
@@ -58,9 +57,6 @@ export class HomeComponent implements OnInit, AfterViewInit, OnDestroy {
ngAfterViewInit() {
const canvas = this.myCanvas?.nativeElement;
if (canvas)
this.animateClouds(canvas);
if (this.locations != undefined) {
fromEvent(this.myInput?.nativeElement, 'focus').pipe(
@@ -80,36 +76,6 @@ export class HomeComponent implements OnInit, AfterViewInit, OnDestroy {
})
}
animateClouds(canvas: HTMLCanvasElement): void {
let x = -200;
let y = 100;
let speed = 2;
let rand = 30;
let ctx = canvas.getContext("2d");
canvas.width = window.innerWidth;
setInterval(() => {
if (ctx) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
this.drawCloud(x, y, ctx);
x += speed;
if (x > canvas.width + 200) {
x = -200;
}
}
rand = Math.round(Math.random() * (10 - 500)) + 10
}, rand);
}
drawCloud(x: number, y: number, ctx: CanvasRenderingContext2D) {
ctx.beginPath();
ctx.arc(x, y, 50, 0, 2 * Math.PI);
ctx.arc(x + 25, y - 25, 50, 0, 2 * Math.PI);
ctx.arc(x + 75, y - 25, 50, 0, 2 * Math.PI);
ctx.arc(x + 50, y, 50, 0, 2 * Math.PI);
ctx.fillStyle = "#87CEEB";
ctx.fill();
}
cercaLuogo(locations: string) {
setTimeout(() => {
}, 1000);
@@ -153,13 +119,14 @@ export class HomeComponent implements OnInit, AfterViewInit, OnDestroy {
}
}
translate() {
this.deepLService.translate(this.input, 'DE')
.subscribe(response => console.log(response.translations[0].text));
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.menuNear = await this.translateService.getData(this.translations.menuNear, lang);
this.translations.searchButton = await this.translateService.getData(this.translations.searchButton, lang);
}
protected readonly Event = Event;
}

View File

@@ -0,0 +1,9 @@
export interface translations {
alertMessage: string;
translate: string;
searchButton: string;
searchPlaceholder: string;
menuPlaces: string;
menuNear: string;
}

View File

@@ -0,0 +1,27 @@
import {Injectable} from '@angular/core';
import {HttpClient} from "@angular/common/http";
import {translations} from "../interface/translations";
@Injectable({
providedIn: 'root'
})
export class ReadTranslateJsonService {
private translationData: translations = {} as translations;
constructor(private http: HttpClient) {
this.http.get<translations>('assets/i18n/en.json').subscribe(data => {
this.translationData.alertMessage = data.alertMessage;
this.translationData.translate = data.translate;
this.translationData.searchButton = data.searchButton;
this.translationData.searchPlaceholder = data.searchPlaceholder;
this.translationData.menuPlaces = data.menuPlaces;
this.translationData.menuNear = data.menuNear;
console.log("data loaded", this.translationData)
});
}
getData(): translations {
console.log("data loaded", this.translationData)
return this.translationData;
}
}

View File

@@ -53,8 +53,4 @@ export class ReadjsonService{
tap(data => console.log("data requested", data))
);
}
}

View File

@@ -1,21 +1,16 @@
import { Injectable } from '@angular/core';
//import { Translate } from '@google-cloud/translate/build/src/v2';
import {DeepLService} from "./deepL.service";
import {Injectable} from "@angular/core";
@Injectable({
providedIn: 'root'
})
export class TranslateService {
constructor(private deepLService: DeepLService) {
//private translate: Translate;
// constructor() {
// this.translate = new Translate({projectId: 'Modulo-152'});
//}
//async translateText(text: string, target: string): Promise<string> {
//const [translation] = await this.translate.translate(text, target);
//return translation;
//}
}
async getData(input: string, lang: string): Promise<string> {
const response = await this.deepLService.translate(input, lang).toPromise();
return response.translations[0].text;
}
}

8
src/assets/i18n/en.json Normal file
View File

@@ -0,0 +1,8 @@
{
"alertMessage": "Enter a location!!",
"translate": "Translate",
"searchButton": "Search",
"searchPlaceholder": "Type here...",
"menuPlaces": "Places",
"menuNear": "Near"
}