feat: apply new layout overhaul

This commit is contained in:
Andy Bastian
2022-08-08 11:01:00 +00:00
committed by Rainer Killinger
parent f16e5394cc
commit 7bbdba5c0b
228 changed files with 28387 additions and 1092 deletions

View File

@@ -8,6 +8,7 @@
trigger="show-more"
[presentingElement]="routerOutlet.nativeEl"
swipeToClose="true"
class="modal-large"
>
<ng-template>
<app-map-single-modal [item]="item" style="height: 100%">
@@ -15,36 +16,35 @@
</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="circle-x"></ion-icon>
</ion-button>
</ion-card-header>
<ion-card-content>
<ion-grid>
<ion-row>
<ion-col size="7">
<ion-note>
<span *ngIf="item.address as address">
<span *ngIf="$any(item).inPlace"
>{{ $any(item).inPlace.name }},</span
>
{{ address.streetAddress }}, {{ address.addressLocality }}
</span>
</ion-note>
</ion-col>
<ion-col size="5">
<ion-button size="small" id="show-more-button"
>More&nbsp;<ion-icon name="information-circle"></ion-icon
></ion-button>
<ion-modal
trigger="show-more-button"
swipeToClose="true"
[presentingElement]="routerOutlet.nativeEl"
>
<ng-template>
<app-map-single-modal [item]="item" style="height: 100%">
</app-map-single-modal>
</ng-template>
</ion-modal>
</ion-col>
</ion-row>
</ion-grid>
<ion-note>
<span *ngIf="item.address as address">
<span *ngIf="$any(item).inPlace">{{ $any(item).inPlace.name }},</span>
{{ address.streetAddress }}, {{ address.addressLocality }}
</span>
</ion-note>
<ion-button size="small" id="show-more-button" fill="clear">{{
'map.page.buttons.MORE' | translate
}}</ion-button>
<ion-modal
trigger="show-more-button"
swipeToClose="true"
[presentingElement]="routerOutlet.nativeEl"
class="modal-large"
>
<ng-template>
<app-map-single-modal [item]="item" style="height: 100%">
</app-map-single-modal>
</ng-template>
</ion-modal>
</ion-card-content>
</ion-card>

View File

