Add messages about privacy concerns (P2P)

pull/322/head
Chocobozzz 2018-02-28 15:33:45 +01:00
parent d7137ad5fb
commit 22b59e8099
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
7 changed files with 116 additions and 67 deletions

View File

@ -18,7 +18,7 @@
<ng-template pTemplate="body" let-videoAbuse> <ng-template pTemplate="body" let-videoAbuse>
<tr> <tr>
<td>{{ videoAbuse.reason }}</td> <td>{{ videoAbuse.reason }}</td>
<td>{{ videoAbuse.reporterServerHost + '@' + videoAbuse.reporterUsername }}</td> <td>{{ videoAbuse.reporterUsername + '@' + videoAbuse.reporterServerHost }}</td>
<td>{{ videoAbuse.createdAt }}</td> <td>{{ videoAbuse.createdAt }}</td>
<td> <td>
<a [routerLink]="getRouterVideoLink(videoAbuse.videoUUID)" title="Go to the video">{{ videoAbuse.videoName }}</a> <a [routerLink]="getRouterVideoLink(videoAbuse.videoUUID)" title="Go to the video">{{ videoAbuse.videoName }}</a>

View File

@ -21,7 +21,7 @@
</span> </span>
<input <input
type="submit" value="Confirm" class="action-button-submit" [disabled]="isConfirmationDisabled()" type="submit" [value]="confirmButtonText" class="action-button-submit" [disabled]="isConfirmationDisabled()"
(click)="confirm()" (click)="confirm()"
> >
</div> </div>

View File

@ -18,6 +18,7 @@ export class ConfirmComponent implements OnInit {
inputLabel = '' inputLabel = ''
inputValue = '' inputValue = ''
confirmButtonText = ''
constructor (private confirmService: ConfirmService) { constructor (private confirmService: ConfirmService) {
// Empty // Empty
@ -30,13 +31,15 @@ export class ConfirmComponent implements OnInit {
} }
this.confirmService.showConfirm.subscribe( this.confirmService.showConfirm.subscribe(
({ title, message, expectedInputValue, inputLabel }) => { ({ title, message, expectedInputValue, inputLabel, confirmButtonText }) => {
this.title = title this.title = title
this.message = message this.message = message
this.inputLabel = inputLabel this.inputLabel = inputLabel
this.expectedInputValue = expectedInputValue this.expectedInputValue = expectedInputValue
this.confirmButtonText = confirmButtonText || 'Confirm'
this.showModal() this.showModal()
} }
) )

View File

@ -3,19 +3,27 @@ import { Subject } from 'rxjs/Subject'
import 'rxjs/add/operator/first' import 'rxjs/add/operator/first'
import 'rxjs/add/operator/toPromise' import 'rxjs/add/operator/toPromise'
type ConfirmOptions = {
title: string
message: string
inputLabel?: string
expectedInputValue?: string
confirmButtonText?: string
}
@Injectable() @Injectable()
export class ConfirmService { export class ConfirmService {
showConfirm = new Subject<{ title: string, message: string, inputLabel?: string, expectedInputValue?: string }>() showConfirm = new Subject<ConfirmOptions>()
confirmResponse = new Subject<boolean>() confirmResponse = new Subject<boolean>()
confirm (message: string, title = '') { confirm (message: string, title = '', confirmButtonText?: string) {
this.showConfirm.next({ title, message }) this.showConfirm.next({ title, message, confirmButtonText })
return this.confirmResponse.asObservable().first().toPromise() return this.confirmResponse.asObservable().first().toPromise()
} }
confirmWithInput (message: string, inputLabel: string, expectedInputValue: string, title = '') { confirmWithInput (message: string, inputLabel: string, expectedInputValue: string, title = '', confirmButtonText?: string) {
this.showConfirm.next({ title, message, inputLabel, expectedInputValue }) this.showConfirm.next({ title, message, inputLabel, expectedInputValue, confirmButtonText })
return this.confirmResponse.asObservable().first().toPromise() return this.confirmResponse.asObservable().first().toPromise()
} }

View File

@ -26,6 +26,8 @@ import { VideoShareComponent } from './modal/video-share.component'
styleUrls: [ './video-watch.component.scss' ] styleUrls: [ './video-watch.component.scss' ]
}) })
export class VideoWatchComponent implements OnInit, OnDestroy { export class VideoWatchComponent implements OnInit, OnDestroy {
private static LOCAL_STORAGE_PRIVACY_CONCERN_KEY = 'video-watch-privacy-concern'
@ViewChild('videoDownloadModal') videoDownloadModal: VideoDownloadComponent @ViewChild('videoDownloadModal') videoDownloadModal: VideoDownloadComponent
@ViewChild('videoShareModal') videoShareModal: VideoShareComponent @ViewChild('videoShareModal') videoShareModal: VideoShareComponent
@ViewChild('videoReportModal') videoReportModal: VideoReportComponent @ViewChild('videoReportModal') videoReportModal: VideoReportComponent
@ -301,75 +303,76 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
) )
} }
private onVideoFetched (video: VideoDetails) { private async onVideoFetched (video: VideoDetails) {
this.video = video this.video = video
this.updateOtherVideosDisplayed() this.updateOtherVideosDisplayed()
let observable
if (this.video.isVideoNSFWForUser(this.user)) { if (this.video.isVideoNSFWForUser(this.user)) {
observable = this.confirmService.confirm( const res = await this.confirmService.confirm(
'This video contains mature or explicit content. Are you sure you want to watch it?', 'This video contains mature or explicit content. Are you sure you want to watch it?',
'Mature or explicit content' 'Mature or explicit content'
) )
} else { if (res === false) return this.router.navigate([ '/videos/list' ])
observable = Observable.of(true)
} }
observable.subscribe( if (!this.hasAlreadyAcceptedPrivacyConcern()) {
res => { const res = await this.confirmService.confirm(
if (res === false) { 'PeerTube uses P2P, other may know you are watching that video through your public IP address. ' +
'Are you okay with that?',
'Privacy concern',
'I accept!'
)
if (res === false) return this.router.navigate([ '/videos/list' ])
}
return this.router.navigate([ '/videos/list' ]) this.acceptedPrivacyConcern()
}
// Player was already loaded // Player was already loaded
if (this.videoPlayerLoaded !== true) { if (this.videoPlayerLoaded !== true) {
this.playerElement = this.elementRef.nativeElement.querySelector('#video-element') this.playerElement = this.elementRef.nativeElement.querySelector('#video-element')
// If autoplay is true, we don't really need a poster // If autoplay is true, we don't really need a poster
if (this.isAutoplay() === false) { if (this.isAutoplay() === false) {
this.playerElement.poster = this.video.previewUrl this.playerElement.poster = this.video.previewUrl
}
const videojsOptions = {
controls: true,
autoplay: this.isAutoplay(),
plugins: {
peertube: {
videoFiles: this.video.files,
playerElement: this.playerElement,
peerTubeLink: false,
videoViewUrl: this.videoService.getVideoViewUrl(this.video.uuid),
videoDuration: this.video.duration
},
hotkeys: {
enableVolumeScroll: false
}
}
}
this.videoPlayerLoaded = true
const self = this
this.zone.runOutsideAngular(() => {
videojs(this.playerElement, videojsOptions, function () {
self.player = this
this.on('customError', (event, data) => self.handleError(data.err))
})
})
} else {
const videoViewUrl = this.videoService.getVideoViewUrl(this.video.uuid)
this.player.peertube().setVideoFiles(this.video.files, videoViewUrl, this.video.duration)
}
this.setVideoDescriptionHTML()
this.setVideoLikesBarTooltipText()
this.setOpenGraphTags()
this.checkUserRating()
} }
)
const videojsOptions = {
controls: true,
autoplay: this.isAutoplay(),
plugins: {
peertube: {
videoFiles: this.video.files,
playerElement: this.playerElement,
peerTubeLink: false,
videoViewUrl: this.videoService.getVideoViewUrl(this.video.uuid),
videoDuration: this.video.duration
},
hotkeys: {
enableVolumeScroll: false
}
}
}
this.videoPlayerLoaded = true
const self = this
this.zone.runOutsideAngular(() => {
videojs(this.playerElement, videojsOptions, function () {
self.player = this
this.on('customError', (event, data) => self.handleError(data.err))
})
})
} else {
const videoViewUrl = this.videoService.getVideoViewUrl(this.video.uuid)
this.player.peertube().setVideoFiles(this.video.files, videoViewUrl, this.video.duration)
}
this.setVideoDescriptionHTML()
this.setVideoLikesBarTooltipText()
this.setOpenGraphTags()
this.checkUserRating()
} }
private setRating (nextRating) { private setRating (nextRating) {
@ -411,8 +414,8 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
this.video.likes += likesToIncrement this.video.likes += likesToIncrement
this.video.dislikes += dislikesToIncrement this.video.dislikes += dislikesToIncrement
this.video.buildLikeAndDislikePercents()
this.video.buildLikeAndDislikePercents()
this.setVideoLikesBarTooltipText() this.setVideoLikesBarTooltipText()
} }
@ -450,4 +453,12 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
// Be sure the autoPlay is set to false // Be sure the autoPlay is set to false
return this.user.autoPlayVideo !== false return this.user.autoPlayVideo !== false
} }
private hasAlreadyAcceptedPrivacyConcern () {
return localStorage.getItem(VideoWatchComponent.LOCAL_STORAGE_PRIVACY_CONCERN_KEY) === 'true'
}
private acceptedPrivacyConcern () {
localStorage.setItem(VideoWatchComponent.LOCAL_STORAGE_PRIVACY_CONCERN_KEY, 'true')
}
} }

