diff --git a/client/src/app/+my-account/my-account-history/my-account-history.component.html b/client/src/app/+my-account/my-account-history/my-account-history.component.html
index 653b33f89..d42af37d4 100644
--- a/client/src/app/+my-account/my-account-history/my-account-history.component.html
+++ b/client/src/app/+my-account/my-account-history/my-account-history.component.html
@@ -1,4 +1,16 @@
-
You don't have history yet.
+You don't have videos history yet.
diff --git a/client/src/app/+my-account/my-account-history/my-account-history.component.scss b/client/src/app/+my-account/my-account-history/my-account-history.component.scss
index 115bb0e5c..82150cbe3 100644
--- a/client/src/app/+my-account/my-account-history/my-account-history.component.scss
+++ b/client/src/app/+my-account/my-account-history/my-account-history.component.scss
@@ -1,6 +1,37 @@
@import '_variables';
@import '_mixins';
+.no-history {
+ display: flex;
+ justify-content: center;
+ margin-top: 50px;
+ font-weight: $font-semibold;
+ font-size: 16px;
+}
+
+.top-buttons {
+ margin-bottom: 20px;
+ display: flex;
+
+ .history-switch {
+ display: flex;
+ flex-grow: 1;
+
+ label {
+ margin: 0 0 0 5px;
+ }
+ }
+
+ .delete-history {
+ font-size: 15px;
+
+ button {
+ @include peertube-button;
+ @include grey-button;
+ }
+ }
+}
+
.video {
@include row-blocks;
diff --git a/client/src/app/+my-account/my-account-history/my-account-history.component.ts b/client/src/app/+my-account/my-account-history/my-account-history.component.ts
index 508552167..6ec4fefe8 100644
--- a/client/src/app/+my-account/my-account-history/my-account-history.component.ts
+++ b/client/src/app/+my-account/my-account-history/my-account-history.component.ts
@@ -11,6 +11,7 @@ import { VideoService } from '../../shared/video/video.service'
import { I18n } from '@ngx-translate/i18n-polyfill'
import { ScreenService } from '@app/shared/misc/screen.service'
import { UserHistoryService } from '@app/shared/users/user-history.service'
+import { UserService } from '@app/shared'
@Component({
selector: 'my-account-history',
@@ -25,6 +26,7 @@ export class MyAccountHistoryComponent extends AbstractVideoList implements OnIn
itemsPerPage: 5,
totalItems: null
}
+ videosHistoryEnabled: boolean
protected baseVideoWidth = -1
protected baseVideoHeight = 155
@@ -33,6 +35,7 @@ export class MyAccountHistoryComponent extends AbstractVideoList implements OnIn
protected router: Router,
protected route: ActivatedRoute,
protected authService: AuthService,
+ protected userService: UserService,
protected notificationsService: NotificationsService,
protected location: Location,
protected screenService: ScreenService,
@@ -48,6 +51,8 @@ export class MyAccountHistoryComponent extends AbstractVideoList implements OnIn
ngOnInit () {
super.ngOnInit()
+
+ this.videosHistoryEnabled = this.authService.getUser().videosHistoryEnabled
}
ngOnDestroy () {
@@ -63,4 +68,40 @@ export class MyAccountHistoryComponent extends AbstractVideoList implements OnIn
generateSyndicationList () {
throw new Error('Method not implemented.')
}
+
+ onVideosHistoryChange () {
+ this.userService.updateMyProfile({ videosHistoryEnabled: this.videosHistoryEnabled })
+ .subscribe(
+ () => {
+ const message = this.videosHistoryEnabled === true ?
+ this.i18n('Videos history is enabled') :
+ this.i18n('Videos history is disabled')
+
+ this.notificationsService.success(this.i18n('Success'), message)
+
+ this.authService.refreshUserInformation()
+ },
+
+ err => this.notificationsService.error(this.i18n('Error'), err.message)
+ )
+ }
+
+ async deleteHistory () {
+ const title = this.i18n('Delete videos history')
+ const message = this.i18n('Are you sure you want to delete all your videos history?')
+
+ const res = await this.confirmService.confirm(message, title)
+ if (res !== true) return
+
+ this.userHistoryService.deleteUserVideosHistory()
+ .subscribe(
+ () => {
+ this.notificationsService.success(this.i18n('Success'), this.i18n('Videos history deleted'))
+
+ this.reloadVideos()
+ },
+
+ err => this.notificationsService.error(this.i18n('Error'), err.message)
+ )
+ }
}
diff --git a/client/src/app/+my-account/my-account.module.ts b/client/src/app/+my-account/my-account.module.ts
index c05406438..80d9f0cf7 100644
--- a/client/src/app/+my-account/my-account.module.ts
+++ b/client/src/app/+my-account/my-account.module.ts
@@ -1,6 +1,7 @@
import { TableModule } from 'primeng/table'
import { NgModule } from '@angular/core'
import { AutoCompleteModule } from 'primeng/autocomplete'
+import { InputSwitchModule } from 'primeng/inputswitch'
import { SharedModule } from '../shared'
import { MyAccountRoutingModule } from './my-account-routing.module'
import { MyAccountChangePasswordComponent } from './my-account-settings/my-account-change-password/my-account-change-password.component'
@@ -29,7 +30,8 @@ import { MyAccountHistoryComponent } from '@app/+my-account/my-account-history/m
MyAccountRoutingModule,
AutoCompleteModule,
SharedModule,
- TableModule
+ TableModule,
+ InputSwitchModule
],
declarations: [
diff --git a/client/src/app/core/auth/auth-user.model.ts b/client/src/app/core/auth/auth-user.model.ts
index acd13d9c5..abb11fdc2 100644
--- a/client/src/app/core/auth/auth-user.model.ts
+++ b/client/src/app/core/auth/auth-user.model.ts
@@ -1,8 +1,9 @@
import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage'
import { UserRight } from '../../../../../shared/models/users/user-right.enum'
+import { User as ServerUserModel } from '../../../../../shared/models/users/user.model'
// Do not use the barrel (dependency loop)
import { hasUserRight, UserRole } from '../../../../../shared/models/users/user-role'
-import { User, UserConstructorHash } from '../../shared/users/user.model'
+import { User } from '../../shared/users/user.model'
import { NSFWPolicyType } from '../../../../../shared/models/videos/nsfw-policy.type'
export type TokenOptions = {
@@ -70,6 +71,7 @@ export class AuthUser extends User {
ID: 'id',
ROLE: 'role',
EMAIL: 'email',
+ VIDEOS_HISTORY_ENABLED: 'videos-history-enabled',
USERNAME: 'username',
NSFW_POLICY: 'nsfw_policy',
WEBTORRENT_ENABLED: 'peertube-videojs-' + 'webtorrent_enabled',
@@ -89,7 +91,8 @@ export class AuthUser extends User {
role: parseInt(peertubeLocalStorage.getItem(this.KEYS.ROLE), 10) as UserRole,
nsfwPolicy: peertubeLocalStorage.getItem(this.KEYS.NSFW_POLICY) as NSFWPolicyType,
webTorrentEnabled: peertubeLocalStorage.getItem(this.KEYS.WEBTORRENT_ENABLED) === 'true',
- autoPlayVideo: peertubeLocalStorage.getItem(this.KEYS.AUTO_PLAY_VIDEO) === 'true'
+ autoPlayVideo: peertubeLocalStorage.getItem(this.KEYS.AUTO_PLAY_VIDEO) === 'true',
+ videosHistoryEnabled: peertubeLocalStorage.getItem(this.KEYS.VIDEOS_HISTORY_ENABLED) === 'true'
},
Tokens.load()
)
@@ -104,12 +107,13 @@ export class AuthUser extends User {
peertubeLocalStorage.removeItem(this.KEYS.ROLE)
peertubeLocalStorage.removeItem(this.KEYS.NSFW_POLICY)
peertubeLocalStorage.removeItem(this.KEYS.WEBTORRENT_ENABLED)
+ peertubeLocalStorage.removeItem(this.KEYS.VIDEOS_HISTORY_ENABLED)
peertubeLocalStorage.removeItem(this.KEYS.AUTO_PLAY_VIDEO)
peertubeLocalStorage.removeItem(this.KEYS.EMAIL)
Tokens.flush()
}
- constructor (userHash: UserConstructorHash, hashTokens: TokenOptions) {
+ constructor (userHash: Partial, hashTokens: TokenOptions) {
super(userHash)
this.tokens = new Tokens(hashTokens)
}
diff --git a/client/src/app/core/routing/login-guard.service.ts b/client/src/app/core/routing/login-guard.service.ts
index 18bc41ca6..7b1c37ee8 100644
--- a/client/src/app/core/routing/login-guard.service.ts
+++ b/client/src/app/core/routing/login-guard.service.ts
@@ -1,11 +1,5 @@
import { Injectable } from '@angular/core'
-import {
- ActivatedRouteSnapshot,
- CanActivateChild,
- RouterStateSnapshot,
- CanActivate,
- Router
-} from '@angular/router'
+import { ActivatedRouteSnapshot, CanActivate, CanActivateChild, Router, RouterStateSnapshot } from '@angular/router'
import { AuthService } from '../auth/auth.service'
diff --git a/client/src/app/shared/users/user.model.ts b/client/src/app/shared/users/user.model.ts
index 9819829fd..3663a7b61 100644
--- a/client/src/app/shared/users/user.model.ts
+++ b/client/src/app/shared/users/user.model.ts
@@ -1,33 +1,8 @@
-import {
- Account as AccountServerModel,
- hasUserRight,
- User as UserServerModel,
- UserRight,
- UserRole,
- VideoChannel
-} from '../../../../../shared'
+import { hasUserRight, User as UserServerModel, UserRight, UserRole, VideoChannel } from '../../../../../shared'
import { NSFWPolicyType } from '../../../../../shared/models/videos/nsfw-policy.type'
import { Account } from '@app/shared/account/account.model'
import { Avatar } from '../../../../../shared/models/avatars/avatar.model'
-export type UserConstructorHash = {
- id: number,
- username: string,
- email: string,
- role: UserRole,
- emailVerified?: boolean,
- videoQuota?: number,
- videoQuotaDaily?: number,
- nsfwPolicy?: NSFWPolicyType,
- webTorrentEnabled?: boolean,
- autoPlayVideo?: boolean,
- createdAt?: Date,
- account?: AccountServerModel,
- videoChannels?: VideoChannel[]
-
- blocked?: boolean
- blockedReason?: string
-}
export class User implements UserServerModel {
id: number
username: string
@@ -35,8 +10,11 @@ export class User implements UserServerModel {
emailVerified: boolean
role: UserRole
nsfwPolicy: NSFWPolicyType
+
webTorrentEnabled: boolean
autoPlayVideo: boolean
+ videosHistoryEnabled: boolean
+
videoQuota: number
videoQuotaDaily: number
account: Account
@@ -46,7 +24,7 @@ export class User implements UserServerModel {
blocked: boolean
blockedReason?: string
- constructor (hash: UserConstructorHash) {
+ constructor (hash: Partial) {
this.id = hash.id
this.username = hash.username
this.email = hash.email
@@ -57,6 +35,7 @@ export class User implements UserServerModel {
this.videoQuotaDaily = hash.videoQuotaDaily
this.nsfwPolicy = hash.nsfwPolicy
this.webTorrentEnabled = hash.webTorrentEnabled
+ this.videosHistoryEnabled = hash.videosHistoryEnabled
this.autoPlayVideo = hash.autoPlayVideo
this.createdAt = hash.createdAt
this.blocked = hash.blocked
diff --git a/client/src/app/videos/+video-edit/video-add-components/video-upload.component.scss b/client/src/app/videos/+video-edit/video-add-components/video-upload.component.scss
index cf1725ef9..4b2c86ae9 100644
--- a/client/src/app/videos/+video-edit/video-add-components/video-upload.component.scss
+++ b/client/src/app/videos/+video-edit/video-add-components/video-upload.component.scss
@@ -54,9 +54,7 @@
/deep/ .ui-progressbar {
font-size: 15px !important;
- color: #fff !important;
height: 30px !important;
- line-height: 30px !important;
border-radius: 3px !important;
background-color: rgba(11, 204, 41, 0.16) !important;
@@ -68,6 +66,8 @@
text-align: left;
padding-left: 18px;
margin-top: 0 !important;
+ color: #fff !important;
+ line-height: 30px !important;
}
}
diff --git a/client/src/sass/primeng-custom.scss b/client/src/sass/primeng-custom.scss
index 0568de4e2..1d6eebcfa 100644
--- a/client/src/sass/primeng-custom.scss
+++ b/client/src/sass/primeng-custom.scss
@@ -2,7 +2,7 @@
@import '_mixins';
@import '~primeng/resources/primeng.css';
-@import '~primeng/resources/themes/bootstrap/theme.css';
+@import '~primeng/resources/themes/nova-light/theme.css';
@mixin glyphicon-light {
font-family: 'Glyphicons Halflings';
@@ -12,10 +12,9 @@
// data table customizations
p-table {
- font-size: 15px !important;
-
.ui-table-caption {
- border: none;
+ border: none !important;
+ background-color: #fff !important;
.caption {
height: 40px;
@@ -24,6 +23,17 @@ p-table {
}
}
+ th {
+ background-color: #fff !important;
+ outline: 0;
+ }
+
+ td, th {
+ font-family: $main-fonts;
+ font-size: 15px !important;
+ color: var(--mainForegroundColor) !important;
+ }
+
td {
padding-left: 15px !important;
@@ -35,12 +45,16 @@ p-table {
}
tr {
+ outline: 0;
background-color: var(--mainBackgroundColor) !important;
height: 46px;
&.ui-state-highlight {
- background-color:var(--submenuColor) !important;
- color:var(--mainForegroundColor) !important;
+ background-color: var(--submenuColor) !important;
+
+ td, td > a {
+ color: var(--mainForegroundColor) !important;
+ }
}
}
@@ -56,6 +70,10 @@ p-table {
}
}
+ td {
+ border: none !important;
+ }
+
&:first-child td {
border-top: none !important;
}
@@ -93,14 +111,14 @@ p-table {
}
&.ui-state-highlight {
- background-color:var(--submenuColor) !important;
+ background-color: var(--submenuColor) !important;
.pi {
@extend .glyphicon;
- color: #000;
- font-size: 11px;
- top: 0;
+ color: #000 !important;
+ font-size: 11px !important;
+ top: 0 !important;
&.pi-sort-up {
@extend .glyphicon-triangle-top;
@@ -177,11 +195,12 @@ p-table {
a {
color: #000 !important;
font-weight: $font-semibold !important;
- margin: 0 10px !important;
+ margin: 0 5px !important;
outline: 0 !important;
border-radius: 3px !important;
padding: 5px 2px !important;
height: auto !important;
+ line-height: initial !important;
&.ui-state-active {
&, &:hover, &:active, &:focus {
@@ -210,11 +229,23 @@ p-calendar .ui-datepicker {
.ui-datepicker-next {
@extend .glyphicon-chevron-right;
@include glyphicon-light;
+
+ text-align: right;
+
+ .pi.pi-chevron-right {
+ display: none !important;
+ }
}
.ui-datepicker-prev {
@extend .glyphicon-chevron-left;
@include glyphicon-light;
+
+ text-align: left;
+
+ .pi.pi-chevron-left {
+ display: none !important;
+ }
}
}
@@ -232,6 +263,7 @@ p-calendar .ui-datepicker {
}
}
+
.ui-chkbox-box {
&.ui-state-active {
border-color: var(--mainColor) !important;
@@ -240,13 +272,15 @@ p-calendar .ui-datepicker {
.ui-chkbox-icon {
position: relative;
+ overflow: visible !important;
&:after {
content: '';
position: absolute;
- left: 5px;
+ top: 1px;
+ left: 7px;
width: 5px;
- height: 12px;
+ height: 13px;
opacity: 0;
transform: rotate(45deg) scale(0);
border-right: 2px solid var(--mainBackgroundColor);
@@ -258,4 +292,10 @@ p-calendar .ui-datepicker {
transform: rotate(45deg) scale(1);
}
}
-}
\ No newline at end of file
+}
+
+p-inputswitch {
+ .ui-inputswitch-checked .ui-inputswitch-slider {
+ background-color: var(--mainColor) !important;
+ }
+}
diff --git a/server/models/account/user.ts b/server/models/account/user.ts
index ea017c338..180ced810 100644
--- a/server/models/account/user.ts
+++ b/server/models/account/user.ts
@@ -370,6 +370,7 @@ export class UserModel extends Model {
emailVerified: this.emailVerified,
nsfwPolicy: this.nsfwPolicy,
webTorrentEnabled: this.webTorrentEnabled,
+ videosHistoryEnabled: this.videosHistoryEnabled,
autoPlayVideo: this.autoPlayVideo,
role: this.role,
roleLabel: USER_ROLE_LABELS[ this.role ],
diff --git a/shared/models/users/user.model.ts b/shared/models/users/user.model.ts
index 82af17516..2aabff494 100644
--- a/shared/models/users/user.model.ts
+++ b/shared/models/users/user.model.ts
@@ -9,7 +9,11 @@ export interface User {
email: string
emailVerified: boolean
nsfwPolicy: NSFWPolicyType
+
autoPlayVideo: boolean
+ webTorrentEnabled: boolean
+ videosHistoryEnabled: boolean
+
role: UserRole
videoQuota: number
videoQuotaDaily: number