Skip to content

Commit

Permalink
Merge pull request #30 from uzh-ase-fs24/27-integrate-guesses-api-wit…
Browse files Browse the repository at this point in the history
…h-frontend

27 integrate guesses api with frontend
  • Loading branch information
chrsBa authored Apr 22, 2024
2 parents 08bfa50 + 890fca5 commit 2271580
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 17 deletions.
10 changes: 10 additions & 0 deletions src/app/home/tabs/feed/data-access/feed-state.service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { computed, effect, inject, Injectable, signal } from '@angular/core';
import { connect } from 'ngxtension/connect';
import { Coordinate } from 'ol/coordinate';
import { forkJoin, map, Subject, switchMap } from 'rxjs';
import { User } from 'src/app/model/user';
import { LocationRiddle } from '../../../../model/location-riddle';
Expand Down Expand Up @@ -32,6 +33,7 @@ export class FeedStateService {

// Action Sources (Subjects)
public refresh = new Subject<void>();
public submitGuess = new Subject<{ locationRiddleId: string; guess: Coordinate }>();

// Sources (Observables)
private locationRiddlesSource = this.locationRiddleApiService.getLocationRiddles();
Expand All @@ -45,6 +47,9 @@ export class FeedStateService {
);
private refreshLocationRiddlesSource = this.refresh.pipe(switchMap(() => this.locationRiddlesSource));
private refreshUsersSource = this.refresh.pipe(switchMap(() => this.usersSource));
private submitGuessSource = this.submitGuess.pipe(
switchMap(({ locationRiddleId, guess }) => this.locationRiddleApiService.postGuess(locationRiddleId, guess))
);

constructor() {
// Reducers
Expand All @@ -61,6 +66,11 @@ export class FeedStateService {
}))
.with(this.refreshUsersSource, (state, users) => ({
users: users
}))
.with(this.submitGuessSource, (state, updatedRiddle) => ({
locationRiddles: state.locationRiddles.map((riddle) =>
riddle.locationRiddleId === updatedRiddle.locationRiddleId ? updatedRiddle : riddle
)
}));