View File

@ -1,4 +1,4 @@
// Thanks: https://github.com/zanechua/videojs-sublime-inspired-skin @charset "utf-8";// Thanks: https://github.com/zanechua/videojs-sublime-inspired-skin
$primary-foreground-color: #fff; $primary-foreground-color: #fff;
$primary-background-color: #000; $primary-background-color: #000;
$font-size: 13px; $font-size: 13px;
@ -8,6 +8,28 @@ $control-bar-height: 34px;
font-size: $font-size; font-size: $font-size;
color: $primary-foreground-color; color: $primary-foreground-color;
.vjs-dock-text {
padding-right: 10px;
}
.vjs-dock-description {
font-size: 11px;
&:before, &:after {
display: inline-block;
content: '\1F308';
}
&:before {
margin-right: 4px;
}
&:after {
margin-left: 4px;
transform: scale(-1, 1);
}
}
.vjs-button > .vjs-icon-placeholder::before { .vjs-button > .vjs-icon-placeholder::before {
line-height: $control-bar-height; line-height: $control-bar-height;
} }
@ -354,7 +376,11 @@ $control-bar-height: 34px;
@media screen and (max-width: 300px) { @media screen and (max-width: 300px) {
.vjs-dock-text { .vjs-dock-text {
font-size: 1em; font-size: 13px;
}
.vjs-dock-description {
font-size: 9px;
} }
.vjs-big-play-button { .vjs-big-play-button {

View File

@ -44,7 +44,8 @@ loadVideoInfo(videoId)
const player = this const player = this
player.dock({ player.dock({
title: videoInfo.name title: videoInfo.name,
description: 'Use P2P, other may know you are watching that video.'
}) })
}) })
}) })