Browse Source

Fix issues with external links in search page

Chocobozzz 3 years ago
parent
commit
0bdad52fbb

+ 0 - 8
client/src/app/+search/channel-lazy-load.resolver.ts

@@ -12,20 +12,12 @@ export class ChannelLazyLoadResolver implements Resolve<any> {
 
   resolve (route: ActivatedRouteSnapshot) {
     const url = route.params.url
-    const externalRedirect = route.params.externalRedirect
-    const fromPath = route.params.fromPath
 
     if (!url) {
       console.error('Could not find url param.', { params: route.params })
       return this.router.navigateByUrl('/404')
     }
 
-    if (externalRedirect === 'true') {
-      window.open(url)
-      this.router.navigateByUrl(fromPath)
-      return
-    }
-
     return this.searchService.searchVideoChannels({ search: url })
       .pipe(
         map(result => {

+ 16 - 4
client/src/app/+search/search.component.html

@@ -35,15 +35,27 @@
 
   <ng-container *ngFor="let result of results">
     <div *ngIf="isVideoChannel(result)" class="entry video-channel">
-      <a [routerLink]="getChannelUrl(result)">
+      <a *ngIf="!isExternalChannelUrl()" [routerLink]="getChannelUrl(result)">
+        <img [src]="result.avatarUrl" alt="Avatar" />
+      </a>
+
+      <a *ngIf="isExternalChannelUrl()" [href]="getChannelUrl(result)" target="_blank">
         <img [src]="result.avatarUrl" alt="Avatar" />
       </a>
 
       <div class="video-channel-info">
-        <a [routerLink]="getChannelUrl(result)" class="video-channel-names">
+        <a *ngIf="!isExternalChannelUrl()" [routerLink]="getChannelUrl(result)" class="video-channel-names">
+          <ng-container *ngTemplateOutlet="aContent"></ng-container>
+        </a>
+
+        <a *ngIf="isExternalChannelUrl()" [href]="getChannelUrl(result)" target="_blank" class="video-channel-names">
+          <ng-container *ngTemplateOutlet="aContent"></ng-container>
+        </a>
+
+        <ng-template #aContent>
           <div class="video-channel-display-name">{{ result.displayName }}</div>
           <div class="video-channel-name">{{ result.nameWithHost }}</div>
-        </a>
+        </ng-template>
 
         <div i18n class="video-channel-followers">{{ result.followersCount }} subscribers</div>
       </div>
@@ -54,7 +66,7 @@
     <div *ngIf="isVideo(result)" class="entry video">
       <my-video-miniature
         [video]="result" [user]="userMiniature" [displayAsRow]="true" [displayVideoActions]="!hideActions()"
-        [displayOptions]="videoDisplayOptions" [useLazyLoadUrl]="advancedSearch.searchTarget === 'search-index'"
+        [displayOptions]="videoDisplayOptions" [videoLinkType]="getVideoLinkType()"
         (videoBlocked)="removeVideoFromArray(result)" (videoRemoved)="removeVideoFromArray(result)"
       ></my-video-miniature>
     </div>

+ 27 - 9
client/src/app/+search/search.component.ts

@@ -5,7 +5,7 @@ import { AuthService, ComponentPagination, HooksService, Notifier, ServerService
 import { immutableAssign } from '@app/helpers'
 import { Video, VideoChannel } from '@app/shared/shared-main'
 import { AdvancedSearch, SearchService } from '@app/shared/shared-search'
-import { MiniatureDisplayOptions } from '@app/shared/shared-video-miniature'
+import { MiniatureDisplayOptions, VideoLinkType } from '@app/shared/shared-video-miniature'
 import { MetaService } from '@ngx-meta/core'
 import { I18n } from '@ngx-translate/i18n-polyfill'
 import { SearchTargetType, ServerConfig } from '@shared/models'
@@ -119,6 +119,25 @@ export class SearchComponent implements OnInit, OnDestroy {
     return this.authService.isLoggedIn()
   }
 
+  getVideoLinkType (): VideoLinkType {
+    if (this.advancedSearch.searchTarget === 'search-index') {
+      const remoteUriConfig = this.serverConfig.search.remoteUri
+
+      // Redirect on the external instance if not allowed to fetch remote data
+      if ((!this.isUserLoggedIn() && !remoteUriConfig.anonymous) || !remoteUriConfig.users) {
+        return 'external'
+      }
+
+      return 'lazy-load'
+    }
+
+    return 'internal'
+  }
+
+  isExternalChannelUrl () {
+    return this.getVideoLinkType() === 'external'
+  }
+
   search () {
     forkJoin([
       this.getVideosObs(),
@@ -184,17 +203,16 @@ export class SearchComponent implements OnInit, OnDestroy {
   }
 
   getChannelUrl (channel: VideoChannel) {
-    if (this.advancedSearch.searchTarget === 'search-index' && channel.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
+    // Same algorithm than videos
+    if (this.getVideoLinkType() === 'external') {
+      return channel.url
+    }
 
-      return [ '/search/lazy-load-channel', { url: channel.url, externalRedirect, fromPath } ]
+    if (this.getVideoLinkType() === 'internal') {
+      return [ '/video-channels', channel.nameWithHost ]
     }
 
-    return [ '/video-channels', channel.nameWithHost ]
+    return [ '/search/lazy-load-channel', { url: channel.url } ]
   }
 
   hideActions () {

+ 0 - 8
client/src/app/+search/video-lazy-load.resolver.ts

@@ -12,20 +12,12 @@ export class VideoLazyLoadResolver implements Resolve<any> {
 
   resolve (route: ActivatedRouteSnapshot) {
     const url = route.params.url
-    const externalRedirect = route.params.externalRedirect
-    const fromPath = route.params.fromPath
 
     if (!url) {
       console.error('Could not find url param.', { params: route.params })
       return this.router.navigateByUrl('/404')
     }
 
-    if (externalRedirect === 'true') {
-      window.open(url)
-      this.router.navigateByUrl(fromPath)
-      return
-    }
-
     return this.searchService.searchVideos({ search: url })
       .pipe(
         map(result => {

+ 10 - 5
client/src/app/shared/shared-thumbnail/video-thumbnail.component.html

@@ -1,7 +1,12 @@
-<a
-  [routerLink]="getVideoRouterLink()" [queryParams]="queryParams"
-  class="video-thumbnail"
->
+<a *ngIf="!videoHref" [routerLink]="getVideoRouterLink()" [queryParams]="queryParams" class="video-thumbnail">
+  <ng-container *ngTemplateOutlet="aContent"></ng-container>
+</a>
+
+<a *ngIf="videoHref" [href]="videoHref" [target]="videoTarget" class="video-thumbnail">
+  <ng-container *ngTemplateOutlet="aContent"></ng-container>
+</a>
+
+<ng-template #aContent>
   <img alt="" [attr.aria-label]="video.name" [attr.src]="getImageUrl()" [ngClass]="{ 'blur-filter': nsfw }" />
 
   <div *ngIf="displayWatchLaterPlaylist" class="video-thumbnail-actions-overlay">
@@ -30,4 +35,4 @@
   <div class="progress-bar" *ngIf="video.userHistory?.currentTime">
     <div [ngStyle]="{ 'width.%': getProgressPercent() }"></div>
   </div>
-</a>
+</ng-template>

+ 5 - 2
client/src/app/shared/shared-thumbnail/video-thumbnail.component.ts

@@ -11,8 +11,11 @@ import { Video } from '../shared-main'
 export class VideoThumbnailComponent {
   @Input() video: Video
   @Input() nsfw = false
-  @Input() routerLink: any[]
+
+  @Input() videoRouterLink: any[]
   @Input() queryParams: { [ p: string ]: any }
+  @Input() videoHref: string
+  @Input() videoTarget: string
 
   @Input() displayWatchLaterPlaylist: boolean
   @Input() inWatchLaterPlaylist: boolean
@@ -49,7 +52,7 @@ export class VideoThumbnailComponent {
   }
 
   getVideoRouterLink () {
-    if (this.routerLink) return this.routerLink
+    if (this.videoRouterLink) return this.videoRouterLink
 
     return [ '/videos/watch', this.video.uuid ]
   }

+ 7 - 5
client/src/app/shared/shared-video-miniature/video-miniature.component.html

@@ -1,6 +1,6 @@
 <div class="video-miniature" [ngClass]="{ 'display-as-row': displayAsRow, 'fit-width': fitWidth }" (mouseenter)="loadActions()">
   <my-video-thumbnail
-    [video]="video" [nsfw]="isVideoBlur" [routerLink]="videoLink"
+    [video]="video" [nsfw]="isVideoBlur" [videoRouterLink]="videoRouterLink" [videoHref]="videoHref" [videoTarget]="videoTarget"
     [displayWatchLaterPlaylist]="isWatchLaterPlaylistDisplayed()" [inWatchLaterPlaylist]="inWatchLaterPlaylist" (watchLaterClick)="onWatchLaterClick($event)"
   >
     <ng-container ngProjectAs="label-warning" *ngIf="displayOptions.privacyLabel && isUnlistedVideo()" i18n>Unlisted</ng-container>
@@ -15,10 +15,12 @@
         </a>
 
         <div class="w-100 d-flex flex-column">
-          <a
-            tabindex="-1"
-            class="video-miniature-name"
-            [routerLink]="videoLink" [attr.title]="video.name" [ngClass]="{ 'blur-filter': isVideoBlur }"
+          <a *ngIf="!videoHref" tabindex="-1" class="video-miniature-name"
+            [routerLink]="videoRouterLink" [attr.title]="video.name" [ngClass]="{ 'blur-filter': isVideoBlur }"
+          >{{ video.name }}</a>
+
+          <a *ngIf="videoHref" tabindex="-1" class="video-miniature-name"
+            [href]="videoHref" [target]="videoTarget" [attr.title]="video.name" [ngClass]="{ 'blur-filter': isVideoBlur }"
           >{{ video.name }}</a>
 
           <span class="video-miniature-created-at-views">

+ 15 - 10
client/src/app/shared/shared-video-miniature/video-miniature.component.ts

@@ -29,6 +29,7 @@ export type MiniatureDisplayOptions = {
   blacklistInfo?: boolean
   nsfw?: boolean
 }
+export type VideoLinkType = 'internal' | 'lazy-load' | 'external'
 
 @Component({
   selector: 'my-video-miniature',
@@ -55,7 +56,7 @@ export class VideoMiniatureComponent implements OnInit {
   @Input() displayVideoActions = true
   @Input() fitWidth = false
 
-  @Input() useLazyLoadUrl = false
+  @Input() videoLinkType: VideoLinkType = 'internal'
 
   @Output() videoBlocked = new EventEmitter()
   @Output() videoUnblocked = new EventEmitter()
@@ -85,7 +86,9 @@ export class VideoMiniatureComponent implements OnInit {
     playlistElementId?: number
   }
 
-  videoLink: any[] = []
+  videoRouterLink: any[] = []
+  videoHref: string
+  videoTarget: string
 
   private ownerDisplayTypeChosen: 'account' | 'videoChannel'
 
@@ -125,18 +128,20 @@ 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
+    if (this.videoLinkType === 'internal' || !this.video.url) {
+      this.videoRouterLink = [ '/videos/watch', this.video.uuid ]
+      return
+    }
 
-      this.videoLink = [ '/search/lazy-load-video', { url: this.video.url, externalRedirect, fromPath } ]
+    if (this.videoLinkType === 'external') {
+      this.videoRouterLink = null
+      this.videoHref = this.video.url
+      this.videoTarget = '_blank'
       return
     }
 
-    this.videoLink = [ '/videos/watch', this.video.uuid ]
+    // Lazy load
+    this.videoRouterLink = [ '/search/lazy-load-video', { url: this.video.url } ]
   }
 
   displayOwnerAccount () {

+ 1 - 1
client/src/app/shared/shared-video-playlist/video-playlist-element-miniature.component.html

@@ -8,7 +8,7 @@
     <my-video-thumbnail
       *ngIf="playlistElement.video"
       [video]="playlistElement.video" [nsfw]="isVideoBlur(playlistElement.video)"
-      [routerLink]="buildRouterLink()" [queryParams]="buildRouterQuery()"
+      [videoRouterLink]="buildRouterLink()" [queryParams]="buildRouterQuery()"
     ></my-video-thumbnail>
 
     <div class="fake-thumbnail" *ngIf="!playlistElement.video"></div>