Skip to content

Commit

Permalink
Merge pull request #82 from Apes2getherStrong/81-wywietlanie-zdjcia-m…
Browse files Browse the repository at this point in the history
…ap-location

81 wywietlanie zdjcia map location
  • Loading branch information
Drillllll authored Jun 17, 2024
2 parents a373523 + 97c70db commit dda7e03
Show file tree
Hide file tree
Showing 12 changed files with 200 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
height: 180px;
width: 180px;
overflow: hidden;
background-color: #89ecda;
}

.photo img {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@


<div class="photo">
<img src="https://images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com/f/dcc3094e-c043-4078-bad1-e65737f5b8e8/dc5b8mp-015b238d-43c6-4f1c-8562-38c98a20017c.jpg/v1/fill/w_1024,h_768,q_75,strp/stock_pohoto_20_for_some_photo_manipulation_by_babine326_dc5b8mp-fullview.jpg?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1cm46YXBwOjdlMGQxODg5ODIyNjQzNzNhNWYwZDQxNWVhMGQyNmUwIiwiaXNzIjoidXJuOmFwcDo3ZTBkMTg4OTgyMjY0MzczYTVmMGQ0MTVlYTBkMjZlMCIsIm9iaiI6W1t7ImhlaWdodCI6Ijw9NzY4IiwicGF0aCI6IlwvZlwvZGNjMzA5NGUtYzA0My00MDc4LWJhZDEtZTY1NzM3ZjViOGU4XC9kYzViOG1wLTAxNWIyMzhkLTQzYzYtNGYxYy04NTYyLTM4Yzk4YTIwMDE3Yy5qcGciLCJ3aWR0aCI6Ijw9MTAyNCJ9XV0sImF1ZCI6WyJ1cm46c2VydmljZTppbWFnZS5vcGVyYXRpb25zIl19.l2WC0hFzadetmSbDFvEfb2gyn7SjBGfSdq9kWD4g2kQ" alt="map-location-photo">
<img *ngIf="imageUrl" [src]="imageUrl">
<!--<img *ngIf="!imageUrl" src="https://images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com/f/dcc3094e-c043-4078-bad1-e65737f5b8e8/dc5b8mp-015b238d-43c6-4f1c-8562-38c98a20017c.jpg/v1/fill/w_1024,h_768,q_75,strp/stock_pohoto_20_for_some_photo_manipulation_by_babine326_dc5b8mp-fullview.jpg?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1cm46YXBwOjdlMGQxODg5ODIyNjQzNzNhNWYwZDQxNWVhMGQyNmUwIiwiaXNzIjoidXJuOmFwcDo3ZTBkMTg4OTgyMjY0MzczYTVmMGQ0MTVlYTBkMjZlMCIsIm9iaiI6W1t7ImhlaWdodCI6Ijw9NzY4IiwicGF0aCI6IlwvZlwvZGNjMzA5NGUtYzA0My00MDc4LWJhZDEtZTY1NzM3ZjViOGU4XC9kYzViOG1wLTAxNWIyMzhkLTQzYzYtNGYxYy04NTYyLTM4Yzk4YTIwMDE3Yy5qcGciLCJ3aWR0aCI6Ijw9MTAyNCJ9XV0sImF1ZCI6WyJ1cm46c2VydmljZTppbWFnZS5vcGVyYXRpb25zIl19.l2WC0hFzadetmSbDFvEfb2gyn7SjBGfSdq9kWD4g2kQ" alt="map-location-photo">-->
</div>

<div class="info">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import {Component, Input, OnChanges, OnInit, SimpleChanges} from '@angular/core';
import {MapLocation} from "../map-location.model";
import {NgForOf, NgIf} from "@angular/common";
import {AudioService} from "../../audio/audio.service";
import {DomSanitizer, SafeUrl} from "@angular/platform-browser";
import {maxPageSize} from "../../shared/http.config";
import {Audio} from "../../audio/audio.model";
import {MapService} from "../../shared/map/map.service";
import {MapLocationService} from "../map-location.service";

@Component({
selector: 'app-map-location-info-window',
Expand All @@ -20,42 +18,36 @@ import {MapService} from "../../shared/map/map.service";
export class MapLocationInfoWindowComponent implements OnInit, OnChanges {

@Input() mapLocation: MapLocation;
audiosEntities: Audio[] = [];
audiosUrls: SafeUrl[] = [];
imageUrl: SafeUrl = null;

constructor(private audioService: AudioService, private sanitizer: DomSanitizer, private mapService: MapService) {

constructor( private sanitizer: DomSanitizer,
private mapService: MapService,
private mapLocationService: MapLocationService) {
}

ngOnChanges(changes: SimpleChanges): void {

this.audiosEntities = [];
this.audiosUrls = [];

this.audioService.getAudiosByMapLocation(this.mapLocation, 0, maxPageSize).subscribe(response => {
this.audiosEntities = response.content;


for (let audio of this.audiosEntities) {
this.audioService.getAudioFileByAudio(audio).subscribe({
next: (response: Blob | null) => {
//convert Blob (raw byte object) to url
if (response) {
const objectURL = URL.createObjectURL(response);
this.audiosUrls.push(this.sanitizer.bypassSecurityTrustUrl(objectURL));
}

},
error: (error: any) => {
//
console.log("getaudio error")
}
});
this.imageUrl = null;

this.mapLocationService.getMapLocationImageById(this.mapLocation.id).subscribe({
next: (response: Blob | null) => {
if (response) {
//convert Blob (raw byte object) to url to display it in the template
const objectURL = URL.createObjectURL(response);
this.imageUrl = this.sanitizer.bypassSecurityTrustUrl(objectURL);
}
},
error: (error: any) => {
//
}
});

}


ngOnInit(): void {

}

onDetailsClick() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@
width:200px;
height: 200px;
background-color: cadetblue;
overflow: hidden;
}

.photo img {
height: 100%;
width: 100%;
}

.info-wrap {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,29 @@
<ul class="list-group" style="padding: 5px">
<div *ngFor="let mapLocation of mapLocations" style="margin-bottom: 5px">
<div *ngFor="let mapLocationData of mapLocationsAndImages" style="margin-bottom: 5px">

<li (click)="onMapLocationSelected(mapLocation)"
[ngClass]="{'active' : activeMapLocationId == mapLocation.id}"
<li (click)="onMapLocationSelected(mapLocationData.mapLocation)"
[ngClass]="{'active' : activeMapLocationId == mapLocationData.mapLocation.id}"
class="list-group-item"
style="cursor: pointer; display: flex; justify-content: center">
style="cursor: pointer; display: flex; justify-content: center; align-items: center;">

<span aria-hidden="true" class="glyphicon glyphicon-map-marker"></span>
<p style="flex-grow: 1; text-align: center">{{mapLocation.name}}</p>
<p style="flex-grow: 1; margin-left: 20px"></p>
{{mapLocationData.mapLocation.name}}
<p style="flex-grow: 1;"></p>
</li>

<li *ngIf="activeMapLocationId == mapLocation.id" class="list-group-item"
style="background-color: #bdf2e9;" #info>
<li *ngIf="activeMapLocationId == mapLocationData.mapLocation.id" class="list-group-item"
style="background-color: #bdf2e9;" #info >
<div class="map-location-grid-container">
<div class="photo-wrap">
<div class="photo">

<img *ngIf="mapLocationData.url" [src]="mapLocationData.url">
</div>
</div>
<div class="info-wrap" >
<p style="text-align: center"><strong>Map Location info: </strong></p>
<p>Name: {{mapLocation.name}}</p>
<p>Description: {{mapLocation.description}}</p>
<p>Name: {{mapLocationData.mapLocation.name}}</p>
<p>Description: {{mapLocationData.mapLocation.description}}</p>
</div>
<div class="audio-list">
<div *ngFor="let audioItem of audioData">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Component, ElementRef, HostListener, Input, OnInit, Renderer2, ViewChild} from '@angular/core';
import {Component, ElementRef, Input, OnInit, Renderer2, ViewChild} from '@angular/core';
import {MapLocationService} from "../map-location.service";
import {maxPageSize} from "../../shared/http.config";
import {Route} from "../../route/route.model";
Expand All @@ -12,6 +12,8 @@ import {AudioService} from "../../audio/audio.service";
import {Audio} from "../../audio/audio.model";
import {DomSanitizer, SafeUrl} from "@angular/platform-browser";
import {ScreenSizeService} from "../../shared/screen-size.service";
import { forkJoin } from 'rxjs';
import { map } from 'rxjs/operators';

@Component({
selector: 'app-map-location-list',
Expand All @@ -30,64 +32,92 @@ export class MapLocationListComponent implements OnInit {

@Input() route: Route;
mapLocations: MapLocation[];
mapLocationsAndImages: { mapLocation: MapLocation, url: SafeUrl }[] = [];
activeMapLocationId: string;

audiosEntities: Audio[] = [];
audiosUrls: SafeUrl[] = [];
audioData: { audio: Audio, url: SafeUrl }[] = [];

mobileVersion: boolean;

@ViewChild('info') infoWrapper: ElementRef;

constructor(private mapService: MapService,
private sidePanelService: SidePanelService,
private mapLocationService: MapLocationService,
private audioService: AudioService,
private sanitizer: DomSanitizer,
private renderer: Renderer2,
private screenSizeService: ScreenSizeService) {
}


@ViewChild('info') infoWrapper: ElementRef;
private screenSizeService: ScreenSizeService) { }

ngOnInit(): void {

this.screenSizeService.isMobileVersion$.subscribe(isMobileVersion => {
this.mobileVersion = isMobileVersion;
});

//subscribe to event emitted by map location in map info window
this.mapService.mapLocationDetailsEventEmitter.subscribe(mapLocation => {
this.onMapLocationSelected(mapLocation);


this.sidePanelService.togglePanelEventEmitter.emit(true);
this.scrollToInfoWrapper();
});

this.fetchMapLocations();
}



//scroll to map location info and animate it
private scrollToInfoWrapper() {
if (this.infoWrapper?.nativeElement) {
this.infoWrapper.nativeElement.scrollIntoView({ behavior: 'smooth', block: 'start' });
this.renderer.addClass(this.infoWrapper.nativeElement, 'animation');
this.infoWrapper.nativeElement.addEventListener('animationend', () => {
this.renderer.removeClass(this.infoWrapper.nativeElement, 'animation');
}, { once: true });
}
}

if (this.infoWrapper.nativeElement) {
this.renderer.addClass(this.infoWrapper.nativeElement, 'animation');
this.infoWrapper.nativeElement.addEventListener('animationend', () => {
this.renderer.removeClass(this.infoWrapper.nativeElement, 'animation');
}, { once: true });
}
})


//fetch map locations and their images
private fetchMapLocations() {
this.mapLocationService.getMapLocationsByRoute(0, maxPageSize, this.route.id)
.subscribe(response => {
this.mapLocations = response.content;
this.loadImagesForMapLocations();
this.mapService.routeSelectedEventEmitter.emit(this.mapLocations);
});
}

//fetch images for map locations
private loadImagesForMapLocations() {
const imageRequests = this.mapLocations.map(ml => {
return this.mapLocationService.getMapLocationImageById(ml.id).pipe(
map(response => {
if (response) {
const objectURL = URL.createObjectURL(response);
const imageUrl = this.sanitizer.bypassSecurityTrustUrl(objectURL);
return { mapLocation: ml, url: imageUrl };
} else {
return { mapLocation: ml, url: null };
}
})
);
});

//execute all requests concurrently and wait for their execution
forkJoin(imageRequests).subscribe({
next: (results) => {
this.mapLocationsAndImages = results;
},
error: (error) => {
console.error('Error loading images:', error);
}
});
}

onMapLocationSelected(mapLocation: MapLocation) {
this.mapService.centerOnMapLocation.emit(mapLocation);
if(this.activeMapLocationId != mapLocation.id) {
if(this.activeMapLocationId == mapLocation.id) {
this.activeMapLocationId = null;
}
else {
this.activeMapLocationId = mapLocation.id;
if (this.mobileVersion) {
this.sidePanelService.togglePanelEventEmitter.emit(false);
Expand Down Expand Up @@ -120,10 +150,8 @@ export class MapLocationListComponent implements OnInit {
});

Promise.all(audioPromises).then(() => {
//All audio files fetched and URLs are set
// All audio files fetched and URLs are set
});
});
}


}
14 changes: 13 additions & 1 deletion src/app/map-location/map-location.service.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { HttpClient, HttpParams } from "@angular/common/http";
import {HttpClient, HttpErrorResponse, HttpParams} from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Page } from "../shared/page.model";
import { MapLocation } from "./map-location.model";
import { backendUrl } from "../shared/http.config";
import {catchError, of} from "rxjs";

@Injectable({ providedIn: 'root' })
export class MapLocationService {
Expand Down Expand Up @@ -30,6 +31,17 @@ export class MapLocationService {
return this.http.put(url, formData);
}

getMapLocationImageById(mapLocationId: string) {
const url = `${backendUrl}/mapLocations/${mapLocationId}/image`;
return this.http.get(url, {responseType: 'blob'}).pipe(
catchError((error: HttpErrorResponse) => {
console.error('Error fetching image:', error);
return of(null);
})
);

}



}
44 changes: 40 additions & 4 deletions src/app/route/route-info/route-info.component.css
Original file line number Diff line number Diff line change
@@ -1,21 +1,57 @@
.flex-item {
text-align: center;
}

.flex-container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
justify-content: center;
justify-content: space-around;
width: 100%;
}

.flex-item {
flex: 1 1 auto;
text-align: center;

.route-button {
height: 30px;
width: 30px;
background-color: white;
color: #10898d;
margin-left: 10px;
font-size: 2.5rem;
display: flex;
justify-content: center;
align-items: center;
}

.background-animation {
animation: background-change 1s infinite;
animation-duration: 1s;
}

@keyframes background-change {
0% {
background-color: #10898d;

}
50% {
background-color: #046169;

}
100% {
background-color: #10898d;

}
}


@media (max-width: 900px) {
* {
font-size: 1rem;
}

.route-button {
height: 20px;
width: 20px;
}
}
Loading

0 comments on commit dda7e03

Please sign in to comment.