mirror of https://github.com/Chocobozzz/PeerTube
Fix issues with external links in search page
parent
69a019968e
commit
0bdad52fbb
|
@ -12,20 +12,12 @@ export class ChannelLazyLoadResolver implements Resolve<any> {
|
||||||
|
|
||||||
resolve (route: ActivatedRouteSnapshot) {
|
resolve (route: ActivatedRouteSnapshot) {
|
||||||
const url = route.params.url
|
const url = route.params.url
|
||||||
const externalRedirect = route.params.externalRedirect
|
|
||||||
const fromPath = route.params.fromPath
|
|
||||||
|
|
||||||
if (!url) {
|
if (!url) {
|
||||||
console.error('Could not find url param.', { params: route.params })
|
console.error('Could not find url param.', { params: route.params })
|
||||||
return this.router.navigateByUrl('/404')
|
return this.router.navigateByUrl('/404')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (externalRedirect === 'true') {
|
|
||||||
window.open(url)
|
|
||||||
this.router.navigateByUrl(fromPath)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.searchService.searchVideoChannels({ search: url })
|
return this.searchService.searchVideoChannels({ search: url })
|
||||||
.pipe(
|
.pipe(
|
||||||
map(result => {
|
map(result => {
|
||||||
|
|
|
@ -35,15 +35,27 @@
|
||||||
|
|
||||||
<ng-container *ngFor="let result of results">
|
<ng-container *ngFor="let result of results">
|
||||||
<div *ngIf="isVideoChannel(result)" class="entry video-channel">
|
<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" />
|
<img [src]="result.avatarUrl" alt="Avatar" />
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<div class="video-channel-info">
|
<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-display-name">{{ result.displayName }}</div>
|
||||||
<div class="video-channel-name">{{ result.nameWithHost }}</div>
|
<div class="video-channel-name">{{ result.nameWithHost }}</div>
|
||||||
</a>
|
</ng-template>
|
||||||
|
|
||||||
<div i18n class="video-channel-followers">{{ result.followersCount }} subscribers</div>
|
<div i18n class="video-channel-followers">{{ result.followersCount }} subscribers</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -54,7 +66,7 @@
|
||||||
<div *ngIf="isVideo(result)" class="entry video">
|
<div *ngIf="isVideo(result)" class="entry video">
|
||||||
<my-video-miniature
|
<my-video-miniature
|
||||||
[video]="result" [user]="userMiniature" [displayAsRow]="true" [displayVideoActions]="!hideActions()"
|
[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)"
|
(videoBlocked)="removeVideoFromArray(result)" (videoRemoved)="removeVideoFromArray(result)"
|
||||||
></my-video-miniature>
|
></my-video-miniature>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { AuthService, ComponentPagination, HooksService, Notifier, ServerService
|
||||||
import { immutableAssign } from '@app/helpers'
|
import { immutableAssign } from '@app/helpers'
|
||||||
import { Video, VideoChannel } from '@app/shared/shared-main'
|
import { Video, VideoChannel } from '@app/shared/shared-main'
|
||||||
import { AdvancedSearch, SearchService } from '@app/shared/shared-search'
|
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 { MetaService } from '@ngx-meta/core'
|
||||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||||
import { SearchTargetType, ServerConfig } from '@shared/models'
|
import { SearchTargetType, ServerConfig } from '@shared/models'
|
||||||
|
@ -119,6 +119,25 @@ export class SearchComponent implements OnInit, OnDestroy {
|
||||||
return this.authService.isLoggedIn()
|
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 () {
|
search () {
|
||||||
forkJoin([
|
forkJoin([
|
||||||
this.getVideosObs(),
|
this.getVideosObs(),
|
||||||
|
@ -184,19 +203,18 @@ export class SearchComponent implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
|
|
||||||
getChannelUrl (channel: VideoChannel) {
|
getChannelUrl (channel: VideoChannel) {
|
||||||
if (this.advancedSearch.searchTarget === 'search-index' && channel.url) {
|
// Same algorithm than videos
|
||||||
const remoteUriConfig = this.serverConfig.search.remoteUri
|
if (this.getVideoLinkType() === 'external') {
|
||||||
|
return channel.url
|
||||||
// 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 } ]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.getVideoLinkType() === 'internal') {
|
||||||
return [ '/video-channels', channel.nameWithHost ]
|
return [ '/video-channels', channel.nameWithHost ]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return [ '/search/lazy-load-channel', { url: channel.url } ]
|
||||||
|
}
|
||||||
|
|
||||||
hideActions () {
|
hideActions () {
|
||||||
return this.lastSearchTarget === 'search-index'
|
return this.lastSearchTarget === 'search-index'
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,20 +12,12 @@ export class VideoLazyLoadResolver implements Resolve<any> {
|
||||||
|
|
||||||
resolve (route: ActivatedRouteSnapshot) {
|
resolve (route: ActivatedRouteSnapshot) {
|
||||||
const url = route.params.url
|
const url = route.params.url
|
||||||
const externalRedirect = route.params.externalRedirect
|
|
||||||
const fromPath = route.params.fromPath
|
|
||||||
|
|
||||||
if (!url) {
|
if (!url) {
|
||||||
console.error('Could not find url param.', { params: route.params })
|
console.error('Could not find url param.', { params: route.params })
|
||||||
return this.router.navigateByUrl('/404')
|
return this.router.navigateByUrl('/404')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (externalRedirect === 'true') {
|
|
||||||
window.open(url)
|
|
||||||
this.router.navigateByUrl(fromPath)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.searchService.searchVideos({ search: url })
|
return this.searchService.searchVideos({ search: url })
|
||||||
.pipe(
|
.pipe(
|
||||||
map(result => {
|
map(result => {
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
<a
|
<a *ngIf="!videoHref" [routerLink]="getVideoRouterLink()" [queryParams]="queryParams" class="video-thumbnail">
|
||||||
[routerLink]="getVideoRouterLink()" [queryParams]="queryParams"
|
<ng-container *ngTemplateOutlet="aContent"></ng-container>
|
||||||
class="video-thumbnail"
|
</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 }" />
|
<img alt="" [attr.aria-label]="video.name" [attr.src]="getImageUrl()" [ngClass]="{ 'blur-filter': nsfw }" />
|
||||||
|
|
||||||
<div *ngIf="displayWatchLaterPlaylist" class="video-thumbnail-actions-overlay">
|
<div *ngIf="displayWatchLaterPlaylist" class="video-thumbnail-actions-overlay">
|
||||||
|
@ -30,4 +35,4 @@
|
||||||
<div class="progress-bar" *ngIf="video.userHistory?.currentTime">
|
<div class="progress-bar" *ngIf="video.userHistory?.currentTime">
|
||||||
<div [ngStyle]="{ 'width.%': getProgressPercent() }"></div>
|
<div [ngStyle]="{ 'width.%': getProgressPercent() }"></div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</ng-template>
|
||||||
|
|
|
@ -11,8 +11,11 @@ import { Video } from '../shared-main'
|
||||||
export class VideoThumbnailComponent {
|
export class VideoThumbnailComponent {
|
||||||
@Input() video: Video
|
@Input() video: Video
|
||||||
@Input() nsfw = false
|
@Input() nsfw = false
|
||||||
@Input() routerLink: any[]
|
|
||||||
|
@Input() videoRouterLink: any[]
|
||||||
@Input() queryParams: { [ p: string ]: any }
|
@Input() queryParams: { [ p: string ]: any }
|
||||||
|
@Input() videoHref: string
|
||||||
|
@Input() videoTarget: string
|
||||||
|
|
||||||
@Input() displayWatchLaterPlaylist: boolean
|
@Input() displayWatchLaterPlaylist: boolean
|
||||||
@Input() inWatchLaterPlaylist: boolean
|
@Input() inWatchLaterPlaylist: boolean
|
||||||
|
@ -49,7 +52,7 @@ export class VideoThumbnailComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
getVideoRouterLink () {
|
getVideoRouterLink () {
|
||||||
if (this.routerLink) return this.routerLink
|
if (this.videoRouterLink) return this.videoRouterLink
|
||||||
|
|
||||||
return [ '/videos/watch', this.video.uuid ]
|
return [ '/videos/watch', this.video.uuid ]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<div class="video-miniature" [ngClass]="{ 'display-as-row': displayAsRow, 'fit-width': fitWidth }" (mouseenter)="loadActions()">
|
<div class="video-miniature" [ngClass]="{ 'display-as-row': displayAsRow, 'fit-width': fitWidth }" (mouseenter)="loadActions()">
|
||||||
<my-video-thumbnail
|
<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)"
|
[displayWatchLaterPlaylist]="isWatchLaterPlaylistDisplayed()" [inWatchLaterPlaylist]="inWatchLaterPlaylist" (watchLaterClick)="onWatchLaterClick($event)"
|
||||||
>
|
>
|
||||||
<ng-container ngProjectAs="label-warning" *ngIf="displayOptions.privacyLabel && isUnlistedVideo()" i18n>Unlisted</ng-container>
|
<ng-container ngProjectAs="label-warning" *ngIf="displayOptions.privacyLabel && isUnlistedVideo()" i18n>Unlisted</ng-container>
|
||||||
|
@ -15,10 +15,12 @@
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<div class="w-100 d-flex flex-column">
|
<div class="w-100 d-flex flex-column">
|
||||||
<a
|
<a *ngIf="!videoHref" tabindex="-1" class="video-miniature-name"
|
||||||
tabindex="-1"
|
[routerLink]="videoRouterLink" [attr.title]="video.name" [ngClass]="{ 'blur-filter': isVideoBlur }"
|
||||||
class="video-miniature-name"
|
>{{ video.name }}</a>
|
||||||
[routerLink]="videoLink" [attr.title]="video.name" [ngClass]="{ 'blur-filter': isVideoBlur }"
|
|
||||||
|
<a *ngIf="videoHref" tabindex="-1" class="video-miniature-name"
|
||||||
|
[href]="videoHref" [target]="videoTarget" [attr.title]="video.name" [ngClass]="{ 'blur-filter': isVideoBlur }"
|
||||||
>{{ video.name }}</a>
|
>{{ video.name }}</a>
|
||||||
|
|
||||||
<span class="video-miniature-created-at-views">
|
<span class="video-miniature-created-at-views">
|
||||||
|
|
|
@ -29,6 +29,7 @@ export type MiniatureDisplayOptions = {
|
||||||
blacklistInfo?: boolean
|
blacklistInfo?: boolean
|
||||||
nsfw?: boolean
|
nsfw?: boolean
|
||||||
}
|
}
|
||||||
|
export type VideoLinkType = 'internal' | 'lazy-load' | 'external'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-video-miniature',
|
selector: 'my-video-miniature',
|
||||||
|
@ -55,7 +56,7 @@ export class VideoMiniatureComponent implements OnInit {
|
||||||
@Input() displayVideoActions = true
|
@Input() displayVideoActions = true
|
||||||
@Input() fitWidth = false
|
@Input() fitWidth = false
|
||||||
|
|
||||||
@Input() useLazyLoadUrl = false
|
@Input() videoLinkType: VideoLinkType = 'internal'
|
||||||
|
|
||||||
@Output() videoBlocked = new EventEmitter()
|
@Output() videoBlocked = new EventEmitter()
|
||||||
@Output() videoUnblocked = new EventEmitter()
|
@Output() videoUnblocked = new EventEmitter()
|
||||||
|
@ -85,7 +86,9 @@ export class VideoMiniatureComponent implements OnInit {
|
||||||
playlistElementId?: number
|
playlistElementId?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
videoLink: any[] = []
|
videoRouterLink: any[] = []
|
||||||
|
videoHref: string
|
||||||
|
videoTarget: string
|
||||||
|
|
||||||
private ownerDisplayTypeChosen: 'account' | 'videoChannel'
|
private ownerDisplayTypeChosen: 'account' | 'videoChannel'
|
||||||
|
|
||||||
|
@ -125,18 +128,20 @@ export class VideoMiniatureComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
buildVideoLink () {
|
buildVideoLink () {
|
||||||
if (this.useLazyLoadUrl && this.video.url) {
|
if (this.videoLinkType === 'internal' || !this.video.url) {
|
||||||
const remoteUriConfig = this.serverConfig.search.remoteUri
|
this.videoRouterLink = [ '/videos/watch', this.video.uuid ]
|
||||||
|
|
||||||
// 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
|
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 () {
|
displayOwnerAccount () {
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<my-video-thumbnail
|
<my-video-thumbnail
|
||||||
*ngIf="playlistElement.video"
|
*ngIf="playlistElement.video"
|
||||||
[video]="playlistElement.video" [nsfw]="isVideoBlur(playlistElement.video)"
|
[video]="playlistElement.video" [nsfw]="isVideoBlur(playlistElement.video)"
|
||||||
[routerLink]="buildRouterLink()" [queryParams]="buildRouterQuery()"
|
[videoRouterLink]="buildRouterLink()" [queryParams]="buildRouterQuery()"
|
||||||
></my-video-thumbnail>
|
></my-video-thumbnail>
|
||||||
|
|
||||||
<div class="fake-thumbnail" *ngIf="!playlistElement.video"></div>
|
<div class="fake-thumbnail" *ngIf="!playlistElement.video"></div>
|
||||||
|
|
Loading…
Reference in New Issue