-
-
- 1"
- color="light"
- shape="round"
- size="small"
- (click)="mapListModal.present()"
- >
- {{ 'map.page.buttons.SHOW_LIST' | translate }}
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/frontend/app/src/app/modules/map/page/map-page.scss b/frontend/app/src/app/modules/map/page/map-page.scss
index 01563e90..e9b6ce47 100644
--- a/frontend/app/src/app/modules/map/page/map-page.scss
+++ b/frontend/app/src/app/modules/map/page/map-page.scss
@@ -12,113 +12,87 @@
* You should have received a copy of the GNU General Public License along with
* this program. If not, see .
*/
+@import '../../../../theme/util/mixins';
-ion-content {
- // fixes the unexpected issue that the content is not fullscreen (behind the header)
- position: absolute;
+$bottom-offset: 7px; // no idea what happened here
- div.map-container {
- position: fixed;
- width: 100%;
- height: 100%;
- }
-
- & > div {
- overflow: hidden;
- }
+.map-container {
+ width: 100%;
+ height: 100%;
}
ion-toolbar:first-of-type {
padding: 0 var(--spacing-md) var(--spacing-xs);
}
-div.map-buttons {
+.floating-content {
+ position: fixed;
+ z-index: 1000;
+ right: 0;
+ bottom: 0;
+ left: 0;
+
+ display: flex;
+ flex-flow: row-reverse wrap;
+ align-items: flex-end;
+ justify-content: space-between;
+}
+
+.map-buttons {
+ display: flex;
+ justify-content: flex-end;
+
ion-button {
// important for iOS
// TODO: find an option that is better suited for the iOS theme
--box-shadow: var(--map-box-shadow);
align-self: flex-end;
- margin: 4px;
+ margin: var(--spacing-md);
+
+ &.location-button {
+ view-transition-name: location-button;
+ }
}
}
-::ng-deep {
- .stapps-location {
- ion-icon {
- width: 100%;
- height: 100%;
- color: #fd435c;
- }
- }
+.map-item {
+ position: relative;
+ max-width: 550px;
+ margin: var(--spacing-md);
- .stapps-device-location {
- ion-icon {
- width: 100%;
- height: 100%;
- color: #4387fd;
- }
- }
-
- div.floating-content {
- position: fixed;
- z-index: 1000;
+ .close {
+ position: absolute;
+ top: 0;
right: 0;
- bottom: 0;
- left: 0;
+ }
- display: block;
- justify-content: center;
+ ::ng-deep ion-item {
+ margin: 0;
+ }
+}
+@include ion-md-down {
+ .md {
+ ion-content {
+ --padding-bottom: $bottom-offset;
+ }
+
+ .floating-content {
+ bottom: $bottom-offset;
+ }
+ }
+
+ .map-buttons ion-button {
+ margin: var(--spacing-sm);
+ }
+
+ .map-item {
width: 100%;
- padding: 0 var(--spacing-md) 8vh;
+ max-width: unset;
+ margin: 0;
- ion-card {
- margin: 0;
- }
-
- div.map-buttons {
- display: flex;
- justify-content: flex-end;
- }
-
- stapps-map-item {
- position: center;
- justify-self: center;
- width: 550px;
- margin: var(--spacing-sm) auto;
- }
- }
-}
-
-div.floating-buttons {
- position: absolute;
- z-index: 1000;
- right: 10px;
- bottom: 15px;
-}
-
-div.map-buttons.above {
- display: none;
- min-width: 70%;
-}
-
-@media (width <= 667px) {
- div.map-buttons.above {
- display: flex;
- }
-
- div.floating-content {
- justify-content: normal;
- padding: 0 var(--spacing-md) var(--spacing-lg);
-
- stapps-map-item {
- display: grid;
- width: 100%;
- }
- }
-
- div.map-buttons.floating-buttons {
- display: none;
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
}
}
diff --git a/frontend/app/src/app/modules/map/page/modals/map-single.scss b/frontend/app/src/app/modules/map/page/modals/map-single.scss
deleted file mode 100644
index 4cef8a0c..00000000
--- a/frontend/app/src/app/modules/map/page/modals/map-single.scss
+++ /dev/null
@@ -1,4 +0,0 @@
-:host {
- display: flex;
- flex-direction: column;
-}
diff --git a/frontend/app/src/app/modules/map/widget/map-widget.component.ts b/frontend/app/src/app/modules/map/widget/map-widget.component.ts
index 7f522634..74477408 100644
--- a/frontend/app/src/app/modules/map/widget/map-widget.component.ts
+++ b/frontend/app/src/app/modules/map/widget/map-widget.component.ts
@@ -12,9 +12,9 @@
* You should have received a copy of the GNU General Public License along with
* this program. If not, see .
*/
-import {Component, ElementRef, Input, OnInit, ViewChild} from '@angular/core';
+import {Component, ElementRef, HostBinding, Input, OnInit, ViewChild} from '@angular/core';
import {Router} from '@angular/router';
-import {SCPlace} from '@openstapps/core';
+import {SCPlaceWithoutReferences, SCThingWithoutReferences} from '@openstapps/core';
import {geoJSON, Map, MapOptions, tileLayer} from 'leaflet';
import {MapProvider} from '../map.provider';
@@ -27,6 +27,8 @@ import {MapProvider} from '../map.provider';
templateUrl: './map-widget.html',
})
export class MapWidgetComponent implements OnInit {
+ @HostBinding('class.expand-when-space') expandWhenSpace = true;
+
/**
* A leaflet map showed
*/
@@ -45,7 +47,7 @@ export class MapWidgetComponent implements OnInit {
/**
* A place to show on the map
*/
- @Input() place: SCPlace;
+ @Input() place: SCThingWithoutReferences & Pick;
/**
* Indicates if the expand button should be visible
diff --git a/frontend/app/src/app/modules/map/widget/map-widget.html b/frontend/app/src/app/modules/map/widget/map-widget.html
index c0bb910b..5077d6d2 100644
--- a/frontend/app/src/app/modules/map/widget/map-widget.html
+++ b/frontend/app/src/app/modules/map/widget/map-widget.html
@@ -21,6 +21,10 @@
[leafletOptions]="options"
>
+
+
+ {{'map.directions.TITLE' | translate}}
+
diff --git a/frontend/app/src/app/modules/map/widget/map-widget.scss b/frontend/app/src/app/modules/map/widget/map-widget.scss
index abd4ae60..7cbe7ef2 100644
--- a/frontend/app/src/app/modules/map/widget/map-widget.scss
+++ b/frontend/app/src/app/modules/map/widget/map-widget.scss
@@ -12,6 +12,12 @@
* You should have received a copy of the GNU General Public License along with
* this program. If not, see .
*/
+:host {
+ position: relative;
+ width: auto;
+ height: 300px;
+ min-height: 300px;
+}
div.map-container {
pointer-events: none;
diff --git a/frontend/app/src/app/translation/i18n.spec.ts b/frontend/app/src/app/translation/i18n.spec.ts
index a6f96bd8..4672a619 100644
--- a/frontend/app/src/app/translation/i18n.spec.ts
+++ b/frontend/app/src/app/translation/i18n.spec.ts
@@ -17,23 +17,31 @@
import english from '../../assets/i18n/en.json';
import german from '../../assets/i18n/de.json';
-const exceptions = new Set([
- 'login',
- 'ok',
- 'protein',
- 'feedback',
- 'name',
- 'status',
- 'issn',
- 'ejournal',
- 'backup',
- 'export',
- 'dashboard',
- 'home',
- 'email',
- 'logins',
- 'https://www.swffm.de/essen-trinken/uebersicht/umweltscore',
-]);
+const exceptions = new Set(
+ [
+ 'login',
+ 'ok',
+ 'protein',
+ 'feedback',
+ 'name',
+ 'status',
+ 'issn',
+ 'ejournal',
+ 'backup',
+ 'export',
+ 'dashboard',
+ 'home',
+ 'email',
+ 'logins',
+ 'google maps',
+ 'apple maps',
+ 'openstreetmaps routing',
+ 'https://www.swffm.de/essen-trinken/uebersicht/umweltscore',
+ 'https://www.google.com/maps/dir/?api=1&destination={{lat}},{{lon}}&origin={{posLat}},{{posLon}}',
+ 'https://maps.apple.com/?daddr={{lat}},{{lon}}&saddr={{posLat}},{{posLon}}',
+ 'https://www.openstreetmap.org/directions?from={{posLat}},{{posLon}}&to={{lat}},{{lon}}#map=15/{{lat}}/{{lon}}',
+ ].map(it => it.toLowerCase()),
+);
const languages = [
['english', english],
diff --git a/frontend/app/src/app/util/view-transition.ts b/frontend/app/src/app/util/view-transition.ts
new file mode 100644
index 00000000..afea72f1
--- /dev/null
+++ b/frontend/app/src/app/util/view-transition.ts
@@ -0,0 +1,14 @@
+/**
+ * Performs a view transition
+ *
+ * This is a progressive enhancement for (as of right now) Chromium-based browsers
+ * - Firefox position: [positive](https://mozilla.github.io/standards-positions/#view-transitions)
+ * - WebKit position: [support](https://github.com/WebKit/standards-positions/issues/48#issuecomment-1679760489)
+ */
+export function startViewTransition(runner: () => Promise) {
+ if ('startViewTransition' in document) {
+ document.startViewTransition(runner);
+ } else {
+ void runner();
+ }
+}
diff --git a/frontend/app/src/assets/i18n/de.json b/frontend/app/src/assets/i18n/de.json
index 50bf50f4..bbd07cb6 100644
--- a/frontend/app/src/assets/i18n/de.json
+++ b/frontend/app/src/assets/i18n/de.json
@@ -244,6 +244,25 @@
}
},
"map": {
+ "directions": {
+ "TITLE": "Anbindung",
+ "TITLE_LONG": "Anbindung nach {{name}}",
+ "ADDRESS": "{{streetAddress}}, {{postalCode}} {{addressLocality}}",
+ "COPY_ADDRESS": "Adresse kopieren",
+ "ADDRESS_COPIED": "Adresse wurde kopiert",
+ "GOOGLE_MAPS": {
+ "TITLE": "Google Maps",
+ "URL": "https://www.google.com/maps/dir/?api=1&destination={{lat}},{{lon}}&origin={{posLat}},{{posLon}}"
+ },
+ "APPLE_MAPS": {
+ "TITLE": "Apple Maps",
+ "URL": "https://maps.apple.com/?daddr={{lat}},{{lon}}&saddr={{posLat}},{{posLon}}"
+ },
+ "OSM_ROUTING": {
+ "TITLE": "OpenStreetMaps Routing",
+ "URL": "https://routing.openstreetmap.de/?loc={{posLat}},{{posLon}}&loc={{lat}},{{lon}}&srv=2&hl=de"
+ }
+ },
"page": {
"TITLE": "Karte",
"search_bar": {
diff --git a/frontend/app/src/assets/i18n/en.json b/frontend/app/src/assets/i18n/en.json
index 21b4f93a..3b6350ff 100644
--- a/frontend/app/src/assets/i18n/en.json
+++ b/frontend/app/src/assets/i18n/en.json
@@ -244,6 +244,25 @@
}
},
"map": {
+ "directions": {
+ "TITLE": "Directions",
+ "TITLE_LONG": "Directions to {{name}}",
+ "ADDRESS": "{{streetAddress}}, {{addressLocality}} {{postalCode}}",
+ "COPY_ADDRESS": "Copy Address",
+ "ADDRESS_COPIED": "Address copied",
+ "GOOGLE_MAPS": {
+ "TITLE": "Google Maps",
+ "URL": "https://www.google.com/maps/dir/?api=1&destination={{lat}},{{lon}}&origin={{posLat}},{{posLon}}"
+ },
+ "APPLE_MAPS": {
+ "TITLE": "Apple Maps",
+ "URL": "https://maps.apple.com/?daddr={{lat}},{{lon}}&saddr={{posLat}},{{posLon}}"
+ },
+ "OSM_ROUTING": {
+ "TITLE": "OpenStreetMaps Routing",
+ "URL": "https://routing.openstreetmap.de/?loc={{posLat}},{{posLon}}&loc={{lat}},{{lon}}&srv=2&hl=en"
+ }
+ },
"page": {
"TITLE": "Map",
"search_bar": {
diff --git a/frontend/app/src/assets/icons.min.woff2 b/frontend/app/src/assets/icons.min.woff2
index 3cc1beeb..433d5e16 100644
Binary files a/frontend/app/src/assets/icons.min.woff2 and b/frontend/app/src/assets/icons.min.woff2 differ
diff --git a/frontend/app/src/global.scss b/frontend/app/src/global.scss
index aaaebff5..5848a75f 100644
--- a/frontend/app/src/global.scss
+++ b/frontend/app/src/global.scss
@@ -131,6 +131,18 @@ ion-alert {
}
}
+.stapps-location ion-icon {
+ width: 100%;
+ height: 100%;
+ color: #fd435c;
+}
+
+.stapps-device-location ion-icon {
+ width: 100%;
+ height: 100%;
+ color: #4387fd;
+}
+
.add-event-popover {
--width: fit-content;
--max-width: 95%;
diff --git a/frontend/app/tsconfig.spec.json b/frontend/app/tsconfig.spec.json
index 59fb1e3c..4e9b391c 100644
--- a/frontend/app/tsconfig.spec.json
+++ b/frontend/app/tsconfig.spec.json
@@ -2,7 +2,7 @@
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/spec",
- "types": ["jasmine", "node"],
+ "types": ["jasmine", "node", "dom-view-transitions"],
"paths": {
"@capacitor/*": ["__mocks__/@capacitor/*"]
}
diff --git a/images/app-cypress/package.json b/images/app-cypress/package.json
index 2fe83fc2..e065a398 100644
--- a/images/app-cypress/package.json
+++ b/images/app-cypress/package.json
@@ -5,8 +5,7 @@
"type": "module",
"license": "GPL-3.0-only",
"author": "Rainer Killinger ",
- "contributors": [
- ],
+ "contributors": [],
"files": [
"Dockerfile",
"CHANGELOG.md"
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index ca87e354..8dedc830 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -752,6 +752,9 @@ importers:
'@capacitor/browser':
specifier: 4.1.0
version: 4.1.0(@capacitor/core@4.6.1)
+ '@capacitor/clipboard':
+ specifier: 4.1.0
+ version: 4.1.0(@capacitor/core@4.6.1)
'@capacitor/core':
specifier: 4.6.1
version: 4.6.1
@@ -824,6 +827,9 @@ importers:
'@transistorsoft/capacitor-background-fetch':
specifier: 1.0.2
version: 1.0.2(@capacitor/core@4.6.1)
+ '@types/dom-view-transitions':
+ specifier: 1.0.1
+ version: 1.0.1
capacitor-secure-storage-plugin:
specifier: 0.8.1
version: 0.8.1(@capacitor/core@4.6.1)
@@ -1089,6 +1095,8 @@ importers:
images/app-builder: {}
+ images/app-cypress: {}
+
images/node-base: {}
images/node-builder: {}
@@ -4910,6 +4918,14 @@ packages:
- supports-color
dev: true
+ /@capacitor/clipboard@4.1.0(@capacitor/core@4.6.1):
+ resolution: {integrity: sha512-lfUwDqZces3mQcBOyfxpBCsRWWSfLuPzekA1N3RaMgYVhD6/rdzFnzfRiksj1hm4It+lnULK0y+N5nxVnTt+0Q==}
+ peerDependencies:
+ '@capacitor/core': ^4.0.0
+ dependencies:
+ '@capacitor/core': 4.6.1
+ dev: false
+
/@capacitor/core@4.6.1:
resolution: {integrity: sha512-7A2IV9E8umgu9u0fChUTjQJq+Jp25GJZMmWxoQN/nVx/1rcpFJ4m1xo3NPBoIRs+aV7FR+BM17mPrnkKlA8N2g==}
dependencies:
@@ -6735,6 +6751,10 @@ packages:
'@types/node': 18.15.3
dev: false
+ /@types/dom-view-transitions@1.0.1:
+ resolution: {integrity: sha512-A9S1ijj/4MX06I1W/6on8lhaYyq1Ir7gaOvfllW1o4RzVWW88HAeqX0pUx9VgOLnNpdiGeUW2CTkg18p5LWIrA==}
+ dev: false
+
/@types/eslint-scope@3.7.4:
resolution: {integrity: sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==}
dependencies: