From 370240824e2fb28b314255f6c23f5ea7d6b08625 Mon Sep 17 00:00:00 2001 From: Rigel Kent Date: Tue, 19 Jan 2021 13:43:33 +0100 Subject: Allow users/visitors to search through an account's videos (#3589) * WIP: account search * add search to account view * add tests for account search --- client/src/app/shared/shared-main/misc/index.ts | 1 + .../misc/simple-search-input.component.html | 14 ++++++ .../misc/simple-search-input.component.scss | 29 ++++++++++++ .../misc/simple-search-input.component.ts | 54 ++++++++++++++++++++++ .../app/shared/shared-main/shared-main.module.ts | 4 +- .../app/shared/shared-main/video/video.service.ts | 7 ++- 6 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 client/src/app/shared/shared-main/misc/simple-search-input.component.html create mode 100644 client/src/app/shared/shared-main/misc/simple-search-input.component.scss create mode 100644 client/src/app/shared/shared-main/misc/simple-search-input.component.ts (limited to 'client/src/app/shared') diff --git a/client/src/app/shared/shared-main/misc/index.ts b/client/src/app/shared/shared-main/misc/index.ts index e806fd2f2..dc8ef9754 100644 --- a/client/src/app/shared/shared-main/misc/index.ts +++ b/client/src/app/shared/shared-main/misc/index.ts @@ -1,3 +1,4 @@ export * from './help.component' export * from './list-overflow.component' export * from './top-menu-dropdown.component' +export * from './simple-search-input.component' diff --git a/client/src/app/shared/shared-main/misc/simple-search-input.component.html b/client/src/app/shared/shared-main/misc/simple-search-input.component.html new file mode 100644 index 000000000..fb0d97122 --- /dev/null +++ b/client/src/app/shared/shared-main/misc/simple-search-input.component.html @@ -0,0 +1,14 @@ + + + + + diff --git a/client/src/app/shared/shared-main/misc/simple-search-input.component.scss b/client/src/app/shared/shared-main/misc/simple-search-input.component.scss new file mode 100644 index 000000000..591b04fb2 --- /dev/null +++ b/client/src/app/shared/shared-main/misc/simple-search-input.component.scss @@ -0,0 +1,29 @@ +@import '_variables'; +@import '_mixins'; + +span { + opacity: .6; + + &:focus-within { + opacity: 1; + } +} + +my-global-icon { + height: 18px; + position: relative; + top: -2px; +} + +input { + @include peertube-input-text(150px); + + height: 22px; // maximum height for the account/video-channels links + padding-left: 10px; + background-color: transparent; + border: none; + + &::placeholder { + font-size: 15px; + } +} diff --git a/client/src/app/shared/shared-main/misc/simple-search-input.component.ts b/client/src/app/shared/shared-main/misc/simple-search-input.component.ts new file mode 100644 index 000000000..86ae9ab42 --- /dev/null +++ b/client/src/app/shared/shared-main/misc/simple-search-input.component.ts @@ -0,0 +1,54 @@ +import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core' +import { ActivatedRoute, Router } from '@angular/router' +import { Subject } from 'rxjs' +import { debounceTime, distinctUntilChanged } from 'rxjs/operators' + +@Component({ + selector: 'simple-search-input', + templateUrl: './simple-search-input.component.html', + styleUrls: [ './simple-search-input.component.scss' ] +}) +export class SimpleSearchInputComponent implements OnInit { + @ViewChild('ref') input: ElementRef + + @Input() name = 'search' + @Input() placeholder = $localize`Search` + + @Output() searchChanged = new EventEmitter() + + value = '' + shown: boolean + + private searchSubject = new Subject() + + constructor ( + private router: Router, + private route: ActivatedRoute + ) {} + + ngOnInit () { + this.searchSubject + .pipe( + debounceTime(400), + distinctUntilChanged() + ) + .subscribe(value => this.searchChanged.emit(value)) + + this.searchSubject.next(this.value) + } + + showInput () { + this.shown = true + setTimeout(() => this.input.nativeElement.focus()) + } + + focusLost () { + if (this.value !== '') return + this.shown = false + } + + searchChange () { + this.router.navigate(['./search'], { relativeTo: this.route }) + this.searchSubject.next(this.value) + } +} diff --git a/client/src/app/shared/shared-main/shared-main.module.ts b/client/src/app/shared/shared-main/shared-main.module.ts index 123b5a3e3..c69a4c8b2 100644 --- a/client/src/app/shared/shared-main/shared-main.module.ts +++ b/client/src/app/shared/shared-main/shared-main.module.ts @@ -30,7 +30,7 @@ import { ActionDropdownComponent, ButtonComponent, DeleteButtonComponent, EditBu import { DateToggleComponent } from './date' import { FeedComponent } from './feeds' import { LoaderComponent, SmallLoaderComponent } from './loaders' -import { HelpComponent, ListOverflowComponent, TopMenuDropdownComponent } from './misc' +import { HelpComponent, ListOverflowComponent, TopMenuDropdownComponent, SimpleSearchInputComponent } from './misc' import { UserHistoryService, UserNotificationsComponent, UserNotificationService, UserQuotaComponent } from './users' import { RedundancyService, VideoImportService, VideoOwnershipService, VideoService } from './video' import { VideoCaptionService } from './video-caption' @@ -88,6 +88,7 @@ import { VideoChannelService } from './video-channel' HelpComponent, ListOverflowComponent, TopMenuDropdownComponent, + SimpleSearchInputComponent, UserQuotaComponent, UserNotificationsComponent @@ -140,6 +141,7 @@ import { VideoChannelService } from './video-channel' HelpComponent, ListOverflowComponent, TopMenuDropdownComponent, + SimpleSearchInputComponent, UserQuotaComponent, UserNotificationsComponent diff --git a/client/src/app/shared/shared-main/video/video.service.ts b/client/src/app/shared/shared-main/video/video.service.ts index 59860c5cb..0b708b692 100644 --- a/client/src/app/shared/shared-main/video/video.service.ts +++ b/client/src/app/shared/shared-main/video/video.service.ts @@ -140,8 +140,9 @@ export class VideoService implements VideosProvider { sort: VideoSortField nsfwPolicy?: NSFWPolicyType videoFilter?: VideoFilter + search?: string }): Observable> { - const { account, videoPagination, sort, videoFilter, nsfwPolicy } = parameters + const { account, videoPagination, sort, videoFilter, nsfwPolicy, search } = parameters const pagination = this.restService.componentPaginationToRestPagination(videoPagination) @@ -156,6 +157,10 @@ export class VideoService implements VideosProvider { params = params.set('filter', videoFilter) } + if (search) { + params = params.set('search', search) + } + return this.authHttp .get>(AccountService.BASE_ACCOUNT_URL + account.nameWithHost + '/videos', { params }) .pipe( -- cgit v1.2.3