Skip to content

Commit

Permalink
Add instance search (#172)
Browse files Browse the repository at this point in the history
  • Loading branch information
RikudouSage committed Jan 6, 2024
1 parent 1b1b36d commit 502d14b
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 28 deletions.
24 changes: 24 additions & 0 deletions src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,30 @@
</a>
</li>
</ng-container>
<div class="form-inline" *ngIf="!loggedInInstance.anonymous" [class.sidebar-search-open]="searchFocused" (focusin)="searchFocused = true" #searchWrapper>
<form [formGroup]="searchForm">
<div class="input-group" data-widget="sidebar-search">
<input formControlName="searchContent" #searchInput class="form-control form-control-sidebar" type="search" placeholder="{{'app.search' | transloco}}" />
<div class="input-group-append">
<button class="btn btn-sidebar" (click)="searchAnywhere(searchInput.value)">
<i class="fas fa-search fa-fw"></i>
</button>
</div>
</div>
</form>
<div class="sidebar-search-results">
<div class="list-group">
<a href="javascript:void(0)" class="list-group-item" *ngIf="!(searchResults|keys).length">
<div class="search-title">{{'app.search.not_found' | transloco}}</div>
<div class="search-path"></div>
</a>
<a *ngFor="let result of searchResults | keyvalue" [routerLink]="result.value.link" class="list-group-item">
<div class="search-title">{{result.value.title}}</div>
<div class="search-path"></div>
</a>
</div>
</div>
</div>
<li class="nav-item" *ngIf="!loggedInInstance.anonymous">
<a routerLink="/endorsements/my" class="nav-link">
<i class="nav-icon fas fa-thumbs-up"></i>
Expand Down
80 changes: 72 additions & 8 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {Component, ElementRef, HostListener, Inject, OnInit, TemplateRef, ViewChild} from '@angular/core';
import {TitleService} from "./services/title.service";
import {AuthenticationManagerService} from "./services/authentication-manager.service";
import {Observable} from "rxjs";
import {debounceTime, Observable} from "rxjs";
import {Instance} from "./user/instance";
import {Resolvable} from "./types/resolvable";
import {MessageService, MessageType} from "./services/message.service";
Expand All @@ -15,6 +15,7 @@ import {NgbModal, NgbModalRef} from "@ng-bootstrap/ng-bootstrap";
import {DatabaseService} from "./services/database.service";
import {TranslocoService} from "@ngneat/transloco";
import {CachedFediseerApiService} from "./services/cached-fediseer-api.service";
import {FormControl, FormGroup} from "@angular/forms";

@Component({
selector: 'app-root',
Expand All @@ -30,6 +31,7 @@ export class AppComponent implements OnInit {

@ViewChild('sideMenu') private sideMenu: ElementRef<HTMLElement> | null = null;
@ViewChild('sideMenuToggle') private sideMenuToggle: ElementRef<HTMLAnchorElement> | null = null;
@ViewChild('searchWrapper') private searchWrapper: ElementRef<HTMLDivElement> | null = null;

private switchAccountModal: NgbModalRef | null = null;

Expand All @@ -52,6 +54,12 @@ export class AppComponent implements OnInit {
public availableLanguages: string[] = [];
public selectedLanguage: string | null = null;

public searchFocused: boolean = false;
public searchResults: {[instance: string]: {title: string, link: string}} = {};
public searchForm = new FormGroup({
searchContent: new FormControl(''),
});

constructor(
private readonly titleService: TitleService,
private readonly authenticationManager: AuthenticationManagerService,
Expand Down Expand Up @@ -139,6 +147,48 @@ export class AppComponent implements OnInit {
this.software = response.successResponse!.software.toLowerCase();
});
});

this.searchForm.controls.searchContent.valueChanges.pipe(
debounceTime(300),
).subscribe(async searchText => {
this.searchResults = {};
if (!searchText) {
return;
}

this.cachedApi.getAllSafelistedInstances({}, {ttl: 600}).subscribe(instancesResponse => {
if (this.apiResponseHelper.handleErrors([instancesResponse])) {
return;
}

const allInstances = instancesResponse.successResponse!.instances.map(instance => instance.domain);
this.cachedApi.getAllCensuresByInstances(allInstances, {ttl: 600}).subscribe(instancesResponse => {
if (this.apiResponseHelper.handleErrors([instancesResponse])) {
return;
}
const instances = instancesResponse.successResponse!.instances.filter(
instance => instance.domain.includes(searchText),
);
for (const instance of instances) {
this.searchResults[instance.domain] = {
title: instance.domain,
link: `/instances/detail/${instance.domain}`
};
}
});

const instances = instancesResponse.successResponse!.instances.filter(
instance => instance.domain.includes(searchText),
);

for (const instance of instances) {
this.searchResults[instance.domain] = {
title: instance.domain,
link: `/instances/detail/${instance.domain}`
};
}
});
});
}

public async logout(removeFromAccounts: boolean = true): Promise<void> {
Expand Down Expand Up @@ -166,17 +216,27 @@ export class AppComponent implements OnInit {

@HostListener('body:click', ['$event'])
public async onBodyClicked(event: Event): Promise<void> {
if (this.sideMenu === null || this.sideMenuToggle === null) {
return;
}
if (this.sideMenu.nativeElement.contains(<HTMLElement>event.target) || this.sideMenuToggle.nativeElement.contains(<HTMLElement>event.target)) {
return;
if (this.sideMenu !== null && this.sideMenuToggle !== null) {
if (this.sideMenu.nativeElement.contains(<HTMLElement>event.target) || this.sideMenuToggle.nativeElement.contains(<HTMLElement>event.target)) {
return;
}
if (window.outerWidth <= this.autoCollapse) {
await this.hideMenu();
}
}
if (window.outerWidth <= this.autoCollapse) {
await this.hideMenu();
if (this.searchWrapper !== null) {
if (this.searchWrapper.nativeElement.contains(<HTMLElement>event.target)) {
return;
}
this.searchFocused = false;
}
}

@HostListener('document:keydown.escape')
public onEscapePressed() {
this.searchFocused = false;
}

private async hideMenu(): Promise<void> {
const body = this.document.body;
if (window.outerWidth <= this.autoCollapse) {
Expand Down Expand Up @@ -224,4 +284,8 @@ export class AppComponent implements OnInit {
this.transloco.setActiveLang(language);
this.database.storedLanguage = language;
}

public async searchAnywhere(searchText: string) {

}
}
12 changes: 12 additions & 0 deletions src/app/shared/pipes/keys.pipe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {Pipe, PipeTransform} from '@angular/core';

@Pipe({
name: 'keys'
})
export class KeysPipe implements PipeTransform {

transform(value: any): string[] {
return Object.keys(value);
}

}
41 changes: 22 additions & 19 deletions src/app/shared/shared.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {ReactiveFormsModule} from "@angular/forms";
import {FlagsComponent} from './components/flags/flags.component';
import {InstanceLogoComponent} from './components/instance-logo/instance-logo.component';
import {LanguageNamePipe} from './pipes/language-name.pipe';
import {KeysPipe} from './pipes/keys.pipe';


@NgModule({
Expand All @@ -36,26 +37,28 @@ import {LanguageNamePipe} from './pipes/language-name.pipe';
FlagsComponent,
InstanceLogoComponent,
LanguageNamePipe,
KeysPipe,
],
exports: [
ToObservablePipe,
LoaderComponent,
YesNoComponent,
IterableEnumPipe,
TomSelectDirective,
TooltipComponent,
FormatDatetimePipe,
FormatPercentagePipe,
FormatNumberPipe,
TranslocoModule,
NgbModule,
TranslocoMarkupComponent,
InstanceStatusComponent,
InstanceMoveToListComponent,
FlagsComponent,
InstanceLogoComponent,
LanguageNamePipe,
KeysPipe,
],
exports: [
ToObservablePipe,
LoaderComponent,
YesNoComponent,
IterableEnumPipe,
TomSelectDirective,
TooltipComponent,
FormatDatetimePipe,
FormatPercentagePipe,
FormatNumberPipe,
TranslocoModule,
NgbModule,
TranslocoMarkupComponent,
InstanceStatusComponent,
InstanceMoveToListComponent,
FlagsComponent,
InstanceLogoComponent,
LanguageNamePipe,
],
imports: [
CommonModule,
NgbTooltip,
Expand Down
4 changes: 3 additions & 1 deletion src/assets/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -173,5 +173,7 @@
"app.censures.unguaranteed": "No one guaranteed for this instance, you cannot censure others.",
"app.censures.my.title": "My censures",
"error.censures.moving_failed": "Failed moving the instance {{instance}}. Please reload the page to see whether it was removed from your censures or not.",
"app.language": "Language"
"app.language": "Language",
"app.search": "Search",
"app.search.not_found": "Nothing was found"
}

0 comments on commit 502d14b

Please sign in to comment.