effect(() => console.info('Feed State Change: ', this.state()));
Expand Down
1 change: 1 addition & 0 deletions src/app/home/tabs/feed/feed.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
[createdAt]="item.createdAt"
[rating]="item.rating"
[comments]="item.comments"
(submitGuess)="feedState.submitGuess.next({ locationRiddleId: item.locationRiddleId, guess: $event })"
></app-location-riddle-post>
} @empty {
<div class="base-container">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,21 @@ <h2>{{ username() }}</h2>
</ion-card-header>
<ion-card-content style="height: 40vh; min-height: 30rem">
@if (showMap()) {
<app-map [(markerCoordinates)]="guessedLocation"></app-map>
<app-map (placeMarker)="placeGuess($event)" [markerCoordinates]="[guess()]"></app-map>
} @else {
<ion-img src="data:image;base64, {{ locationRiddleImage() }}"></ion-img>
}
<ion-fab horizontal="end" slot="fixed" vertical="bottom">
<ion-fab horizontal="start" slot="fixed" vertical="bottom">
<ion-fab-button (click)="toggleMap()">
<ion-icon name="{{ showMap() ? 'image' : 'map' }}-outline"></ion-icon>
</ion-fab-button>
</ion-fab>
@if(guess() && !submitted()){
<ion-fab horizontal="end" slot="fixed" vertical="bottom">
<ion-fab-button color="success" (click)="submit()">
<ion-icon color="dark" name="checkmark-outline"></ion-icon>
</ion-fab-button>
</ion-fab>
}
</ion-card-content>
</ion-card>
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { CommonModule } from '@angular/common';
import { Component, input, signal } from '@angular/core';
import { Component, input, output, signal } from '@angular/core';
import {
IonAvatar,
IonCard,
Expand Down Expand Up @@ -46,17 +46,27 @@ export class LocationRiddlePostComponent {
rating = input<number>();
createdAt = input<number>();

submitGuess = output<Coordinate>();

showMap = signal(false);
guessedLocation?: Coordinate;
imageHeight = signal(null);
guess = signal<Coordinate | null>(null);
submitted = signal(false);

constructor() {}

toggleMap() {
this.showMap.set(!this.showMap());
}

submitGuess() {
console.log(this.guessedLocation);
placeGuess(guess: Coordinate) {
this.guess.set(guess);
}

submit() {
if (this.guess()) {
// The flow prevents the guess from being null, but for the sake of typing we define a fallback
this.submitGuess.emit(this.guess() || []);
this.submitted.set(true);
}
}
}
2 changes: 1 addition & 1 deletion src/app/home/tabs/post/post.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ <h2>Mark the image location on the map</h2>
</div>

<div class="center-container">
<app-map class="map-container" (markerCoordinatesChange)="postState.setLocation.next($event)"></app-map>
<app-map class="map-container" (placeMarker)="postState.setLocation.next($event)"></app-map>
</div>

<div class="center-container" style="margin-top: 5vh">
Expand Down
18 changes: 18 additions & 0 deletions src/app/services/api/location-riddle-api.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { map, Observable } from 'rxjs';
import { environment } from '../../../environments/environment';
import { LocationRiddle, LocationRiddleDto, LocationRiddlePostDto } from '../../model/location-riddle';
import { AuthService } from '../auth/auth.service';
import { Coordinate } from 'ol/coordinate';

@Injectable()
export class LocationRiddleApiService {
Expand Down Expand Up @@ -32,4 +33,21 @@ export class LocationRiddleApiService {
postLocationRiddle(locationRiddle: LocationRiddlePostDto): Observable<void> {
return this.http.post<void>(environment.api.url + '/location-riddles', locationRiddle);
}

postGuess(locationRiddleId: string, guess: Coordinate): Observable<LocationRiddle> {
return this.http.post<LocationRiddleDto>(environment.api.url + '/location-riddles/' + locationRiddleId + '/guess', {
guess: guess
}).pipe(
map((dto: LocationRiddleDto) => {
return {
locationRiddleId: dto.location_riddle_id,
userId: dto.user_id,
comments: dto.comments,
locationRiddleImage: dto.location_riddle_image.image_base64,
createdAt: dto.created_at,
rating: dto.rating
};
})
);
}
}
1 change: 0 additions & 1 deletion src/app/shared/map/map.component.html

This file was deleted.

21 changes: 13 additions & 8 deletions src/app/shared/map/map.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,22 @@ import { Icon, Style } from 'ol/style';

@Component({
selector: 'app-map',
templateUrl: './map.component.html',
styleUrls: ['./map.component.scss'],
standalone: true
standalone: true,
template: ` <div #mapElement class="map"></div> `
})
export class MapComponent {
@ViewChild('mapElement') set content(mapElement: ElementRef) {
this.initMap(mapElement);
}

markerCoordinates = input<Coordinate>();
markerCoordinatesChange = output<Coordinate>();
center = input<Coordinate>();
markerCoordinates = input<(Coordinate | null)[]>([]);
placeMarker = output<Coordinate>();

map?: Map;
defaultMapCenter = [914135.8295099558, 5901532.510434296]; // central of europe
placedMarker?: Coordinate;

private vectorSource = new VectorSource();
private vectorLayer = new VectorLayer({
Expand All @@ -45,17 +47,20 @@ export class MapComponent {
],
controls: [],
view: new View({
center: this.markerCoordinates() || this.defaultMapCenter, // central of europe
zoom: this.markerCoordinates() ? 16 : 4
center: this.center() || this.placedMarker || this.defaultMapCenter, // central of europe
zoom: this.center() || this.placeMarker ? 4 : 16
})
});

this.removeMapAttribution();

if (this.markerCoordinates()) this.addMarker(this.markerCoordinates()!);
this.markerCoordinates().forEach((coordinate) => {
if (coordinate) this.addMarker(coordinate);
});

this.map.on('click', (event) => {
this.addMarker(event.coordinate, true);
this.placedMarker = event.coordinate;
});
}

Expand All @@ -76,7 +81,7 @@ export class MapComponent {
);

this.vectorSource.addFeature(marker);
if (emit) this.markerCoordinatesChange.emit(coordinate);
if (emit) this.placeMarker.emit(coordinate);
}

removeMapAttribution() {
Expand Down

0 comments on commit 2271580

Please sign in to comment.