Fix issues with external links in search page

pull/2986/head
Chocobozzz 2020-07-20 11:37:06 +02:00
parent 69a019968e
commit 0bdad52fbb
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
9 changed files with 83 additions and 54 deletions

View File

@ -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 => {

View File

@ -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>

View File

@ -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
return [ '/search/lazy-load-channel', { url: channel.url, externalRedirect, fromPath } ]
// Same algorithm than videos
if (this.getVideoLinkType() === 'external') {
return channel.url
}
return [ '/video-channels', channel.nameWithHost ]
if (this.getVideoLinkType() === 'internal') {
return [ '/video-channels', channel.nameWithHost ]
}
return [ '/search/lazy-load-channel', { url: channel.url } ]
}
hideActions () {

View File

@ -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 => {

View File

@ -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>

View File

@ -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 ]
}

View File

@ -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">

View File

@ -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
this.videoLink = [ '/search/lazy-load-video', { url: this.video.url, externalRedirect, fromPath } ]
if (this.videoLinkType === 'internal' || !this.video.url) {
this.videoRouterLink = [ '/videos/watch', this.video.uuid ]
return
}
this.videoLink = [ '/videos/watch', this.video.uuid ]
if (this.videoLinkType === 'external') {
this.videoRouterLink = null
this.videoHref = this.video.url
this.videoTarget = '_blank'
return
}
// Lazy load
this.videoRouterLink = [ '/search/lazy-load-video', { url: this.video.url } ]
}
displayOwnerAccount () {

View File

@ -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>