From 51d5283917e8d69a8dcca17ea0e68329cc35adad Mon Sep 17 00:00:00 2001 From: Patrick Gebhardt Date: Fri, 19 Jun 2020 22:38:43 +0200 Subject: [PATCH] Add share button --- frontend/src/app/app.module.ts | 16 ++++-- .../components/region/region.component.html | 4 +- .../components/result/result.component.html | 4 +- .../share-button/share-button.component.html | 3 ++ .../share-button/share-button.component.scss | 0 .../share-button.component.spec.ts | 25 +++++++++ .../share-button/share-button.component.ts | 54 +++++++++++++++++++ .../region-details.component.html | 4 +- .../share-dialog/share-dialog.component.html | 13 +++++ .../share-dialog/share-dialog.component.scss | 23 ++++++++ .../share-dialog.component.spec.ts | 25 +++++++++ .../share-dialog/share-dialog.component.ts | 40 ++++++++++++++ 12 files changed, 198 insertions(+), 13 deletions(-) create mode 100644 frontend/src/app/components/share-button/share-button.component.html create mode 100644 frontend/src/app/components/share-button/share-button.component.scss create mode 100644 frontend/src/app/components/share-button/share-button.component.spec.ts create mode 100644 frontend/src/app/components/share-button/share-button.component.ts create mode 100644 frontend/src/app/dialogs/share-dialog/share-dialog.component.html create mode 100644 frontend/src/app/dialogs/share-dialog/share-dialog.component.scss create mode 100644 frontend/src/app/dialogs/share-dialog/share-dialog.component.spec.ts create mode 100644 frontend/src/app/dialogs/share-dialog/share-dialog.component.ts diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts index 268ffbe..50036cb 100644 --- a/frontend/src/app/app.module.ts +++ b/frontend/src/app/app.module.ts @@ -21,7 +21,7 @@ import {TranslateModule, TranslateService} from '@ngx-translate/core'; // @ts-ignore import * as enLang from '../assets/i18n/en.json'; import {HttpClientModule} from '@angular/common/http'; -import {MatButtonToggleModule, MatCheckboxModule, MatDividerModule, MatTooltipModule} from '@angular/material'; +import {MatButtonToggleModule, MatCheckboxModule, MatDialogModule, MatDividerModule, MatTooltipModule} from '@angular/material'; import {FormsModule} from '@angular/forms'; import {RegionComponent} from './components/region/region.component'; import {ResultComponent} from './components/result/result.component'; @@ -30,6 +30,8 @@ import {GraphComponent} from './components/graph/graph.component'; import {RegionStatsComponent} from './components/region-stats/region-stats.component'; import {BookmarkButtonComponent} from './components/bookmark-button/bookmark-button.component'; import {BookmarkListComponent} from './containers/bookmark-list/bookmark-list.component'; +import {ShareButtonComponent} from './components/share-button/share-button.component'; +import {ShareDialogComponent} from './dialogs/share-dialog/share-dialog.component'; @NgModule({ @@ -45,7 +47,9 @@ import {BookmarkListComponent} from './containers/bookmark-list/bookmark-list.co GraphComponent, RegionStatsComponent, BookmarkButtonComponent, - BookmarkListComponent + BookmarkListComponent, + ShareButtonComponent, + ShareDialogComponent ], imports: [ BrowserModule, @@ -66,10 +70,14 @@ import {BookmarkListComponent} from './containers/bookmark-list/bookmark-list.co FormsModule, MatButtonToggleModule, MatDividerModule, - MatTooltipModule + MatTooltipModule, + MatDialogModule ], providers: [], - bootstrap: [AppComponent] + bootstrap: [AppComponent], + entryComponents: [ + ShareDialogComponent + ] }) export class AppModule { constructor(translate: TranslateService) { diff --git a/frontend/src/app/components/region/region.component.html b/frontend/src/app/components/region/region.component.html index 4ea7798..810a17b 100644 --- a/frontend/src/app/components/region/region.component.html +++ b/frontend/src/app/components/region/region.component.html @@ -7,8 +7,6 @@ | {{region.country}} - + diff --git a/frontend/src/app/components/result/result.component.html b/frontend/src/app/components/result/result.component.html index bc72275..462f3e2 100644 --- a/frontend/src/app/components/result/result.component.html +++ b/frontend/src/app/components/result/result.component.html @@ -7,9 +7,7 @@ | {{result.country}} - +
diff --git a/frontend/src/app/components/share-button/share-button.component.html b/frontend/src/app/components/share-button/share-button.component.html new file mode 100644 index 0000000..0bbd320 --- /dev/null +++ b/frontend/src/app/components/share-button/share-button.component.html @@ -0,0 +1,3 @@ + diff --git a/frontend/src/app/components/share-button/share-button.component.scss b/frontend/src/app/components/share-button/share-button.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/app/components/share-button/share-button.component.spec.ts b/frontend/src/app/components/share-button/share-button.component.spec.ts new file mode 100644 index 0000000..36a20c9 --- /dev/null +++ b/frontend/src/app/components/share-button/share-button.component.spec.ts @@ -0,0 +1,25 @@ +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; + +import {ShareButtonComponent} from './share-button.component'; + +describe('ShareButtonComponent', () => { + let component: ShareButtonComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ShareButtonComponent] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ShareButtonComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/components/share-button/share-button.component.ts b/frontend/src/app/components/share-button/share-button.component.ts new file mode 100644 index 0000000..e2f53df --- /dev/null +++ b/frontend/src/app/components/share-button/share-button.component.ts @@ -0,0 +1,54 @@ +import {Component, Input, OnInit} from '@angular/core'; +import {Region} from '../../interfaces/region.interface'; +import {ShareDialogComponent} from '../../dialogs/share-dialog/share-dialog.component'; +import {MatDialog} from '@angular/material'; + +@Component({ + selector: 'app-share-button', + templateUrl: './share-button.component.html', + styleUrls: ['./share-button.component.scss'] +}) +export class ShareButtonComponent implements OnInit { + + @Input() + region: Region; + + constructor(public dialog: MatDialog) { + } + + ngOnInit() { + } + + async onShare(event: Event) { + event.stopPropagation(); + + // @ts-ignore + if (navigator.share) { + try { + await this.executeMobileShareMenu(); + } catch (e) { + this.executeShareDialog(); + } + + } else { + this.executeShareDialog(); + } + } + + async executeMobileShareMenu() { + const shareData = { + title: 'Travopti', + text: `Check out the region "${this.region.name}"`, + url: `https://travopti.de/region/${this.region.region_id}` + }; + // @ts-ignore + await navigator.share(shareData); + } + + executeShareDialog() { + this.dialog.open(ShareDialogComponent, { + width: '350px', + data: this.region + }); + } +} diff --git a/frontend/src/app/containers/region-details/region-details.component.html b/frontend/src/app/containers/region-details/region-details.component.html index a332780..e612e82 100644 --- a/frontend/src/app/containers/region-details/region-details.component.html +++ b/frontend/src/app/containers/region-details/region-details.component.html @@ -7,9 +7,7 @@ {{region.name}} - +

{{region.description.substr(0, DESC_CUT_POINT)}} diff --git a/frontend/src/app/dialogs/share-dialog/share-dialog.component.html b/frontend/src/app/dialogs/share-dialog/share-dialog.component.html new file mode 100644 index 0000000..5bb9762 --- /dev/null +++ b/frontend/src/app/dialogs/share-dialog/share-dialog.component.html @@ -0,0 +1,13 @@ +

+ Share the link + +
+
+ + +
+ diff --git a/frontend/src/app/dialogs/share-dialog/share-dialog.component.scss b/frontend/src/app/dialogs/share-dialog/share-dialog.component.scss new file mode 100644 index 0000000..3df4d15 --- /dev/null +++ b/frontend/src/app/dialogs/share-dialog/share-dialog.component.scss @@ -0,0 +1,23 @@ +.dialog-header { + display: flex; + flex-direction: row; + align-items: center; + margin-bottom: 2rem; + + span { + flex: 1 1 auto; + margin: 0; + } +} + +.dialog-body { + + display: flex; + flex-direction: row; + + .url { + flex: 1 1 auto; + border: 1px solid black; + text-align: center; + } +} diff --git a/frontend/src/app/dialogs/share-dialog/share-dialog.component.spec.ts b/frontend/src/app/dialogs/share-dialog/share-dialog.component.spec.ts new file mode 100644 index 0000000..ef3725d --- /dev/null +++ b/frontend/src/app/dialogs/share-dialog/share-dialog.component.spec.ts @@ -0,0 +1,25 @@ +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; + +import {ShareDialogComponent} from './share-dialog.component'; + +describe('ShareDialogComponent', () => { + let component: ShareDialogComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ShareDialogComponent] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ShareDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/dialogs/share-dialog/share-dialog.component.ts b/frontend/src/app/dialogs/share-dialog/share-dialog.component.ts new file mode 100644 index 0000000..faf15f3 --- /dev/null +++ b/frontend/src/app/dialogs/share-dialog/share-dialog.component.ts @@ -0,0 +1,40 @@ +import {Component, ElementRef, Inject, OnInit, ViewChild} from '@angular/core'; +import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material'; +import {Region} from '../../interfaces/region.interface'; + +@Component({ + selector: 'app-share-dialog', + templateUrl: './share-dialog.component.html', + styleUrls: ['./share-dialog.component.scss'] +}) +export class ShareDialogComponent implements OnInit { + + @ViewChild('url', {static: false}) + urlTextBox: ElementRef; + + readonly host = window.location.host; + + isCopied = false; + + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: Region + ) { + } + + ngOnInit() { + } + + onCopy() { + const urlElement: HTMLInputElement = this.urlTextBox.nativeElement; + + urlElement.select(); + urlElement.setSelectionRange(0, 999); // For mobile devices + + document.execCommand('copy'); + + urlElement.value = 'Copied to Clipboard!'; + this.isCopied = true; + } + +}