-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #74 from e-picsa/feat/deep-linking
Feat: App deep linking
- Loading branch information
Showing
12 changed files
with
223 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 12 additions & 0 deletions
12
apps/picsa-apps/extension-app/src/static/.well-known/assetlinks.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
[ | ||
{ | ||
"relation": ["delegate_permission/common.handle_all_urls"], | ||
"target": { | ||
"namespace": "android_app", | ||
"package_name": "io.picsa.extension", | ||
"sha256_cert_fingerprints": [ | ||
"E8:13:EC:21:32:37:45:EA:08:2D:E3:1C:D0:B4:91:05:07:9E:E9:E0:55:BE:4B:75:DC:4C:BB:44:82:C6:3C:4E" | ||
] | ||
} | ||
} | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
82 changes: 82 additions & 0 deletions
82
libs/shared/src/modules/deep-links/app-open-prompt.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import { Component } from '@angular/core'; | ||
import { MatBottomSheet } from '@angular/material/bottom-sheet'; | ||
import { DeepLinksService } from './deep-links.service'; | ||
|
||
/** | ||
* Show a link to open the app in native platform version, using dynamic app link | ||
*/ | ||
@Component({ | ||
selector: 'picsa-app-open-prompt', | ||
template: ` | ||
<div> | ||
<h2>Open With...</h2> | ||
<a [href]="appDynamicLink" target="_blank" rel="noopener"> | ||
<div class="open-option"> | ||
<div class="picsa-app-icon">PICSA</div> | ||
<h3>PICSA App</h3> | ||
<button mat-raised-button color="primary">Open</button> | ||
</div> | ||
</a> | ||
<div class="open-option" (click)="dismiss()"> | ||
<mat-icon class="open-icon">language</mat-icon> | ||
<h3>Browser</h3> | ||
<button mat-stroked-button>Continue</button> | ||
</div> | ||
<div class="spacer"></div> | ||
</div> | ||
`, | ||
styles: [ | ||
` | ||
.picsa-app-icon { | ||
background: #8a2644; | ||
border-radius: 10px; | ||
color: white; | ||
padding: 4px; | ||
line-height: 48px; | ||
height: 48px; | ||
width: 48px; | ||
text-align: center; | ||
font-size: 16px; | ||
} | ||
.open-option { | ||
display: flex; | ||
align-items: center; | ||
margin-bottom: 1rem; | ||
} | ||
h3 { | ||
flex: 1; | ||
text-align: left; | ||
margin-left: 1rem; | ||
} | ||
a { | ||
text-decoration: none; | ||
color: unset; | ||
} | ||
button { | ||
width: 90px; | ||
} | ||
.open-icon { | ||
font-size: 48px; | ||
height: 48px; | ||
width: 48px; | ||
padding: 4px; | ||
} | ||
.spacer { | ||
height: 1rem; | ||
} | ||
`, | ||
], | ||
}) | ||
export class AppOpenPromptComponent { | ||
appDynamicLink: string; | ||
constructor( | ||
deepLinksService: DeepLinksService, | ||
private bottomSheet: MatBottomSheet | ||
) { | ||
this.appDynamicLink = deepLinksService.config.appDynamicLink; | ||
} | ||
|
||
dismiss() { | ||
this.bottomSheet.dismiss(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { ModuleWithProviders, NgModule } from '@angular/core'; | ||
import { MatBottomSheetModule } from '@angular/material/bottom-sheet'; | ||
import { MatButtonModule } from '@angular/material/button'; | ||
import { MatIconModule } from '@angular/material/icon'; | ||
import { AppOpenPromptComponent } from './app-open-prompt.component'; | ||
import { DeepLinksService, DeepLinksServiceConfig } from './deep-links.service'; | ||
|
||
@NgModule({ | ||
imports: [MatIconModule, MatBottomSheetModule, MatButtonModule], | ||
exports: [], | ||
declarations: [AppOpenPromptComponent], | ||
}) | ||
export class PicsaDeepLinksModule { | ||
constructor(deepLinksService: DeepLinksService) { | ||
deepLinksService.init(); | ||
} | ||
// https://angular.io/guide/singleton-services#providing-a-singleton-service | ||
static forRoot( | ||
config: DeepLinksServiceConfig | ||
): ModuleWithProviders<PicsaDeepLinksModule> { | ||
return { | ||
ngModule: PicsaDeepLinksModule, | ||
providers: [{ provide: DeepLinksServiceConfig, useValue: config }], | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import { Injectable, NgZone, Optional } from '@angular/core'; | ||
import { MatBottomSheet } from '@angular/material/bottom-sheet'; | ||
import { Router } from '@angular/router'; | ||
import { App, URLOpenListenerEvent } from '@capacitor/app'; | ||
import { Capacitor } from '@capacitor/core'; | ||
import { AppOpenPromptComponent } from './app-open-prompt.component'; | ||
|
||
export class DeepLinksServiceConfig { | ||
/** Web url associated with deep links */ | ||
baseUrl: string; | ||
/** E.g. firebase dynamic link */ | ||
appDynamicLink: string; | ||
} | ||
|
||
@Injectable({ providedIn: 'root' }) | ||
/** | ||
* Provide support for opening deep links within app | ||
* https://capacitorjs.com/docs/guides/deep-links#angular | ||
*/ | ||
export class DeepLinksService { | ||
constructor( | ||
@Optional() public config: DeepLinksServiceConfig, | ||
private zone: NgZone, | ||
private router: Router, | ||
private bottomSheet: MatBottomSheet | ||
) {} | ||
|
||
public init() { | ||
if (Capacitor.isNativePlatform()) { | ||
const baseUrl = this.config?.baseUrl || location.origin; | ||
App.addListener('appUrlOpen', (event: URLOpenListenerEvent) => { | ||
this.zone.run(() => { | ||
const slug = event.url.replace(`${baseUrl}/`, ''); | ||
if (slug) { | ||
this.router.navigateByUrl(slug); | ||
} | ||
}); | ||
}); | ||
} else { | ||
if (this.isMobile()) { | ||
// open prompt after slight delay to allow time for app to render | ||
setTimeout(() => { | ||
this.toggleAppOpenTargetSheet(); | ||
}, 2500); | ||
} | ||
} | ||
} | ||
|
||
private isMobile() { | ||
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( | ||
navigator.userAgent | ||
); | ||
} | ||
|
||
/** | ||
* Present a bottom sheet to encourage user to use native version of app if running | ||
* on mobile | ||
*/ | ||
private toggleAppOpenTargetSheet() { | ||
this.bottomSheet.open(AppOpenPromptComponent); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,12 @@ | ||
import {PicsaNativeModule} from './native'; | ||
import {PicsaDbModule} from './db.module'; | ||
import {PicsaTranslateModule, PicsaTranslateService} from './translate' | ||
import { PicsaNativeModule } from './native'; | ||
import { PicsaDbModule } from './db.module'; | ||
import { PicsaTranslateModule, PicsaTranslateService } from './translate'; | ||
import { PicsaDeepLinksModule } from './deep-links/deep-links.module'; | ||
|
||
export {PicsaNativeModule, PicsaDbModule, PicsaTranslateModule, PicsaTranslateService} | ||
export { | ||
PicsaNativeModule, | ||
PicsaDbModule, | ||
PicsaTranslateModule, | ||
PicsaTranslateService, | ||
PicsaDeepLinksModule, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters