From 5fb2e2888ce032c638e4b75d07458642f0833e52 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 29 May 2020 16:16:24 +0200 Subject: First implem global search --- client/src/app/shared/actor/actor.model.ts | 10 ++++-- client/src/app/shared/angular/highlight.pipe.ts | 20 ++++++------ .../custom-config-validators.service.ts | 8 +++++ .../app/shared/users/user-notification.model.ts | 4 +-- .../shared/video/video-miniature.component.html | 4 +-- .../app/shared/video/video-miniature.component.ts | 38 +++++++++++++++++----- client/src/app/shared/video/video.model.ts | 13 ++++++-- 7 files changed, 69 insertions(+), 28 deletions(-) (limited to 'client/src/app/shared') diff --git a/client/src/app/shared/actor/actor.model.ts b/client/src/app/shared/actor/actor.model.ts index 0e5060f67..a78303a2f 100644 --- a/client/src/app/shared/actor/actor.model.ts +++ b/client/src/app/shared/actor/actor.model.ts @@ -15,10 +15,14 @@ export abstract class Actor implements ActorServer { avatarUrl: string - static GET_ACTOR_AVATAR_URL (actor: { avatar?: { path: string } }) { - const absoluteAPIUrl = getAbsoluteAPIUrl() + static GET_ACTOR_AVATAR_URL (actor: { avatar?: Avatar }) { + if (actor?.avatar?.url) return actor.avatar.url + + if (actor && actor.avatar) { + const absoluteAPIUrl = getAbsoluteAPIUrl() - if (actor && actor.avatar) return absoluteAPIUrl + actor.avatar.path + return absoluteAPIUrl + actor.avatar.path + } return this.GET_DEFAULT_AVATAR_URL() } diff --git a/client/src/app/shared/angular/highlight.pipe.ts b/client/src/app/shared/angular/highlight.pipe.ts index fb6042280..50ee5c1bd 100644 --- a/client/src/app/shared/angular/highlight.pipe.ts +++ b/client/src/app/shared/angular/highlight.pipe.ts @@ -11,19 +11,17 @@ export class HighlightPipe implements PipeTransform { /* use this for global search */ static MULTI_MATCH = 'Multi-Match' - // tslint:disable-next-line:no-empty - constructor () {} - transform ( - contentString: string = null, - stringToHighlight: string = null, - option = 'Single-And-StartsWith-Match', - caseSensitive = false, - highlightStyleName = 'search-highlight' + contentString: string = null, + stringToHighlight: string = null, + option = 'Single-And-StartsWith-Match', + caseSensitive = false, + highlightStyleName = 'search-highlight' ): SafeHtml { if (stringToHighlight && contentString && option) { let regex: any = '' const caseFlag: string = !caseSensitive ? 'i' : '' + switch (option) { case 'Single-Match': { regex = new RegExp(stringToHighlight, caseFlag) @@ -42,10 +40,12 @@ export class HighlightPipe implements PipeTransform { regex = new RegExp(stringToHighlight, 'gi') } } + const replaced = contentString.replace( - regex, - (match) => `${match}` + regex, + (match) => `${match}` ) + return replaced } else { return contentString diff --git a/client/src/app/shared/forms/form-validators/custom-config-validators.service.ts b/client/src/app/shared/forms/form-validators/custom-config-validators.service.ts index abcbca817..fdb19e06a 100644 --- a/client/src/app/shared/forms/form-validators/custom-config-validators.service.ts +++ b/client/src/app/shared/forms/form-validators/custom-config-validators.service.ts @@ -14,6 +14,7 @@ export class CustomConfigValidatorsService { readonly ADMIN_EMAIL: BuildFormValidator readonly TRANSCODING_THREADS: BuildFormValidator readonly INDEX_URL: BuildFormValidator + readonly SEARCH_INDEX_URL: BuildFormValidator constructor (private i18n: I18n) { this.INSTANCE_NAME = { @@ -86,5 +87,12 @@ export class CustomConfigValidatorsService { 'pattern': this.i18n('Index URL should be a URL') } } + + this.SEARCH_INDEX_URL = { + VALIDATORS: [ Validators.pattern(/^https?:\/\//) ], + MESSAGES: { + 'pattern': this.i18n('Search index URL should be a URL') + } + } } } diff --git a/client/src/app/shared/users/user-notification.model.ts b/client/src/app/shared/users/user-notification.model.ts index ba29cb462..7b8368d87 100644 --- a/client/src/app/shared/users/user-notification.model.ts +++ b/client/src/app/shared/users/user-notification.model.ts @@ -1,4 +1,4 @@ -import { ActorInfo, FollowState, UserNotification as UserNotificationServer, UserNotificationType, VideoInfo } from '../../../../../shared' +import { ActorInfo, FollowState, UserNotification as UserNotificationServer, UserNotificationType, VideoInfo, Avatar } from '../../../../../shared' import { Actor } from '@app/shared/actor/actor.model' export class UserNotification implements UserNotificationServer { @@ -178,7 +178,7 @@ export class UserNotification implements UserNotificationServer { return videoImport.targetUrl || videoImport.magnetUri || videoImport.torrentName } - private setAvatarUrl (actor: { avatarUrl?: string, avatar?: { path: string } }) { + private setAvatarUrl (actor: { avatarUrl?: string, avatar?: Avatar }) { actor.avatarUrl = Actor.GET_ACTOR_AVATAR_URL(actor) } } diff --git a/client/src/app/shared/video/video-miniature.component.html b/client/src/app/shared/video/video-miniature.component.html index d354a2930..3e23cf18c 100644 --- a/client/src/app/shared/video/video-miniature.component.html +++ b/client/src/app/shared/video/video-miniature.component.html @@ -1,6 +1,6 @@
Unlisted @@ -12,7 +12,7 @@ {{ video.name }}
diff --git a/client/src/app/shared/video/video-miniature.component.ts b/client/src/app/shared/video/video-miniature.component.ts index a1d4f0e81..aa1726ca7 100644 --- a/client/src/app/shared/video/video-miniature.component.ts +++ b/client/src/app/shared/video/video-miniature.component.ts @@ -1,3 +1,4 @@ +import { switchMap } from 'rxjs/operators' import { ChangeDetectionStrategy, ChangeDetectorRef, @@ -9,15 +10,14 @@ import { OnInit, Output } from '@angular/core' -import { User } from '../users' -import { Video } from './video.model' import { AuthService, ServerService } from '@app/core' -import { ServerConfig, VideoPlaylistType, VideoPrivacy, VideoState } from '../../../../../shared' -import { I18n } from '@ngx-translate/i18n-polyfill' -import { VideoActionsDisplayType } from '@app/shared/video/video-actions-dropdown.component' import { ScreenService } from '@app/shared/misc/screen.service' import { VideoPlaylistService } from '@app/shared/video-playlist/video-playlist.service' -import { switchMap } from 'rxjs/operators' +import { VideoActionsDisplayType } from '@app/shared/video/video-actions-dropdown.component' +import { I18n } from '@ngx-translate/i18n-polyfill' +import { ServerConfig, VideoPlaylistType, VideoPrivacy, VideoState } from '../../../../../shared' +import { User } from '../users' +import { Video } from './video.model' export type OwnerDisplayType = 'account' | 'videoChannel' | 'auto' export type MiniatureDisplayOptions = { @@ -57,6 +57,8 @@ export class VideoMiniatureComponent implements OnInit { @Input() displayVideoActions = true @Input() fitWidth = false + @Input() useLazyLoadUrl = false + @Output() videoBlacklisted = new EventEmitter() @Output() videoUnblacklisted = new EventEmitter() @Output() videoRemoved = new EventEmitter() @@ -82,6 +84,8 @@ export class VideoMiniatureComponent implements OnInit { playlistElementId?: number } + videoLink: any[] = [] + private ownerDisplayTypeChosen: 'account' | 'videoChannel' constructor ( @@ -103,7 +107,10 @@ export class VideoMiniatureComponent implements OnInit { ngOnInit () { this.serverConfig = this.serverService.getTmpConfig() this.serverService.getConfig() - .subscribe(config => this.serverConfig = config) + .subscribe(config => { + this.serverConfig = config + this.buildVideoLink() + }) this.setUpBy() @@ -113,6 +120,21 @@ export class VideoMiniatureComponent implements OnInit { } } + buildVideoLink () { + if (this.useLazyLoadUrl && this.video.url) { + const remoteUriConfig = this.serverConfig.search.remoteUri + + // Redirect on the external instance if not allowed to fetch remote data + const externalRedirect = (!this.authService.isLoggedIn() && !remoteUriConfig.anonymous) || !remoteUriConfig.users + const fromPath = window.location.pathname + window.location.search + + this.videoLink = [ '/search/lazy-load-video', { url: this.video.url, externalRedirect, fromPath } ] + return + } + + this.videoLink = [ '/videos/watch', this.video.uuid ] + } + displayOwnerAccount () { return this.ownerDisplayTypeChosen === 'account' } @@ -203,7 +225,7 @@ export class VideoMiniatureComponent implements OnInit { } isWatchLaterPlaylistDisplayed () { - return this.isUserLoggedIn() && this.inWatchLaterPlaylist !== undefined + return this.displayVideoActions && this.isUserLoggedIn() && this.inWatchLaterPlaylist !== undefined } private setUpBy () { diff --git a/client/src/app/shared/video/video.model.ts b/client/src/app/shared/video/video.model.ts index 546518cca..97759f9c1 100644 --- a/client/src/app/shared/video/video.model.ts +++ b/client/src/app/shared/video/video.model.ts @@ -33,10 +33,15 @@ export class Video implements VideoServerModel { serverHost: string thumbnailPath: string thumbnailUrl: string + previewPath: string previewUrl: string + embedPath: string embedUrl: string + + url?: string + views: number likes: number dislikes: number @@ -100,13 +105,15 @@ export class Video implements VideoServerModel { this.name = hash.name this.thumbnailPath = hash.thumbnailPath - this.thumbnailUrl = absoluteAPIUrl + hash.thumbnailPath + this.thumbnailUrl = hash.thumbnailUrl || (absoluteAPIUrl + hash.thumbnailPath) this.previewPath = hash.previewPath - this.previewUrl = absoluteAPIUrl + hash.previewPath + this.previewUrl = hash.previewUrl || (absoluteAPIUrl + hash.previewPath) this.embedPath = hash.embedPath - this.embedUrl = absoluteAPIUrl + hash.embedPath + this.embedUrl = hash.embedUrl || (absoluteAPIUrl + hash.embedPath) + + this.url = hash.url this.views = hash.views this.likes = hash.likes -- cgit v1.2.3