Create a dedicated component for video description
This commit is contained in:
parent
6ea59f4154
commit
b0c43e36db
|
@ -0,0 +1,19 @@
|
|||
<div class="video-info-description">
|
||||
<div
|
||||
class="video-info-description-html"
|
||||
[innerHTML]="videoHTMLDescription"
|
||||
(timestampClicked)="onTimestampClicked($event)"
|
||||
timestampRouteTransformer
|
||||
></div>
|
||||
|
||||
<div class="video-info-description-more" *ngIf="completeDescriptionShown === false && video.description?.length >= 250" (click)="showMoreDescription()">
|
||||
<ng-container i18n>Show more</ng-container>
|
||||
<span *ngIf="descriptionLoading === false" class="glyphicon glyphicon-menu-down"></span>
|
||||
<my-small-loader class="description-loading" [loading]="descriptionLoading"></my-small-loader>
|
||||
</div>
|
||||
|
||||
<div *ngIf="completeDescriptionShown === true" (click)="showLessDescription()" class="video-info-description-more">
|
||||
<ng-container i18n>Show less</ng-container>
|
||||
<span *ngIf="descriptionLoading === false" class="glyphicon glyphicon-menu-up"></span>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,46 @@
|
|||
@use '_variables' as *;
|
||||
@use '_mixins' as *;
|
||||
|
||||
.video-info-description {
|
||||
@include margin-left($video-watch-info-margin-left);
|
||||
@include margin-right(0);
|
||||
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
font-size: 15px;
|
||||
|
||||
.video-info-description-html {
|
||||
@include peertube-word-wrap;
|
||||
|
||||
::ng-deep a {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.glyphicon,
|
||||
.description-loading {
|
||||
@include margin-left(3px);
|
||||
}
|
||||
|
||||
.description-loading {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.video-info-description-more {
|
||||
cursor: pointer;
|
||||
font-weight: $font-semibold;
|
||||
color: pvar(--greyForegroundColor);
|
||||
font-size: 14px;
|
||||
|
||||
.glyphicon {
|
||||
position: relative;
|
||||
top: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 450px) {
|
||||
.video-info-description {
|
||||
font-size: 14px !important;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
import { Component, EventEmitter, Inject, Input, LOCALE_ID, OnChanges, Output } from '@angular/core'
|
||||
import { MarkdownService, Notifier } from '@app/core'
|
||||
import { VideoDetails, VideoService } from '@app/shared/shared-main'
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'my-video-description',
|
||||
templateUrl: './video-description.component.html',
|
||||
styleUrls: [ './video-description.component.scss' ]
|
||||
})
|
||||
export class VideoDescriptionComponent implements OnChanges {
|
||||
@Input() video: VideoDetails
|
||||
|
||||
@Output() timestampClicked = new EventEmitter<number>()
|
||||
|
||||
descriptionLoading = false
|
||||
completeDescriptionShown = false
|
||||
completeVideoDescription: string
|
||||
shortVideoDescription: string
|
||||
videoHTMLDescription = ''
|
||||
|
||||
constructor (
|
||||
private videoService: VideoService,
|
||||
private notifier: Notifier,
|
||||
private markdownService: MarkdownService,
|
||||
@Inject(LOCALE_ID) private localeId: string
|
||||
) { }
|
||||
|
||||
ngOnChanges () {
|
||||
this.descriptionLoading = false
|
||||
this.completeDescriptionShown = false
|
||||
this.completeVideoDescription = undefined
|
||||
|
||||
this.setVideoDescriptionHTML()
|
||||
}
|
||||
|
||||
showMoreDescription () {
|
||||
if (this.completeVideoDescription === undefined) {
|
||||
return this.loadCompleteDescription()
|
||||
}
|
||||
|
||||
this.updateVideoDescription(this.completeVideoDescription)
|
||||
this.completeDescriptionShown = true
|
||||
}
|
||||
|
||||
showLessDescription () {
|
||||
this.updateVideoDescription(this.shortVideoDescription)
|
||||
this.completeDescriptionShown = false
|
||||
}
|
||||
|
||||
loadCompleteDescription () {
|
||||
this.descriptionLoading = true
|
||||
|
||||
this.videoService.loadCompleteDescription(this.video.descriptionPath)
|
||||
.subscribe(
|
||||
description => {
|
||||
this.completeDescriptionShown = true
|
||||
this.descriptionLoading = false
|
||||
|
||||
this.shortVideoDescription = this.video.description
|
||||
this.completeVideoDescription = description
|
||||
|
||||
this.updateVideoDescription(this.completeVideoDescription)
|
||||
},
|
||||
|
||||
error => {
|
||||
this.descriptionLoading = false
|
||||
this.notifier.error(error.message)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
onTimestampClicked (timestamp: number) {
|
||||
this.timestampClicked.emit(timestamp)
|
||||
}
|
||||
|
||||
private updateVideoDescription (description: string) {
|
||||
this.video.description = description
|
||||
this.setVideoDescriptionHTML()
|
||||
.catch(err => console.error(err))
|
||||
}
|
||||
|
||||
private async setVideoDescriptionHTML () {
|
||||
const html = await this.markdownService.textMarkdownToHTML(this.video.description)
|
||||
this.videoHTMLDescription = this.markdownService.processVideoTimestamps(html)
|
||||
}
|
||||
}
|
|
@ -186,25 +186,7 @@
|
|||
|
||||
</div>
|
||||
|
||||
<div class="video-info-description">
|
||||
<div
|
||||
class="video-info-description-html"
|
||||
[innerHTML]="videoHTMLDescription"
|
||||
(timestampClicked)="handleTimestampClicked($event)"
|
||||
timestampRouteTransformer
|
||||
></div>
|
||||
|
||||
<div class="video-info-description-more" *ngIf="completeDescriptionShown === false && video.description?.length >= 250" (click)="showMoreDescription()">
|
||||
<ng-container i18n>Show more</ng-container>
|
||||
<span *ngIf="descriptionLoading === false" class="glyphicon glyphicon-menu-down"></span>
|
||||
<my-small-loader class="description-loading" [loading]="descriptionLoading"></my-small-loader>
|
||||
</div>
|
||||
|
||||
<div *ngIf="completeDescriptionShown === true" (click)="showLessDescription()" class="video-info-description-more">
|
||||
<ng-container i18n>Show less</ng-container>
|
||||
<span *ngIf="descriptionLoading === false" class="glyphicon glyphicon-menu-up"></span>
|
||||
</div>
|
||||
</div>
|
||||
<my-video-description [video]="video"></my-video-description>
|
||||
|
||||
<div class="video-attributes mb-3">
|
||||
<div class="video-attribute">
|
||||
|
|
|
@ -4,15 +4,12 @@
|
|||
@use '_bootstrap-variables';
|
||||
@use '_miniature' as *;
|
||||
|
||||
$player-factor: math.div(16, 9);
|
||||
$video-info-margin-left: 44px;
|
||||
|
||||
@function getPlayerHeight ($width) {
|
||||
@return calc(#{$width} / #{$player-factor});
|
||||
@return calc(#{$width} / #{$video-watch-player-factor});
|
||||
}
|
||||
|
||||
@function getPlayerWidth ($height) {
|
||||
@return calc(#{$height} * #{$player-factor});
|
||||
@return calc(#{$height} * #{$video-watch-player-factor});
|
||||
}
|
||||
|
||||
@mixin playlist-below-player {
|
||||
|
@ -316,46 +313,8 @@ $video-info-margin-left: 44px;
|
|||
}
|
||||
}
|
||||
|
||||
.video-info-description {
|
||||
@include margin-left($video-info-margin-left);
|
||||
@include margin-right(0);
|
||||
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
font-size: 15px;
|
||||
|
||||
.video-info-description-html {
|
||||
@include peertube-word-wrap;
|
||||
|
||||
::ng-deep a {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.glyphicon,
|
||||
.description-loading {
|
||||
@include margin-left(3px);
|
||||
}
|
||||
|
||||
.description-loading {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.video-info-description-more {
|
||||
cursor: pointer;
|
||||
font-weight: $font-semibold;
|
||||
color: pvar(--greyForegroundColor);
|
||||
font-size: 14px;
|
||||
|
||||
.glyphicon {
|
||||
position: relative;
|
||||
top: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.video-attributes {
|
||||
@include margin-left($video-info-margin-left);
|
||||
@include margin-left($video-watch-info-margin-left);
|
||||
}
|
||||
|
||||
.video-attributes .video-attribute {
|
||||
|
@ -555,10 +514,6 @@ my-video-comments {
|
|||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.video-info-description {
|
||||
font-size: 14px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ import {
|
|||
AuthService,
|
||||
AuthUser,
|
||||
ConfirmService,
|
||||
MarkdownService,
|
||||
MetaService,
|
||||
Notifier,
|
||||
PeerTubeSocket,
|
||||
|
@ -139,7 +138,6 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
|||
private serverService: ServerService,
|
||||
private restExtractor: RestExtractor,
|
||||
private notifier: Notifier,
|
||||
private markdownService: MarkdownService,
|
||||
private zone: NgZone,
|
||||
private redirectService: RedirectService,
|
||||
private videoCaptionService: VideoCaptionService,
|
||||
|
@ -228,20 +226,6 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
|||
this.hotkeysService.remove(this.hotkeys)
|
||||
}
|
||||
|
||||
showMoreDescription () {
|
||||
if (this.completeVideoDescription === undefined) {
|
||||
return this.loadCompleteDescription()
|
||||
}
|
||||
|
||||
this.updateVideoDescription(this.completeVideoDescription)
|
||||
this.completeDescriptionShown = true
|
||||
}
|
||||
|
||||
showLessDescription () {
|
||||
this.updateVideoDescription(this.shortVideoDescription)
|
||||
this.completeDescriptionShown = false
|
||||
}
|
||||
|
||||
showDownloadModal () {
|
||||
this.videoDownloadModal.show(this.video, this.videoCaptions)
|
||||
}
|
||||
|
@ -250,28 +234,6 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
|||
return this.video && this.video instanceof VideoDetails && this.video.downloadEnabled && !this.video.isLive
|
||||
}
|
||||
|
||||
loadCompleteDescription () {
|
||||
this.descriptionLoading = true
|
||||
|
||||
this.videoService.loadCompleteDescription(this.video.descriptionPath)
|
||||
.subscribe(
|
||||
description => {
|
||||
this.completeDescriptionShown = true
|
||||
this.descriptionLoading = false
|
||||
|
||||
this.shortVideoDescription = this.video.description
|
||||
this.completeVideoDescription = description
|
||||
|
||||
this.updateVideoDescription(this.completeVideoDescription)
|
||||
},
|
||||
|
||||
error => {
|
||||
this.descriptionLoading = false
|
||||
this.notifier.error(error.message)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
showSupportModal () {
|
||||
this.supportModal.show()
|
||||
}
|
||||
|
@ -492,17 +454,6 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
|||
})
|
||||
}
|
||||
|
||||
private updateVideoDescription (description: string) {
|
||||
this.video.description = description
|
||||
this.setVideoDescriptionHTML()
|
||||
.catch(err => console.error(err))
|
||||
}
|
||||
|
||||
private async setVideoDescriptionHTML () {
|
||||
const html = await this.markdownService.textMarkdownToHTML(this.video.description)
|
||||
this.videoHTMLDescription = this.markdownService.processVideoTimestamps(html)
|
||||
}
|
||||
|
||||
private setVideoLikesBarTooltipText () {
|
||||
this.likesBarTooltipText = `${this.video.likes} likes / ${this.video.dislikes} dislikes`
|
||||
}
|
||||
|
@ -552,7 +503,6 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
|||
this.buildPlayer(urlOptions)
|
||||
.catch(err => console.error('Cannot build the player', err))
|
||||
|
||||
this.setVideoDescriptionHTML()
|
||||
this.setVideoLikesBarTooltipText()
|
||||
|
||||
this.setOpenGraphTags()
|
||||
|
|
|
@ -19,6 +19,7 @@ import { PlayerStylesComponent } from './player-styles.component'
|
|||
import { RecommendationsModule } from './recommendations/recommendations.module'
|
||||
import { TimestampRouteTransformerDirective } from './timestamp-route-transformer.directive'
|
||||
import { VideoAvatarChannelComponent } from './video-avatar-channel.component'
|
||||
import { VideoDescriptionComponent } from './video-description.component'
|
||||
import { VideoRateComponent } from './video-rate.component'
|
||||
import { VideoWatchPlaylistComponent } from './video-watch-playlist.component'
|
||||
import { VideoWatchRoutingModule } from './video-watch-routing.module'
|
||||
|
@ -47,6 +48,7 @@ import { VideoWatchComponent } from './video-watch.component'
|
|||
VideoWatchComponent,
|
||||
VideoWatchPlaylistComponent,
|
||||
VideoRateComponent,
|
||||
VideoDescriptionComponent,
|
||||
|
||||
VideoCommentsComponent,
|
||||
VideoCommentAddComponent,
|
||||
|
|
|
@ -95,6 +95,9 @@ $activated-action-button-color: #000;
|
|||
|
||||
$focus-box-shadow-form: 0 0 0 .2rem;
|
||||
|
||||
$video-watch-player-factor: math.div(16, 9);
|
||||
$video-watch-info-margin-left: 44px;
|
||||
|
||||
/*** map theme ***/
|
||||
|
||||
// pass variables into a sass map,
|
||||
|
|
Loading…
Reference in New Issue