@@ -1,8 +1,57 @@
ion-col:nth-child(2) {
display: flex;
justify-content: flex-end;
@import '../../../../theme/util/mixins';
ion-button {
margin-top: auto;
:host {
display: block;
max-width: 100%;
ion-card {
padding: 0;
overflow: visible;
ion-card-header{
padding: 0;
border-bottom: var(--border-width-default) solid var(--border-color-default);
stapps-data-list-item {
--ion-margin: 0;
&::ng-deep ion-item {
--padding-start: 0;
--padding-end: 0;
ion-label {
white-space: break-spaces;
}
}
}
.close {
position: absolute;
top: -15px;
right: -15px;
z-index: 1;
--padding-top: 0;
--padding-bottom: 0;
--padding-start: 0;
--padding-end: 0;
ion-icon {
width: 30px;
height: 30px;
}
}
}
ion-card-content {
padding: var(--spacing-md);
display: flex;
flex-direction: row;
#show-more-button {
text-transform: uppercase;
margin-left: auto;
}
}
}
}

View File

@@ -12,7 +12,7 @@
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {Component, Input} from '@angular/core';
import {Component, EventEmitter, Input, Output} from '@angular/core';
import {SCPlace} from '@openstapps/core';
import {IonRouterOutlet} from '@ionic/angular';
@@ -27,5 +27,15 @@ export class MapItemComponent {
*/
@Input() item: SCPlace;
// eslint-disable-next-line @angular-eslint/no-output-on-prefix
@Output() onClose = new EventEmitter<void>();
constructor(readonly routerOutlet: IonRouterOutlet) {}
/**
* Action when edit is clicked
*/
onCloseClick() {
this.onClose.emit();
}
}

View File

@@ -33,6 +33,7 @@ import {MapListModalComponent} from './page/modals/map-list-modal.component';
import {MapSingleModalComponent} from './page/modals/map-single-modal.component';
import {MapItemComponent} from './item/map-item.component';
import {NgModule} from '@angular/core';
import {UtilModule} from '../../util/util.module';
/**
* Initializes the default area to show in advance (before components are initialized)
@@ -78,6 +79,7 @@ const mapRoutes: Routes = [
DataModule,
FormsModule,
ThingTranslateModule,
UtilModule,
],
providers: [
Geolocation,

View File

@@ -76,7 +76,7 @@ export class MapProvider {
? `<ion-icon name="navigate-straight"
style="transform-origin: center; transform: rotate(${position.heading}deg);">
</ion-icon>`
: '<ion-icon name="locate"></ion-icon>',
: '<ion-icon name="current-location"></ion-icon>',
iconSize: [iconSize, iconSize],
}),
zIndexOffset: 1000,

View File

@@ -13,6 +13,7 @@
* 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,
@@ -59,6 +60,24 @@ 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 {
/**
@@ -242,13 +261,17 @@ export class MapPageComponent {
/**
* Fetches items with set query configuration
*
* @param fetchAll Should fetch all items
* @param animate Should the fly animation be used
*/
async fetchAndUpdateItems(animate?: boolean): Promise<void> {
async fetchAndUpdateItems(
fetchAll = false,
animate?: boolean,
): Promise<void> {
try {
const result = await this.mapProvider.searchPlaces(
this.filterQuery,
this.queryText,
fetchAll ? '' : this.queryText,
);
if (result.data.length === 0) {
const alert = await this.alertController.create({
@@ -353,7 +376,7 @@ export class MapPageComponent {
this.subscriptions.push(
this.contextMenuService.filterQueryChanged$.subscribe(query => {
this.filterQuery = query;
this.fetchAndUpdateItems(true);
this.fetchAndUpdateItems(false, true);
}),
);
@@ -414,7 +437,7 @@ export class MapPageComponent {
*/
async resetView() {
this.location.go('/map');
await this.fetchAndUpdateItems();
await this.fetchAndUpdateItems(this.items.length > 0);
this.ref.detectChanges();
}
@@ -437,7 +460,7 @@ export class MapPageComponent {
*/
searchStringChanged(queryText?: string) {
this.queryText = queryText || '';
void this.fetchAndUpdateItems(true);
void this.fetchAndUpdateItems(false, true);
}
/**
@@ -451,7 +474,7 @@ export class MapPageComponent {
this.distance = this.positionService.getDistance(this.items[0].geo.point);
this.addToMap(this.items, true);
this.ref.detectChanges();
const url = this.router.createUrlTree([[], uid]).toString();
const url = this.router.createUrlTree(['/map', uid]).toString();
this.location.go(url);
// center the selected place
this.focus(geoJSON(this.items[0].geo.point).getBounds().getCenter());

View File

@@ -16,31 +16,39 @@
<stapps-context contentId="map"></stapps-context>
<ion-header class="ion-no-border" translucent="true">
<ion-toolbar>
<ion-toolbar color="primary" mode="ios">
<ion-buttons slot="start">
<ion-back-button
*ngIf="items.length !== 1"
[defaultHref]="'..'"
[text]="'back' | translate | titlecase"
></ion-back-button>
<ion-back-button
*ngIf="items.length === 1"
default-href="/"
[defaultHref]="'..'"
[text]="'back' | translate | titlecase"
(click)="resetView()"
></ion-back-button>
<ion-menu-button></ion-menu-button>
</ion-buttons>
<ion-title>{{ 'map.page.TITLE' | translate }}</ion-title>
</ion-toolbar>
<ion-toolbar color="primary">
<ion-searchbar
(keyup)="searchKeyUp($event)"
(keyup.enter)="hideKeyboard()"
[(ngModel)]="queryText"
(ionClear)="searchStringChanged()"
mode="md"
placeholder="{{ 'map.page.search_bar.placeholder' | translate }}"
showClearButton="always"
type="search"
enterkeyhint="search"
class="filterable"
>
</ion-searchbar>
<ion-buttons slot="end">
<ion-menu-button menu="context" auto-hide="false">
<ion-icon name="filter"></ion-icon>
<ion-icon name="adjustments"></ion-icon>
</ion-menu-button>
</ion-buttons>
</ion-searchbar>
</ion-toolbar>
</ion-header>
@@ -61,6 +69,7 @@
<div class="map-buttons above">
<ion-button
*ngIf="items.length > 1"
[@fadeInOut]
color="light"
shape="round"
size="small"
@@ -79,21 +88,24 @@
>
<ion-icon
*ngIf="position !== null; else questionIcon"
name="locate"
name="current-location"
></ion-icon>
<ng-template #questionIcon>
<ion-icon name="help-circle-outline"></ion-icon>
<ion-icon name="help"></ion-icon>
</ng-template>
</ion-button>
</div>
<stapps-map-item
*ngIf="items.length === 1"
[@fadeInOut]
[item]="items[0]"
(onClose)="resetView()"
></stapps-map-item>
</div>
<div class="map-buttons floating-buttons">
<ion-button
*ngIf="items.length > 1"
[@fadeInOut]
color="light"
shape="round"
size="small"
@@ -112,10 +124,10 @@
>
<ion-icon
*ngIf="position !== null; else questionIcon"
name="locate"
name="current-location"
></ion-icon>
<ng-template #questionIcon>
<ion-icon name="help-circle-outline"></ion-icon>
<ion-icon name="help"></ion-icon>
</ng-template>
</ion-button>
</div>

View File

@@ -1,22 +1,3 @@
ion-header {
ion-toolbar {
--background: transparent;
--ion-color-base: transparent;
ion-buttons {
ion-back-button::part(native), ion-menu-button::part(native) {
box-shadow: var(--map-box-shadow);
//padding: 2px;
}
}
}
ion-searchbar {
--background: white;
// important for iOS
--box-shadow: var(--map-box-shadow);
}
}
ion-content {
// fixes the unexpected issue that the content is not fullscreen (behind the header)
position: absolute;
@@ -24,12 +5,13 @@ ion-content {
width: 100%;
height: 100%;
}
& > div {
overflow: hidden;
}
}
ion-back-button, ion-menu-button {
--background: white;
--background-hover: whitesmoke;
--background-focused: whitesmoke;
ion-toolbar:first-of-type {
padding: 0 var(--spacing-md) var(--spacing-xs);
}
::ng-deep {
@@ -50,14 +32,20 @@ ion-back-button, ion-menu-button {
}
div.floating-content {
display: grid;
display: block;
position: absolute;
bottom: 15px;
left: 0;
right: 0;
bottom: 0;
z-index: 1000;
width: 100%;
padding: 0 20px;
padding: 0 var(--spacing-md) 8vh;
justify-content: center;
ion-card {
margin: 0;
}
div.map-buttons {
display: flex;
justify-content: flex-end;
@@ -67,7 +55,7 @@ ion-back-button, ion-menu-button {
width: 550px;
position: center;
justify-self: center;
margin: 2px;
margin: var(--spacing-sm) auto;
}
}
}

View File

@@ -15,7 +15,7 @@
<div class="container">
<ion-header translucent>
<ion-toolbar color="primary">
<ion-toolbar color="primary" mode="ios">
<ion-title>{{ 'map.modals.list.TITLE' | translate }}</ion-title>
<ion-buttons slot="end">
<ion-button (click)="modalController.dismiss()">{{

View File

@@ -1,5 +1,5 @@
<ion-header translucent>
<ion-toolbar color="primary">
<ion-toolbar color="primary" mode="ios">
<ion-title>{{ 'map.modals.single.TITLE' | translate }}</ion-title>
<ion-buttons slot="end">
<ion-button (click)="modalController.dismiss()">{{
@@ -9,5 +9,8 @@
</ion-toolbar>
</ion-header>
<ion-content>
<stapps-data-detail-content [item]="$any(item)"></stapps-data-detail-content>
<stapps-data-detail-content
[item]="$any(item)"
[openAsModal]="true"
></stapps-data-detail-content>
</ion-content>

View File

@@ -0,0 +1,4 @@
:host {
display: flex;
flex-direction: column;
}

View File

@@ -13,6 +13,7 @@
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {Component, ElementRef, Input, OnInit, ViewChild} from '@angular/core';
import {Router} from '@angular/router';
import {SCPlace} from '@openstapps/core';
import {geoJSON, Map, MapOptions, tileLayer} from 'leaflet';
import {MapProvider} from '../map.provider';
@@ -46,6 +47,13 @@ export class MapWidgetComponent implements OnInit {
*/
@Input() place: SCPlace;
/**
* Indicates if the expand button should be visible
*/
showExpandButton = true;
constructor(private router: Router) {}
/**
* Prepare the map
*/
@@ -69,6 +77,9 @@ export class MapWidgetComponent implements OnInit {
zoom: 16,
zoomControl: false,
};
if (this.router) {
this.showExpandButton = !this.router.url.startsWith('/map');
}
}
/**

View File

@@ -5,13 +5,13 @@
#mapContainer
[leafletOptions]="options"
></div>
<div class="map-buttons">
<div class="map-buttons" *ngIf="showExpandButton">
<ion-button
color="primary"
shape="round"
size="small"
[routerLink]="['/map', place.uid]"
>
<ion-icon name="expand"></ion-icon>
<ion-icon name="arrows-maximize"></ion-icon>
</ion-button>
</div>