mirror of
https://github.com/block-core/blockcore-notes.git
synced 2024-09-29 06:20:42 +00:00
Add a protocol handler for nostr
This commit is contained in:
parent
d5a760e089
commit
579f719cc2
1
package-lock.json
generated
1
package-lock.json
generated
@ -43,6 +43,7 @@
|
||||
"@blockcore/tsconfig": "0.0.1",
|
||||
"@types/jasmine": "~4.3.0",
|
||||
"@types/qrcode": "^1.5.0",
|
||||
"@types/qs": "^6.9.7",
|
||||
"@types/sanitize-html": "^2.8.0",
|
||||
"@types/uuid": "^9.0.0",
|
||||
"jasmine-core": "~4.5.0",
|
||||
|
@ -47,6 +47,7 @@
|
||||
"@blockcore/tsconfig": "0.0.1",
|
||||
"@types/jasmine": "~4.3.0",
|
||||
"@types/qrcode": "^1.5.0",
|
||||
"@types/qs": "^6.9.7",
|
||||
"@types/sanitize-html": "^2.8.0",
|
||||
"@types/uuid": "^9.0.0",
|
||||
"jasmine-core": "~4.5.0",
|
||||
|
@ -20,6 +20,7 @@ import { ScrollEvent } from './shared/scroll.directive';
|
||||
import { NavigationService } from './services/navigation.service';
|
||||
import { NostrProfileDocument } from './services/interfaces';
|
||||
import { ThemeService } from './services/theme.service';
|
||||
import { NostrProtocolRequest } from './common/NostrProtocolRequest';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
@ -51,6 +52,25 @@ export class AppComponent {
|
||||
public navigationService: NavigationService,
|
||||
public theme: ThemeService
|
||||
) {
|
||||
// This must happen in the constructor on app component, or when loading in PWA, it won't
|
||||
// be possible to read the query parameters.
|
||||
const queryParam = globalThis.location.search;
|
||||
|
||||
if (queryParam) {
|
||||
const param = Object.fromEntries(new URLSearchParams(queryParam)) as any;
|
||||
this.appState.params = param;
|
||||
|
||||
if (this.appState.params.nostr) {
|
||||
const protocolRequest = new NostrProtocolRequest();
|
||||
const protocolData = protocolRequest.decode(this.appState.params.nostr);
|
||||
|
||||
if (protocolData && protocolData.scheme && protocolData.address) {
|
||||
const prefix = protocolData.scheme === 'nevent' ? '/e' : '/p';
|
||||
this.router.navigate([prefix, protocolData.address!]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// appState.title = 'Blockcore Notes';
|
||||
this.authService.authInfo$.subscribe(async (auth) => {
|
||||
this.authenticated = auth.authenticated();
|
||||
|
61
src/app/common/NostrProtocolRequest.ts
Normal file
61
src/app/common/NostrProtocolRequest.ts
Normal file
@ -0,0 +1,61 @@
|
||||
import * as qs from 'qs';
|
||||
|
||||
export class NostrProtocolRequestData {
|
||||
address?: string;
|
||||
options: any;
|
||||
scheme?: string;
|
||||
}
|
||||
|
||||
export class NostrProtocolRequest {
|
||||
prefix = 'web+nostr:';
|
||||
|
||||
removeHandler(uri: string) {
|
||||
if (uri.indexOf('://') > -1) {
|
||||
return uri.substring(uri.indexOf('://') + 3);
|
||||
} else {
|
||||
return uri;
|
||||
}
|
||||
}
|
||||
|
||||
decode(uri: string): NostrProtocolRequestData {
|
||||
if (!uri.startsWith(this.prefix)) {
|
||||
throw new Error('Invalid Nostr URI: ' + uri);
|
||||
}
|
||||
|
||||
var urnScheme = uri.slice(this.prefix.length, uri.indexOf(':', this.prefix.length)).toLowerCase();
|
||||
var urnValue = uri.slice(this.prefix.length + urnScheme.length + 1);
|
||||
var split = urnValue.split('?');
|
||||
var address = split[0];
|
||||
|
||||
// Depending on how the user interacts with the protocol handler, browsers might append / at the end of the URL,
|
||||
// which is then included on the address value. We must ensure that this is removed.
|
||||
if (address.indexOf('/') > -1) {
|
||||
address = address.substring(0, address.length - 1);
|
||||
}
|
||||
|
||||
let options;
|
||||
|
||||
if (split.length > 1) {
|
||||
options = qs.parse(split[1]);
|
||||
}
|
||||
|
||||
return { address: address, scheme: urnScheme, options: options };
|
||||
}
|
||||
|
||||
/** Transform all flattened values into PaymentRequestData. */
|
||||
transform(data: any): NostrProtocolRequestData {
|
||||
const address = data.address;
|
||||
const scheme = data.scheme;
|
||||
|
||||
const options = data;
|
||||
delete options.address;
|
||||
delete options.scheme;
|
||||
|
||||
return { address: address, scheme: scheme, options: options };
|
||||
}
|
||||
|
||||
encode(request: NostrProtocolRequestData): string {
|
||||
var query = qs.stringify(request.options);
|
||||
return request.scheme + ':' + request.address + (query ? '?' : '') + query;
|
||||
}
|
||||
}
|
@ -39,6 +39,9 @@ export class ApplicationState {
|
||||
|
||||
actions: Action[] = [];
|
||||
|
||||
/** Parameters that comes from query string during activation of the extension. */
|
||||
params: any;
|
||||
|
||||
isSmallScreen$: Observable<boolean>;
|
||||
|
||||
displayLabels$: Observable<boolean>;
|
||||
|
@ -33,7 +33,7 @@
|
||||
|
||||
<div class="settings-action-buttons">
|
||||
<button mat-stroked-button (click)="toggle()"><span *ngIf="!open">Expand All</span><span *ngIf="open">Collapse All</span></button>
|
||||
<br>
|
||||
<br />
|
||||
<button mat-flat-button color="primary" (click)="getRelays()">Append relays from extension</button><button mat-flat-button color="primary" (click)="getDefaultRelays()">Append relays from app</button
|
||||
><button mat-flat-button color="warn" (click)="deleteRelays()">Delete all relays</button>
|
||||
</div>
|
||||
@ -47,13 +47,27 @@
|
||||
</ng-template>
|
||||
<ng-template matTabContent>
|
||||
<div class="page">
|
||||
<mat-form-field class="input-full-width" appearance="outline">
|
||||
<mat-label>Choose mode</mat-label>
|
||||
<mat-select (selectionChange)="theme.darkMode = !theme.darkMode" [value]="theme.darkMode">
|
||||
<mat-option [value]="true">Dark</mat-option>
|
||||
<mat-option [value]="false">Light</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-card>
|
||||
<mat-card-content>
|
||||
<mat-form-field class="input-full-width" appearance="outline">
|
||||
<mat-label>Choose mode</mat-label>
|
||||
<mat-select (selectionChange)="theme.darkMode = !theme.darkMode" [value]="theme.darkMode">
|
||||
<mat-option [value]="true">Dark</mat-option>
|
||||
<mat-option [value]="false">Light</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
|
||||
<br>
|
||||
|
||||
<mat-card>
|
||||
<mat-card-content>
|
||||
<button mat-stroked-button (click)="registerHandler('web+nostr', 'nostr')">Register Protocol Handler</button>
|
||||
<br /><br />
|
||||
<div class="dimmed">Click the button to make Blockcore Notes handle links on websites for npub, nevent and nprofile.</div>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</div>
|
||||
</ng-template>
|
||||
</mat-tab>
|
||||
|
@ -104,6 +104,11 @@ export class SettingsComponent {
|
||||
];
|
||||
}
|
||||
|
||||
registerHandler(protocol: string, parameter: string) {
|
||||
// navigator.registerProtocolHandler(protocol, `./index.html?${parameter}=%s`);
|
||||
navigator.registerProtocolHandler(protocol, `/?${parameter}=%s`);
|
||||
}
|
||||
|
||||
addRelay(): void {
|
||||
const dialogRef = this.dialog.open(AddRelayDialog, {
|
||||
data: { read: true, write: true },
|
||||
|
Loading…
Reference in New Issue
Block a user