refactor: polish map module ui/ux

This commit is contained in:
Rainer Killinger
2022-09-08 14:44:20 +00:00
parent 37dd29a60f
commit 855531fefb
20 changed files with 119 additions and 77 deletions

View File

@@ -51,7 +51,7 @@ export class AboutLicensesComponent implements OnInit {
modal.dismiss();
},
},
swipeToClose: true,
canDismiss: true,
});
return await modal.present();
}

View File

@@ -249,7 +249,7 @@ export class AddEventPopoverComponent implements OnInit, OnDestroy {
async export() {
const modal = await this.modalController.create({
component: AddEventReviewModalComponent,
swipeToClose: true,
canDismiss: true,
cssClass: 'add-modal',
componentProps: {
dismissAction: () => {

View File

@@ -22,7 +22,7 @@
<ion-modal
trigger="show-more"
[presentingElement]="routerOutlet.nativeEl"
swipeToClose="true"
canDismiss="true"
class="modal-large"
>
<ng-template>
@@ -31,14 +31,6 @@
</ng-template>
</ion-modal>
<stapps-skeleton-list-item *ngIf="!item"></stapps-skeleton-list-item>
<ion-button
size="small"
fill="clear"
class="close"
(click)="onCloseClick()"
>
<ion-icon name="cancel" fill></ion-icon>
</ion-button>
</ion-card-header>
<ion-card-content>
<ion-note>
@@ -52,7 +44,7 @@
}}</ion-button>
<ion-modal
trigger="show-more-button"
swipeToClose="true"
canDismiss="true"
[presentingElement]="routerOutlet.nativeEl"
class="modal-large"
>

View File

@@ -22,7 +22,7 @@ import {
SCUuid,
} from '@openstapps/core';
import {Point, Polygon} from 'geojson';
import {divIcon, geoJSON, icon, LatLng, Map, marker, Marker} from 'leaflet';
import {divIcon, geoJSON, LatLng, Map, marker, Marker} from 'leaflet';
import {DataProvider} from '../data/data.provider';
import {MapPosition, PositionService} from './position.service';
import {hasValidLocation} from '../data/types/place/place-types';
@@ -45,14 +45,20 @@ export class MapProvider {
* Provide a point marker for a leaflet map
*
* @param point Point to get marker for
* @param className CSS class name
* @param iconSize Size of the position icon
*/
static getPointMarker(point: Point) {
static getPointMarker(point: Point, className: string, iconSize: number) {
return marker(geoJSON(point).getBounds().getCenter(), {
icon: icon({
iconAnchor: [13, 41],
iconSize: [25, 41],
iconUrl: '../assets/marker-icon.png',
shadowUrl: '../assets/marker-shadow.png',
icon: divIcon({
className: className,
html: `<span
name="${SCIcon`location_on`}"
class="material-symbols-rounded map-location-pin"
style="font-size: ${iconSize}px;"
>${SCIcon`location_on`}</span>`,
iconSize: [iconSize, iconSize],
iconAnchor: [iconSize / 2, iconSize],
}),
});
}
@@ -80,12 +86,13 @@ export class MapProvider {
transform-origin: center;
transform: rotate(${position.heading}deg);
font-size: ${iconSize}px;
color: var(--ion-color-primary);
"
>${SCIcon`navigation`}</span>`
: `<span
name="${SCIcon`person_pin_circle`}"
class="material-symbols-rounded map-location-pin"
style="font-size: ${iconSize}px;"
style="font-size: ${iconSize}px; color: var(--ion-color-primary);"
>${SCIcon`person_pin_circle`}</span>`,
iconSize: [iconSize, iconSize],
}),

View File

@@ -13,7 +13,6 @@
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {Location} from '@angular/common';
import {trigger, style, animate, transition} from '@angular/animations';
import {
ChangeDetectorRef,
Component,
@@ -60,24 +59,6 @@ import {Capacitor} from '@capacitor/core';
styleUrls: ['./map-page.scss'],
templateUrl: './map-page.html',
providers: [ContextMenuService],
animations: [
trigger('fadeInOut', [
transition(':enter', [
style({transform: 'translateY(200%)', opacity: 0}),
animate(
'500ms ease-in-out',
style({transform: 'translateY(0%)', opacity: 1}),
),
]),
transition(':leave', [
style({transform: 'translateY(0%)', opacity: 1}),
animate(
'500ms ease-in-out',
style({transform: 'translateY(200%)', opacity: 0}),
),
]),
]),
],
})
export class MapPageComponent {
/**
@@ -230,7 +211,11 @@ export class MapPageComponent {
return polygonLayer.on('click', this.showItem.bind(this, place.uid));
}
const markerLayer = MapProvider.getPointMarker(place.geo.point);
const markerLayer = MapProvider.getPointMarker(
place.geo.point,
'stapps-location',
32,
);
return markerLayer.on('click', this.showItem.bind(this, place.uid));
};
@@ -327,7 +312,7 @@ export class MapPageComponent {
this.positionMarker = MapProvider.getPositionMarker(
position,
'stapps-device-location',
30,
32,
);
},
error: async _error => {
@@ -407,14 +392,13 @@ export class MapPageComponent {
await (
await this.alertController.create({
header: location.TITLE,
subHeader: location.SUBTITLE,
message: `${
this.locationStatus?.location === 'denied'
? location.NOT_ALLOWED
: this.locationStatus?.location !== 'granted'
? location.NOT_ENABLED
: unknownError
}.`,
}`,
buttons: ['OK'],
})
).present();

View File

@@ -59,7 +59,6 @@
<div class="map-buttons above">
<ion-button
*ngIf="items.length > 1"
[@fadeInOut]
color="light"
shape="round"
size="small"
@@ -70,24 +69,31 @@
}}
</ion-button>
<ion-button
[disabled]="position === undefined"
color="light"
shape="round"
size="small"
(click)="onPositionClick()"
>
<ion-icon
*ngIf="position !== null; else questionIcon"
*ngIf="position !== null; else noLocationIcon"
name="my_location"
></ion-icon>
<ng-template #questionIcon>
<ion-icon name="location_searching"></ion-icon>
<ng-template #noLocationIcon>
<ion-icon
*ngIf="
locationStatus.location !== 'denied';
else deniedLocationIcon
"
name="location_searching"
></ion-icon>
</ng-template>
<ng-template #deniedLocationIcon>
<ion-icon name="location_disabled"></ion-icon>
</ng-template>
</ion-button>
</div>
<stapps-map-item
*ngIf="items.length === 1"
[@fadeInOut]
[item]="items[0]"
(onClose)="resetView()"
></stapps-map-item>
@@ -95,7 +101,6 @@
<div class="map-buttons floating-buttons">
<ion-button
*ngIf="items.length > 1"
[@fadeInOut]
color="light"
shape="round"
size="small"
@@ -106,24 +111,29 @@
}}
</ion-button>
<ion-button
[disabled]="position === undefined"
color="light"
shape="round"
size="small"
(click)="onPositionClick()"
>
<ion-icon
*ngIf="position !== null; else questionIcon"
*ngIf="position !== null; else noLocationIcon"
name="my_location"
></ion-icon>
<ng-template #questionIcon>
<ion-icon name="location_searching"></ion-icon>
<ng-template #noLocationIcon>
<ion-icon
*ngIf="locationStatus.location !== 'denied'; else deniedLocationIcon"
name="location_searching"
></ion-icon>
</ng-template>
<ng-template #deniedLocationIcon>
<ion-icon name="location_disabled"></ion-icon>
</ng-template>
</ion-button>
</div>
<ion-modal
[swipeToClose]="true"
[canDismiss]="true"
[presentingElement]="routerOutlet.nativeEl"
#mapListModal
>
@@ -131,6 +141,7 @@
<map-list-modal
style="height: 100%"
[filterQuery]="filterQuery"
[mapBounds]="this.map.getBounds()"
[queryText]="queryText"
></map-list-modal>
</ng-template>

View File

@@ -4,6 +4,7 @@ ion-content {
div.map-container {
width: 100%;
height: 100%;
position: fixed;
}
& > div {
overflow: hidden;
@@ -33,7 +34,7 @@ ion-toolbar:first-of-type {
div.floating-content {
display: block;
position: absolute;
position: fixed;
left: 0;
right: 0;
bottom: 0;
@@ -41,7 +42,7 @@ ion-toolbar:first-of-type {
width: 100%;
padding: 0 var(--spacing-md) 8vh;
justify-content: center;
ion-card {
margin: 0;
}

View File

@@ -13,9 +13,10 @@
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {Component, Input, OnInit} from '@angular/core';
import {SCPlace, SCSearchFilter} from '@openstapps/core';
import {SCSearchBooleanFilter, SCPlace, SCSearchFilter} from '@openstapps/core';
import {MapProvider} from '../../map.provider';
import {ModalController} from '@ionic/angular';
import {LatLngBounds} from 'leaflet';
/**
* Modal showing a provided list of places
@@ -31,6 +32,11 @@ export class MapListModalComponent implements OnInit {
*/
@Input() filterQuery?: SCSearchFilter;
/**
* Map visible boundaries limiting items in lust
*/
@Input() mapBounds?: LatLngBounds;
/**
* Places to show in the list
*/
@@ -50,8 +56,44 @@ export class MapListModalComponent implements OnInit {
* Populate the list with the results from the search
*/
ngOnInit() {
let geofencedFilter: SCSearchBooleanFilter | undefined;
if (typeof this.mapBounds !== 'undefined') {
geofencedFilter = {
arguments: {
operation: 'and',
filters: [
{
type: 'geo',
arguments: {
field: 'geo',
shape: {
coordinates: [
[
this.mapBounds.getNorthWest().lng,
this.mapBounds.getNorthWest().lat,
],
[
this.mapBounds.getSouthEast().lng,
this.mapBounds.getSouthEast().lat,
],
],
type: 'envelope',
},
spatialRelation: 'intersects',
},
},
],
},
type: 'boolean',
};
if (typeof this.filterQuery !== 'undefined') {
geofencedFilter.arguments.filters.push(this.filterQuery);
}
}
const geofencedFilterQuery = geofencedFilter ?? this.filterQuery;
this.mapProvider
.searchPlaces(this.filterQuery, this.queryText)
.searchPlaces(geofencedFilterQuery, this.queryText)
.then(result => {
this.items = result.data as SCPlace[];
});

View File

@@ -58,7 +58,11 @@ export class MapWidgetComponent implements OnInit {
* Prepare the map
*/
ngOnInit() {
const markerLayer = MapProvider.getPointMarker(this.place.geo.point);
const markerLayer = MapProvider.getPointMarker(
this.place.geo.point,
'stapps-location',
32,
);
this.options = {
center: geoJSON(this.place.geo.polygon || this.place.geo.point)
.getBounds()

View File

@@ -17,6 +17,7 @@
type="overlay"
menuId="context"
contentId="{{ contentId }}"
maxEdgeStart="0"
side="end"
>
<ion-toolbar color="primary" mode="ios">

View File

@@ -44,7 +44,7 @@ export class ModalEventCreatorComponent implements OnInit, OnDestroy {
isModal: true,
inputItem: item,
},
swipeToClose: true,
canDismiss: true,
presentingElement: await this.modalController.getTop(),
});
return modal.present();

View File

@@ -81,7 +81,7 @@
</ion-fab>
<ion-modal
swipeToClose="true"
canDismiss="true"
[presentingElement]="routerOutlet.nativeEl"
[isOpen]="isModalOpen"
(ionModalWillDismiss)="onModalDismiss()"

View File

@@ -112,7 +112,7 @@ export class CalendarSyncSettingsComponent implements OnInit {
const modal = await this.modalController.create({
component: AddEventReviewModalComponent,
swipeToClose: true,
canDismiss: true,
cssClass: 'add-modal',
componentProps: {
dismissAction: () => {

View File

@@ -213,10 +213,9 @@
"MORE": "Mehr"
},
"geolocation": {
"TITLE": "Standort",
"SUBTITLE": "Standort nicht erreichbar",
"NOT_ENABLED": "Standortermittlung auf Deinem Gerät ist nicht aktiviert",
"NOT_ALLOWED": "Zugriff auf den Standort für die App nicht zugelassen"
"TITLE": "Standort nicht verfügbar",
"NOT_ENABLED": "Die Standortermittlung auf dem Gerät ist nicht aktiviert",
"NOT_ALLOWED": "Du hast den Zugriff auf deinen Standort für diese App abgelehnt. Nutze die Datenschutz-Einstellungen deines Gerätes um den Zugriff zu erlauben."
}
},
"modals": {

View File

@@ -213,10 +213,9 @@
"MORE": "More"
},
"geolocation": {
"TITLE": "Location",
"SUBTITLE": "Location not available",
"NOT_ENABLED": "Location service is not enabled on your device",
"NOT_ALLOWED": "The app is not allowed to access your location"
"TITLE": "Location not available",
"NOT_ENABLED": "Location services are not enabled on your device",
"NOT_ALLOWED": "The app is not allowed to access your location. Use your device privacy settings to allow it again."
}
},
"modals": {

Binary file not shown.

View File

@@ -45,7 +45,7 @@ stapps-icon {
.map-location-pin {
font-variation-settings: 'FILL' 1;
color: var(--ion-color-primary);
color: var(--ion-color-tertiary);
&::before {
content: attr(name);