diff options
Diffstat (limited to 'client/src/app/search')
-rw-r--r-- | client/src/app/search/advanced-search.model.ts | 3 | ||||
-rw-r--r-- | client/src/app/search/highlight.pipe.ts | 54 | ||||
-rw-r--r-- | client/src/app/search/search-filters.component.ts | 6 | ||||
-rw-r--r-- | client/src/app/search/search.component.ts | 19 | ||||
-rw-r--r-- | client/src/app/search/search.module.ts | 22 | ||||
-rw-r--r-- | client/src/app/search/search.service.ts | 14 |
6 files changed, 85 insertions, 33 deletions
diff --git a/client/src/app/search/advanced-search.model.ts b/client/src/app/search/advanced-search.model.ts index 643cc9a29..516854a8c 100644 --- a/client/src/app/search/advanced-search.model.ts +++ b/client/src/app/search/advanced-search.model.ts | |||
@@ -1,5 +1,4 @@ | |||
1 | import { SearchTargetType } from '@shared/models/search/search-target-query.model' | 1 | import { NSFWQuery, SearchTargetType } from '@shared/models' |
2 | import { NSFWQuery } from '../../../../shared/models/search' | ||
3 | 2 | ||
4 | export class AdvancedSearch { | 3 | export class AdvancedSearch { |
5 | startDate: string // ISO 8601 | 4 | startDate: string // ISO 8601 |
diff --git a/client/src/app/search/highlight.pipe.ts b/client/src/app/search/highlight.pipe.ts new file mode 100644 index 000000000..50ee5c1bd --- /dev/null +++ b/client/src/app/search/highlight.pipe.ts | |||
@@ -0,0 +1,54 @@ | |||
1 | import { PipeTransform, Pipe } from '@angular/core' | ||
2 | import { SafeHtml } from '@angular/platform-browser' | ||
3 | |||
4 | // Thanks https://gist.github.com/adamrecsko/0f28f474eca63e0279455476cc11eca7#gistcomment-2917369 | ||
5 | @Pipe({ name: 'highlight' }) | ||
6 | export class HighlightPipe implements PipeTransform { | ||
7 | /* use this for single match search */ | ||
8 | static SINGLE_MATCH = 'Single-Match' | ||
9 | /* use this for single match search with a restriction that target should start with search string */ | ||
10 | static SINGLE_AND_STARTS_WITH_MATCH = 'Single-And-StartsWith-Match' | ||
11 | /* use this for global search */ | ||
12 | static MULTI_MATCH = 'Multi-Match' | ||
13 | |||
14 | transform ( | ||
15 | contentString: string = null, | ||
16 | stringToHighlight: string = null, | ||
17 | option = 'Single-And-StartsWith-Match', | ||
18 | caseSensitive = false, | ||
19 | highlightStyleName = 'search-highlight' | ||
20 | ): SafeHtml { | ||
21 | if (stringToHighlight && contentString && option) { | ||
22 | let regex: any = '' | ||
23 | const caseFlag: string = !caseSensitive ? 'i' : '' | ||
24 | |||
25 | switch (option) { | ||
26 | case 'Single-Match': { | ||
27 | regex = new RegExp(stringToHighlight, caseFlag) | ||
28 | break | ||
29 | } | ||
30 | case 'Single-And-StartsWith-Match': { | ||
31 | regex = new RegExp('^' + stringToHighlight, caseFlag) | ||
32 | break | ||
33 | } | ||
34 | case 'Multi-Match': { | ||
35 | regex = new RegExp(stringToHighlight, 'g' + caseFlag) | ||
36 | break | ||
37 | } | ||
38 | default: { | ||
39 | // default will be a global case-insensitive match | ||
40 | regex = new RegExp(stringToHighlight, 'gi') | ||
41 | } | ||
42 | } | ||
43 | |||
44 | const replaced = contentString.replace( | ||
45 | regex, | ||
46 | (match) => `<span class="${highlightStyleName}">${match}</span>` | ||
47 | ) | ||
48 | |||
49 | return replaced | ||
50 | } else { | ||
51 | return contentString | ||
52 | } | ||
53 | } | ||
54 | } | ||
diff --git a/client/src/app/search/search-filters.component.ts b/client/src/app/search/search-filters.component.ts index af76260a7..14a5d0484 100644 --- a/client/src/app/search/search-filters.component.ts +++ b/client/src/app/search/search-filters.component.ts | |||
@@ -1,10 +1,10 @@ | |||
1 | import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core' | 1 | import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core' |
2 | import { ValidatorFn } from '@angular/forms' | 2 | import { ValidatorFn } from '@angular/forms' |
3 | import { VideoValidatorsService } from '@app/shared' | ||
4 | import { ServerService } from '@app/core' | 3 | import { ServerService } from '@app/core' |
5 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
6 | import { AdvancedSearch } from '@app/search/advanced-search.model' | 4 | import { AdvancedSearch } from '@app/search/advanced-search.model' |
7 | import { ServerConfig, VideoConstant } from '../../../../shared' | 5 | import { VideoValidatorsService } from '@app/shared/shared-forms' |
6 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
7 | import { ServerConfig, VideoConstant } from '@shared/models' | ||
8 | 8 | ||
9 | @Component({ | 9 | @Component({ |
10 | selector: 'my-search-filters', | 10 | selector: 'my-search-filters', |
diff --git a/client/src/app/search/search.component.ts b/client/src/app/search/search.component.ts index 6486085be..83b06e0ce 100644 --- a/client/src/app/search/search.component.ts +++ b/client/src/app/search/search.component.ts | |||
@@ -1,20 +1,15 @@ | |||
1 | import { forkJoin, of, Subscription } from 'rxjs' | 1 | import { forkJoin, of, Subscription } from 'rxjs' |
2 | import { Component, OnDestroy, OnInit } from '@angular/core' | 2 | import { Component, OnDestroy, OnInit } from '@angular/core' |
3 | import { ActivatedRoute, Router } from '@angular/router' | 3 | import { ActivatedRoute, Router } from '@angular/router' |
4 | import { AuthService, Notifier, ServerService } from '@app/core' | 4 | import { AuthService, ComponentPagination, HooksService, Notifier, ServerService, User, UserService } from '@app/core' |
5 | import { HooksService } from '@app/core/plugins/hooks.service' | 5 | import { immutableAssign } from '@app/helpers' |
6 | import { AdvancedSearch } from '@app/search/advanced-search.model' | 6 | import { Video, VideoChannel } from '@app/shared/shared-main' |
7 | import { SearchService } from '@app/search/search.service' | 7 | import { MiniatureDisplayOptions } from '@app/shared/shared-video-miniature' |
8 | import { User, UserService } from '@app/shared' | ||
9 | import { immutableAssign } from '@app/shared/misc/utils' | ||
10 | import { ComponentPagination } from '@app/shared/rest/component-pagination.model' | ||
11 | import { VideoChannel } from '@app/shared/video-channel/video-channel.model' | ||
12 | import { MiniatureDisplayOptions } from '@app/shared/video/video-miniature.component' | ||
13 | import { Video } from '@app/shared/video/video.model' | ||
14 | import { MetaService } from '@ngx-meta/core' | 8 | import { MetaService } from '@ngx-meta/core' |
15 | import { I18n } from '@ngx-translate/i18n-polyfill' | 9 | import { I18n } from '@ngx-translate/i18n-polyfill' |
16 | import { ServerConfig } from '@shared/models' | 10 | import { SearchTargetType, ServerConfig } from '@shared/models' |
17 | import { SearchTargetType } from '@shared/models/search/search-target-query.model' | 11 | import { AdvancedSearch } from './advanced-search.model' |
12 | import { SearchService } from './search.service' | ||
18 | 13 | ||
19 | @Component({ | 14 | @Component({ |
20 | selector: 'my-search', | 15 | selector: 'my-search', |
diff --git a/client/src/app/search/search.module.ts b/client/src/app/search/search.module.ts index df5459802..65c954de8 100644 --- a/client/src/app/search/search.module.ts +++ b/client/src/app/search/search.module.ts | |||
@@ -1,11 +1,15 @@ | |||
1 | import { TagInputModule } from 'ngx-chips' | 1 | import { TagInputModule } from 'ngx-chips' |
2 | import { NgModule } from '@angular/core' | 2 | import { NgModule } from '@angular/core' |
3 | import { SearchFiltersComponent } from '@app/search/search-filters.component' | 3 | import { SharedFormModule } from '@app/shared/shared-forms' |
4 | import { SearchRoutingModule } from '@app/search/search-routing.module' | 4 | import { SharedMainModule } from '@app/shared/shared-main' |
5 | import { SearchComponent } from '@app/search/search.component' | 5 | import { SharedUserSubscriptionModule } from '@app/shared/shared-user-subscription' |
6 | import { SearchService } from '@app/search/search.service' | 6 | import { SharedVideoMiniatureModule } from '@app/shared/shared-video-miniature' |
7 | import { SharedModule } from '../shared' | ||
8 | import { ChannelLazyLoadResolver } from './channel-lazy-load.resolver' | 7 | import { ChannelLazyLoadResolver } from './channel-lazy-load.resolver' |
8 | import { HighlightPipe } from './highlight.pipe' | ||
9 | import { SearchFiltersComponent } from './search-filters.component' | ||
10 | import { SearchRoutingModule } from './search-routing.module' | ||
11 | import { SearchComponent } from './search.component' | ||
12 | import { SearchService } from './search.service' | ||
9 | import { VideoLazyLoadResolver } from './video-lazy-load.resolver' | 13 | import { VideoLazyLoadResolver } from './video-lazy-load.resolver' |
10 | 14 | ||
11 | @NgModule({ | 15 | @NgModule({ |
@@ -13,7 +17,10 @@ import { VideoLazyLoadResolver } from './video-lazy-load.resolver' | |||
13 | TagInputModule, | 17 | TagInputModule, |
14 | 18 | ||
15 | SearchRoutingModule, | 19 | SearchRoutingModule, |
16 | SharedModule | 20 | SharedMainModule, |
21 | SharedFormModule, | ||
22 | SharedUserSubscriptionModule, | ||
23 | SharedVideoMiniatureModule | ||
17 | ], | 24 | ], |
18 | 25 | ||
19 | declarations: [ | 26 | declarations: [ |
@@ -29,7 +36,8 @@ import { VideoLazyLoadResolver } from './video-lazy-load.resolver' | |||
29 | providers: [ | 36 | providers: [ |
30 | SearchService, | 37 | SearchService, |
31 | VideoLazyLoadResolver, | 38 | VideoLazyLoadResolver, |
32 | ChannelLazyLoadResolver | 39 | ChannelLazyLoadResolver, |
40 | HighlightPipe | ||
33 | ] | 41 | ] |
34 | }) | 42 | }) |
35 | export class SearchModule { } | 43 | export class SearchModule { } |
diff --git a/client/src/app/search/search.service.ts b/client/src/app/search/search.service.ts index fdb12ea2c..36342034f 100644 --- a/client/src/app/search/search.service.ts +++ b/client/src/app/search/search.service.ts | |||
@@ -2,17 +2,13 @@ import { Observable } from 'rxjs' | |||
2 | import { catchError, map, switchMap } from 'rxjs/operators' | 2 | import { catchError, map, switchMap } from 'rxjs/operators' |
3 | import { HttpClient, HttpParams } from '@angular/common/http' | 3 | import { HttpClient, HttpParams } from '@angular/common/http' |
4 | import { Injectable } from '@angular/core' | 4 | import { Injectable } from '@angular/core' |
5 | import { ComponentPaginationLight, RestExtractor, RestPagination, RestService } from '@app/core' | ||
6 | import { peertubeLocalStorage } from '@app/helpers' | ||
5 | import { AdvancedSearch } from '@app/search/advanced-search.model' | 7 | import { AdvancedSearch } from '@app/search/advanced-search.model' |
6 | import { RestExtractor, RestPagination, RestService } from '@app/shared' | 8 | import { Video, VideoChannel, VideoChannelService, VideoService } from '@app/shared/shared-main' |
7 | import { peertubeLocalStorage } from '@app/shared/misc/peertube-web-storage' | 9 | import { ResultList, Video as VideoServerModel, VideoChannel as VideoChannelServerModel } from '@shared/models' |
8 | import { ComponentPaginationLight } from '@app/shared/rest/component-pagination.model' | ||
9 | import { VideoChannel } from '@app/shared/video-channel/video-channel.model' | ||
10 | import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' | ||
11 | import { Video } from '@app/shared/video/video.model' | ||
12 | import { VideoService } from '@app/shared/video/video.service' | ||
13 | import { ResultList, Video as VideoServerModel, VideoChannel as VideoChannelServerModel } from '../../../../shared' | ||
14 | import { environment } from '../../environments/environment' | ||
15 | import { SearchTargetType } from '@shared/models/search/search-target-query.model' | 10 | import { SearchTargetType } from '@shared/models/search/search-target-query.model' |
11 | import { environment } from '../../environments/environment' | ||
16 | 12 | ||
17 | @Injectable() | 13 | @Injectable() |
18 | export class SearchService { | 14 | export class SearchService { |