Add global search to lookup identities, events and more

This commit is contained in:
SondreB 2023-01-06 03:00:01 +01:00
parent cd22f799db
commit 049a1390c9
No known key found for this signature in database
GPG Key ID: D6CC44C75005FDBF
5 changed files with 84 additions and 8 deletions

View File

@ -44,7 +44,7 @@
<mat-icon>close</mat-icon>
</button>
<button (click)="theme.darkMode = !theme.darkMode" mat-icon-button class="mat-icon-button theme-sidenav-icon">
<mat-icon aria-label="Menu" class="material-icons">{{ theme.darkMode ? "dark_mode": "light_mode" }}</mat-icon>
<mat-icon aria-label="Menu" class="material-icons">{{ theme.darkMode ? "dark_mode" : "light_mode" }}</mat-icon>
</button>
<header>
<div class="bio" (click)="openProfile()">
@ -83,24 +83,39 @@
<mat-sidenav-content>
<mat-toolbar class="app-header">
<button *ngIf="(isHandset$ | async) === true" type="button" aria-label="Toggle sidenav" mat-icon-button (click)="drawer.toggle()">
<button *ngIf="!appState.showSearch && (isHandset$ | async) === true" type="button" aria-label="Toggle sidenav" mat-icon-button (click)="drawer.toggle()">
<mat-icon>menu</mat-icon>
</button>
<span></span>
<button *ngIf="appState.showBackButton" mat-icon-button (click)="goBack()">
<button *ngIf="!appState.showSearch && appState.showBackButton" mat-icon-button (click)="goBack()">
<mat-icon class="arrow-back">arrow_back</mat-icon>
</button>
<div class="top-spacer">{{ appState.title }}</div>
<div *ngIf="!appState.showSearch" class="top-spacer">{{ appState.title }}</div>
<!-- <app-language-selector></app-language-selector> -->
<ng-template *ngIf="!appState.showSearch">
<button *ngFor="let action of appState.actions" (click)="action.click()" mat-icon-button [matTooltip]="action.tooltip">
<mat-icon>{{ action.icon }}</mat-icon>
</button>
</ng-template>
<button *ngFor="let action of appState.actions" (click)="action.click()" mat-icon-button [matTooltip]="action.tooltip">
<mat-icon>{{ action.icon }}</mat-icon>
<mat-form-field *ngIf="appState.showSearch" appearance="outline" class="search-box">
<mat-icon class="circle" matPrefix>search</mat-icon>
<mat-label>Search</mat-label>
<input matInput #searchInput type="text" (change)="searchInputChanged()" autocomplete="off" [(ngModel)]="appState.searchText" />
</mat-form-field>
<button *ngIf="appState.showSearch" mat-icon-button (click)="searchVisibility(false)">
<mat-icon>close</mat-icon>
</button>
<button mat-icon-button (click)="draweraccount.toggle()">
<button *ngIf="!appState.showSearch" mat-icon-button (click)="searchVisibility(true)">
<mat-icon>search</mat-icon>
</button>
<button *ngIf="!appState.showSearch" mat-icon-button (click)="draweraccount.toggle()">
<mat-icon>account_circle</mat-icon>
</button>
</mat-toolbar>

View File

@ -169,3 +169,10 @@ header {
.new-post-button:hover {
opacity: 0.6;
}
.search-box {
display: inline-block;
padding-top: 1em;
top: 20px;
flex: 1 1 auto;
}

View File

@ -1,4 +1,4 @@
import { Component, ViewChild } from '@angular/core';
import { Component, ViewChild, ElementRef } from '@angular/core';
import { ApplicationState } from './services/applicationstate.service';
import { MatSidenav } from '@angular/material/sidenav';
import { Router, TitleStrategy } from '@angular/router';
@ -21,6 +21,7 @@ import { NavigationService } from './services/navigation.service';
import { NostrProfileDocument } from './services/interfaces';
import { ThemeService } from './services/theme.service';
import { NostrProtocolRequest } from './common/NostrProtocolRequest';
import { SearchService } from './services/search.service';
@Component({
selector: 'app-root',
@ -30,6 +31,7 @@ import { NostrProtocolRequest } from './common/NostrProtocolRequest';
export class AppComponent {
@ViewChild('drawer') drawer!: MatSidenav;
@ViewChild('draweraccount') draweraccount!: MatSidenav;
@ViewChild('searchInput') searchInput!: ElementRef;
authenticated = false;
bgimagePath = '/assets/profile-bg.png';
profile: NostrProfileDocument | undefined;
@ -51,6 +53,7 @@ export class AppComponent {
private dataService: DataService,
public profileService: ProfileService,
public navigationService: NavigationService,
private searchService: SearchService,
public theme: ThemeService
) {
if (!this.visibilityHandler) {
@ -92,6 +95,23 @@ export class AppComponent {
});
}
searchInputChanged() {
if (this.appState.searchText) {
this.searchService.search(this.appState.searchText);
}
}
searchVisibility(visible: boolean) {
this.appState.showSearch = visible;
this.appState.searchText = '';
if (visible) {
setTimeout(() => {
this.searchInput.nativeElement.focus();
});
}
}
async onScroll(event: ScrollEvent) {
if (event.isReachingBottom) {
// console.log(`the user is reaching the bottom`);

View File

@ -39,6 +39,10 @@ export class ApplicationState {
showBackButton = false;
searchText?: string;
showSearch = false;
actions: Action[] = [];
/** Parameters that comes from query string during activation of the extension. */

View File

@ -0,0 +1,30 @@
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { nip19 } from 'nostr-tools';
import { ApplicationState } from './applicationstate.service';
@Injectable({
providedIn: 'root',
})
export class SearchService {
constructor(public router: Router, public appState: ApplicationState) {}
search(searchText: string) {
console.log('Searching for: ', searchText);
if (searchText.startsWith('npub')) {
const pubkey = nip19.decode(searchText) as any;
this.resetSearch();
this.router.navigate(['/p', pubkey.data]);
} else if (searchText.startsWith('nevent')) {
const event = nip19.decode(searchText) as any;
this.resetSearch();
this.router.navigate(['/p', event.data]);
}
}
resetSearch() {
this.appState.searchText = '';
this.appState.showSearch = false;
}
}