diff options
Diffstat (limited to 'client/src/app/+my-library')
18 files changed, 303 insertions, 251 deletions
diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channel-create.component.ts b/client/src/app/+my-library/+my-video-channels/my-video-channel-create.component.ts index a625493de..b3265210f 100644 --- a/client/src/app/+my-library/+my-video-channels/my-video-channel-create.component.ts +++ b/client/src/app/+my-library/+my-video-channels/my-video-channel-create.component.ts | |||
@@ -8,10 +8,12 @@ import { | |||
8 | VIDEO_CHANNEL_SUPPORT_VALIDATOR | 8 | VIDEO_CHANNEL_SUPPORT_VALIDATOR |
9 | } from '@app/shared/form-validators/video-channel-validators' | 9 | } from '@app/shared/form-validators/video-channel-validators' |
10 | import { FormValidatorService } from '@app/shared/shared-forms' | 10 | import { FormValidatorService } from '@app/shared/shared-forms' |
11 | import { VideoChannelService } from '@app/shared/shared-main' | 11 | import { VideoChannel, VideoChannelService } from '@app/shared/shared-main' |
12 | import { VideoChannelCreate } from '@shared/models' | 12 | import { VideoChannelCreate } from '@shared/models' |
13 | import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' | 13 | import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' |
14 | import { MyVideoChannelEdit } from './my-video-channel-edit' | 14 | import { MyVideoChannelEdit } from './my-video-channel-edit' |
15 | import { switchMap } from 'rxjs/operators' | ||
16 | import { of } from 'rxjs' | ||
15 | 17 | ||
16 | @Component({ | 18 | @Component({ |
17 | templateUrl: './my-video-channel-edit.component.html', | 19 | templateUrl: './my-video-channel-edit.component.html', |
@@ -19,6 +21,10 @@ import { MyVideoChannelEdit } from './my-video-channel-edit' | |||
19 | }) | 21 | }) |
20 | export class MyVideoChannelCreateComponent extends MyVideoChannelEdit implements OnInit { | 22 | export class MyVideoChannelCreateComponent extends MyVideoChannelEdit implements OnInit { |
21 | error: string | 23 | error: string |
24 | videoChannel = new VideoChannel({}) | ||
25 | |||
26 | private avatar: FormData | ||
27 | private banner: FormData | ||
22 | 28 | ||
23 | constructor ( | 29 | constructor ( |
24 | protected formValidatorService: FormValidatorService, | 30 | protected formValidatorService: FormValidatorService, |
@@ -50,23 +56,43 @@ export class MyVideoChannelCreateComponent extends MyVideoChannelEdit implements | |||
50 | support: body.support || null | 56 | support: body.support || null |
51 | } | 57 | } |
52 | 58 | ||
53 | this.videoChannelService.createVideoChannel(videoChannelCreate).subscribe( | 59 | this.videoChannelService.createVideoChannel(videoChannelCreate) |
54 | () => { | 60 | .pipe( |
55 | this.authService.refreshUserInformation() | 61 | switchMap(() => this.uploadAvatar()), |
62 | switchMap(() => this.uploadBanner()) | ||
63 | ).subscribe( | ||
64 | () => { | ||
65 | this.authService.refreshUserInformation() | ||
66 | |||
67 | this.notifier.success($localize`Video channel ${videoChannelCreate.displayName} created.`) | ||
68 | this.router.navigate(['/my-library', 'video-channels']) | ||
69 | }, | ||
56 | 70 | ||
57 | this.notifier.success($localize`Video channel ${videoChannelCreate.displayName} created.`) | 71 | err => { |
58 | this.router.navigate([ '/my-library', 'video-channels' ]) | 72 | if (err.status === HttpStatusCode.CONFLICT_409) { |
59 | }, | 73 | this.error = $localize`This name already exists on this instance.` |
74 | return | ||
75 | } | ||
60 | 76 | ||
61 | err => { | 77 | this.error = err.message |
62 | if (err.status === HttpStatusCode.CONFLICT_409) { | ||
63 | this.error = $localize`This name already exists on this instance.` | ||
64 | return | ||
65 | } | 78 | } |
79 | ) | ||
80 | } | ||
81 | |||
82 | onAvatarChange (formData: FormData) { | ||
83 | this.avatar = formData | ||
84 | } | ||
85 | |||
86 | onAvatarDelete () { | ||
87 | this.avatar = null | ||
88 | } | ||
89 | |||
90 | onBannerChange (formData: FormData) { | ||
91 | this.banner = formData | ||
92 | } | ||
66 | 93 | ||
67 | this.error = err.message | 94 | onBannerDelete () { |
68 | } | 95 | this.banner = null |
69 | ) | ||
70 | } | 96 | } |
71 | 97 | ||
72 | isCreation () { | 98 | isCreation () { |
@@ -76,4 +102,20 @@ export class MyVideoChannelCreateComponent extends MyVideoChannelEdit implements | |||
76 | getFormButtonTitle () { | 102 | getFormButtonTitle () { |
77 | return $localize`Create` | 103 | return $localize`Create` |
78 | } | 104 | } |
105 | |||
106 | getUsername () { | ||
107 | return this.form.value.name | ||
108 | } | ||
109 | |||
110 | private uploadAvatar () { | ||
111 | if (!this.avatar) return of(undefined) | ||
112 | |||
113 | return this.videoChannelService.changeVideoChannelImage(this.getUsername(), this.avatar, 'avatar') | ||
114 | } | ||
115 | |||
116 | private uploadBanner () { | ||
117 | if (!this.banner) return of(undefined) | ||
118 | |||
119 | return this.videoChannelService.changeVideoChannelImage(this.getUsername(), this.banner, 'banner') | ||
120 | } | ||
79 | } | 121 | } |
diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.component.html b/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.component.html index 735f9e3ba..2910dffad 100644 --- a/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.component.html +++ b/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.component.html | |||
@@ -10,7 +10,7 @@ | |||
10 | <ng-container *ngIf="!isCreation()"> | 10 | <ng-container *ngIf="!isCreation()"> |
11 | <li class="breadcrumb-item active" i18n>Edit</li> | 11 | <li class="breadcrumb-item active" i18n>Edit</li> |
12 | <li class="breadcrumb-item active" aria-current="page"> | 12 | <li class="breadcrumb-item active" aria-current="page"> |
13 | <a *ngIf="videoChannelToUpdate" [routerLink]="[ '/my-library/video-channels/update', videoChannelToUpdate?.nameWithHost ]">{{ videoChannelToUpdate?.displayName }}</a> | 13 | <a *ngIf="videoChannel" [routerLink]="[ '/my-library/video-channels/update', videoChannel?.nameWithHost ]">{{ videoChannel?.displayName }}</a> |
14 | </li> | 14 | </li> |
15 | </ng-container> | 15 | </ng-container> |
16 | </ol> | 16 | </ol> |
@@ -23,10 +23,22 @@ | |||
23 | <div class="form-row"> <!-- channel grid --> | 23 | <div class="form-row"> <!-- channel grid --> |
24 | <div class="form-group col-12 col-lg-4 col-xl-3"> | 24 | <div class="form-group col-12 col-lg-4 col-xl-3"> |
25 | <div *ngIf="isCreation()" class="video-channel-title" i18n>NEW CHANNEL</div> | 25 | <div *ngIf="isCreation()" class="video-channel-title" i18n>NEW CHANNEL</div> |
26 | <div *ngIf="!isCreation() && videoChannelToUpdate" class="video-channel-title" i18n>CHANNEL</div> | 26 | <div *ngIf="!isCreation() && videoChannel" class="video-channel-title" i18n>CHANNEL</div> |
27 | </div> | 27 | </div> |
28 | 28 | ||
29 | <div class="form-group col-12 col-lg-8 col-xl-9"> | 29 | <div class="form-group col-12 col-lg-8 col-xl-9"> |
30 | <h6 i18n>Banner image of your channel</h6> | ||
31 | |||
32 | <my-actor-banner-edit | ||
33 | *ngIf="videoChannel" [previewImage]="isCreation()" | ||
34 | [actor]="videoChannel" (bannerChange)="onBannerChange($event)" (bannerDelete)="onBannerDelete()" | ||
35 | ></my-actor-banner-edit> | ||
36 | |||
37 | <my-actor-avatar-edit | ||
38 | *ngIf="videoChannel" [previewImage]="isCreation()" | ||
39 | [actor]="videoChannel" (avatarChange)="onAvatarChange($event)" (avatarDelete)="onAvatarDelete()" | ||
40 | [displayUsername]="!isCreation()" [displaySubscribers]="!isCreation()" | ||
41 | ></my-actor-avatar-edit> | ||
30 | 42 | ||
31 | <div class="form-group" *ngIf="isCreation()"> | 43 | <div class="form-group" *ngIf="isCreation()"> |
32 | <label i18n for="name">Name</label> | 44 | <label i18n for="name">Name</label> |
@@ -44,11 +56,6 @@ | |||
44 | </div> | 56 | </div> |
45 | </div> | 57 | </div> |
46 | 58 | ||
47 | <my-actor-avatar-info | ||
48 | *ngIf="!isCreation() && videoChannelToUpdate" | ||
49 | [actor]="videoChannelToUpdate" (avatarChange)="onAvatarChange($event)" (avatarDelete)="onAvatarDelete()" | ||
50 | ></my-actor-avatar-info> | ||
51 | |||
52 | <div class="form-group"> | 59 | <div class="form-group"> |
53 | <label i18n for="display-name">Display name</label> | 60 | <label i18n for="display-name">Display name</label> |
54 | <input | 61 | <input |
diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.component.scss b/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.component.scss index 8f8af655c..22de103d1 100644 --- a/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.component.scss +++ b/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.component.scss | |||
@@ -10,11 +10,16 @@ label { | |||
10 | @include settings-big-title; | 10 | @include settings-big-title; |
11 | } | 11 | } |
12 | 12 | ||
13 | my-actor-avatar-info { | 13 | my-actor-avatar-edit, |
14 | my-actor-banner-edit { | ||
14 | display: block; | 15 | display: block; |
15 | margin-bottom: 20px; | 16 | margin-bottom: 20px; |
16 | } | 17 | } |
17 | 18 | ||
19 | my-actor-banner-edit { | ||
20 | max-width: 500px; | ||
21 | } | ||
22 | |||
18 | .input-group { | 23 | .input-group { |
19 | @include peertube-input-group(fit-content); | 24 | @include peertube-input-group(fit-content); |
20 | } | 25 | } |
diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.ts b/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.ts index 3e20a27ee..33bb90f14 100644 --- a/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.ts +++ b/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.ts | |||
@@ -2,8 +2,7 @@ import { FormReactive } from '@app/shared/shared-forms' | |||
2 | import { VideoChannel } from '@app/shared/shared-main' | 2 | import { VideoChannel } from '@app/shared/shared-main' |
3 | 3 | ||
4 | export abstract class MyVideoChannelEdit extends FormReactive { | 4 | export abstract class MyVideoChannelEdit extends FormReactive { |
5 | // We need it even in the create component because it's used in the edit template | 5 | videoChannel: VideoChannel |
6 | videoChannelToUpdate: VideoChannel | ||
7 | 6 | ||
8 | abstract isCreation (): boolean | 7 | abstract isCreation (): boolean |
9 | abstract getFormButtonTitle (): string | 8 | abstract getFormButtonTitle (): string |
@@ -12,10 +11,6 @@ export abstract class MyVideoChannelEdit extends FormReactive { | |||
12 | return window.location.host | 11 | return window.location.host |
13 | } | 12 | } |
14 | 13 | ||
15 | // We need this method so angular does not complain in child template that doesn't need this | ||
16 | onAvatarChange (formData: FormData) { /* empty */ } | ||
17 | onAvatarDelete () { /* empty */ } | ||
18 | |||
19 | // Should be implemented by the child | 14 | // Should be implemented by the child |
20 | isBulkUpdateVideosDisplayed () { | 15 | isBulkUpdateVideosDisplayed () { |
21 | return false | 16 | return false |
diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channel-update.component.ts b/client/src/app/+my-library/+my-video-channels/my-video-channel-update.component.ts index 6cd1ff503..a29af176c 100644 --- a/client/src/app/+my-library/+my-video-channels/my-video-channel-update.component.ts +++ b/client/src/app/+my-library/+my-video-channels/my-video-channel-update.component.ts | |||
@@ -1,7 +1,9 @@ | |||
1 | import { Subscription } from 'rxjs' | 1 | import { Subscription } from 'rxjs' |
2 | import { HttpErrorResponse } from '@angular/common/http' | ||
2 | import { Component, OnDestroy, OnInit } from '@angular/core' | 3 | import { Component, OnDestroy, OnInit } from '@angular/core' |
3 | import { ActivatedRoute, Router } from '@angular/router' | 4 | import { ActivatedRoute, Router } from '@angular/router' |
4 | import { AuthService, Notifier, ServerService } from '@app/core' | 5 | import { AuthService, Notifier, ServerService } from '@app/core' |
6 | import { uploadErrorHandler } from '@app/helpers' | ||
5 | import { | 7 | import { |
6 | VIDEO_CHANNEL_DESCRIPTION_VALIDATOR, | 8 | VIDEO_CHANNEL_DESCRIPTION_VALIDATOR, |
7 | VIDEO_CHANNEL_DISPLAY_NAME_VALIDATOR, | 9 | VIDEO_CHANNEL_DISPLAY_NAME_VALIDATOR, |
@@ -11,8 +13,6 @@ import { FormValidatorService } from '@app/shared/shared-forms' | |||
11 | import { VideoChannel, VideoChannelService } from '@app/shared/shared-main' | 13 | import { VideoChannel, VideoChannelService } from '@app/shared/shared-main' |
12 | import { ServerConfig, VideoChannelUpdate } from '@shared/models' | 14 | import { ServerConfig, VideoChannelUpdate } from '@shared/models' |
13 | import { MyVideoChannelEdit } from './my-video-channel-edit' | 15 | import { MyVideoChannelEdit } from './my-video-channel-edit' |
14 | import { HttpErrorResponse } from '@angular/common/http' | ||
15 | import { uploadErrorHandler } from '@app/helpers' | ||
16 | 16 | ||
17 | @Component({ | 17 | @Component({ |
18 | selector: 'my-video-channel-update', | 18 | selector: 'my-video-channel-update', |
@@ -21,7 +21,7 @@ import { uploadErrorHandler } from '@app/helpers' | |||
21 | }) | 21 | }) |
22 | export class MyVideoChannelUpdateComponent extends MyVideoChannelEdit implements OnInit, OnDestroy { | 22 | export class MyVideoChannelUpdateComponent extends MyVideoChannelEdit implements OnInit, OnDestroy { |
23 | error: string | 23 | error: string |
24 | videoChannelToUpdate: VideoChannel | 24 | videoChannel: VideoChannel |
25 | 25 | ||
26 | private paramsSub: Subscription | 26 | private paramsSub: Subscription |
27 | private oldSupportField: string | 27 | private oldSupportField: string |
@@ -56,7 +56,7 @@ export class MyVideoChannelUpdateComponent extends MyVideoChannelEdit implements | |||
56 | 56 | ||
57 | this.videoChannelService.getVideoChannel(videoChannelId).subscribe( | 57 | this.videoChannelService.getVideoChannel(videoChannelId).subscribe( |
58 | videoChannelToUpdate => { | 58 | videoChannelToUpdate => { |
59 | this.videoChannelToUpdate = videoChannelToUpdate | 59 | this.videoChannel = videoChannelToUpdate |
60 | 60 | ||
61 | this.oldSupportField = videoChannelToUpdate.support | 61 | this.oldSupportField = videoChannelToUpdate.support |
62 | 62 | ||
@@ -87,7 +87,7 @@ export class MyVideoChannelUpdateComponent extends MyVideoChannelEdit implements | |||
87 | bulkVideosSupportUpdate: body.bulkVideosSupportUpdate || false | 87 | bulkVideosSupportUpdate: body.bulkVideosSupportUpdate || false |
88 | } | 88 | } |
89 | 89 | ||
90 | this.videoChannelService.updateVideoChannel(this.videoChannelToUpdate.name, videoChannelUpdate).subscribe( | 90 | this.videoChannelService.updateVideoChannel(this.videoChannel.name, videoChannelUpdate).subscribe( |
91 | () => { | 91 | () => { |
92 | this.authService.refreshUserInformation() | 92 | this.authService.refreshUserInformation() |
93 | 93 | ||
@@ -101,12 +101,12 @@ export class MyVideoChannelUpdateComponent extends MyVideoChannelEdit implements | |||
101 | } | 101 | } |
102 | 102 | ||
103 | onAvatarChange (formData: FormData) { | 103 | onAvatarChange (formData: FormData) { |
104 | this.videoChannelService.changeVideoChannelAvatar(this.videoChannelToUpdate.name, formData) | 104 | this.videoChannelService.changeVideoChannelImage(this.videoChannel.name, formData, 'avatar') |
105 | .subscribe( | 105 | .subscribe( |
106 | data => { | 106 | data => { |
107 | this.notifier.success($localize`Avatar changed.`) | 107 | this.notifier.success($localize`Avatar changed.`) |
108 | 108 | ||
109 | this.videoChannelToUpdate.updateAvatar(data.avatar) | 109 | this.videoChannel.updateAvatar(data.avatar) |
110 | }, | 110 | }, |
111 | 111 | ||
112 | (err: HttpErrorResponse) => uploadErrorHandler({ | 112 | (err: HttpErrorResponse) => uploadErrorHandler({ |
@@ -118,12 +118,42 @@ export class MyVideoChannelUpdateComponent extends MyVideoChannelEdit implements | |||
118 | } | 118 | } |
119 | 119 | ||
120 | onAvatarDelete () { | 120 | onAvatarDelete () { |
121 | this.videoChannelService.deleteVideoChannelAvatar(this.videoChannelToUpdate.name) | 121 | this.videoChannelService.deleteVideoChannelImage(this.videoChannel.name, 'avatar') |
122 | .subscribe( | 122 | .subscribe( |
123 | data => { | 123 | data => { |
124 | this.notifier.success($localize`Avatar deleted.`) | 124 | this.notifier.success($localize`Avatar deleted.`) |
125 | 125 | ||
126 | this.videoChannelToUpdate.resetAvatar() | 126 | this.videoChannel.resetAvatar() |
127 | }, | ||
128 | |||
129 | err => this.notifier.error(err.message) | ||
130 | ) | ||
131 | } | ||
132 | |||
133 | onBannerChange (formData: FormData) { | ||
134 | this.videoChannelService.changeVideoChannelImage(this.videoChannel.name, formData, 'banner') | ||
135 | .subscribe( | ||
136 | data => { | ||
137 | this.notifier.success($localize`Banner changed.`) | ||
138 | |||
139 | this.videoChannel.updateBanner(data.banner) | ||
140 | }, | ||
141 | |||
142 | (err: HttpErrorResponse) => uploadErrorHandler({ | ||
143 | err, | ||
144 | name: $localize`banner`, | ||
145 | notifier: this.notifier | ||
146 | }) | ||
147 | ) | ||
148 | } | ||
149 | |||
150 | onBannerDelete () { | ||
151 | this.videoChannelService.deleteVideoChannelImage(this.videoChannel.name, 'banner') | ||
152 | .subscribe( | ||
153 | data => { | ||
154 | this.notifier.success($localize`Banner deleted.`) | ||
155 | |||
156 | this.videoChannel.resetBanner() | ||
127 | }, | 157 | }, |
128 | 158 | ||
129 | err => this.notifier.error(err.message) | 159 | err => this.notifier.error(err.message) |
diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channels.component.scss b/client/src/app/+my-library/+my-video-channels/my-video-channels.component.scss index f2f42459f..8804fa95c 100644 --- a/client/src/app/+my-library/+my-video-channels/my-video-channels.component.scss +++ b/client/src/app/+my-library/+my-video-channels/my-video-channels.component.scss | |||
@@ -17,10 +17,11 @@ input[type=text] { | |||
17 | 17 | ||
18 | .video-channel { | 18 | .video-channel { |
19 | @include row-blocks; | 19 | @include row-blocks; |
20 | |||
20 | padding-bottom: 0; | 21 | padding-bottom: 0; |
21 | 22 | ||
22 | img { | 23 | img { |
23 | @include avatar(80px); | 24 | @include channel-avatar(80px); |
24 | 25 | ||
25 | margin-right: 10px; | 26 | margin-right: 10px; |
26 | } | 27 | } |
diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channels.module.ts b/client/src/app/+my-library/+my-video-channels/my-video-channels.module.ts index 92b56db49..53557ca02 100644 --- a/client/src/app/+my-library/+my-video-channels/my-video-channels.module.ts +++ b/client/src/app/+my-library/+my-video-channels/my-video-channels.module.ts | |||
@@ -1,5 +1,6 @@ | |||
1 | import { ChartModule } from 'primeng/chart' | 1 | import { ChartModule } from 'primeng/chart' |
2 | import { NgModule } from '@angular/core' | 2 | import { NgModule } from '@angular/core' |
3 | import { SharedActorImageModule } from '@app/shared/shared-actor-image' | ||
3 | import { SharedFormModule } from '@app/shared/shared-forms' | 4 | import { SharedFormModule } from '@app/shared/shared-forms' |
4 | import { SharedGlobalIconModule } from '@app/shared/shared-icons' | 5 | import { SharedGlobalIconModule } from '@app/shared/shared-icons' |
5 | import { SharedMainModule } from '@app/shared/shared-main' | 6 | import { SharedMainModule } from '@app/shared/shared-main' |
@@ -16,7 +17,8 @@ import { MyVideoChannelsComponent } from './my-video-channels.component' | |||
16 | 17 | ||
17 | SharedMainModule, | 18 | SharedMainModule, |
18 | SharedFormModule, | 19 | SharedFormModule, |
19 | SharedGlobalIconModule | 20 | SharedGlobalIconModule, |
21 | SharedActorImageModule | ||
20 | ], | 22 | ], |
21 | 23 | ||
22 | declarations: [ | 24 | declarations: [ |
diff --git a/client/src/app/+my-library/my-history/my-history.component.html b/client/src/app/+my-library/my-history/my-history.component.html index c180161e7..9dec64645 100644 --- a/client/src/app/+my-library/my-history/my-history.component.html +++ b/client/src/app/+my-library/my-history/my-history.component.html | |||
@@ -4,7 +4,7 @@ | |||
4 | </h1> | 4 | </h1> |
5 | 5 | ||
6 | <div class="top-buttons"> | 6 | <div class="top-buttons"> |
7 | <div> | 7 | <div class="search-wrapper"> |
8 | <div class="input-group has-feedback has-clear"> | 8 | <div class="input-group has-feedback has-clear"> |
9 | <input | 9 | <input |
10 | type="text" name="history-search" id="history-search" i18n-placeholder placeholder="Search your history" | 10 | type="text" name="history-search" id="history-search" i18n-placeholder placeholder="Search your history" |
@@ -15,7 +15,7 @@ | |||
15 | </div> | 15 | </div> |
16 | </div> | 16 | </div> |
17 | 17 | ||
18 | <div class="history-switch ml-auto mr-3"> | 18 | <div class="history-switch"> |
19 | <my-input-switch [(ngModel)]="videosHistoryEnabled" (ngModelChange)="onVideosHistoryChange()"></my-input-switch> | 19 | <my-input-switch [(ngModel)]="videosHistoryEnabled" (ngModelChange)="onVideosHistoryChange()"></my-input-switch> |
20 | <label i18n>Track watch history</label> | 20 | <label i18n>Track watch history</label> |
21 | </div> | 21 | </div> |
diff --git a/client/src/app/+my-library/my-history/my-history.component.scss b/client/src/app/+my-library/my-history/my-history.component.scss index 928a8a3da..af4a34b4b 100644 --- a/client/src/app/+my-library/my-history/my-history.component.scss +++ b/client/src/app/+my-library/my-history/my-history.component.scss | |||
@@ -11,16 +11,24 @@ | |||
11 | 11 | ||
12 | .top-buttons { | 12 | .top-buttons { |
13 | margin-bottom: 30px; | 13 | margin-bottom: 30px; |
14 | display: flex; | 14 | display: grid; |
15 | grid-template-columns: 250px 1fr auto auto; | ||
15 | align-items: center; | 16 | align-items: center; |
16 | flex-wrap: wrap; | ||
17 | 17 | ||
18 | #history-search { | 18 | .search-wrapper { |
19 | @include peertube-input-text(250px); | 19 | grid-column: 1; |
20 | |||
21 | input { | ||
22 | @include peertube-input-text(250px); | ||
23 | } | ||
20 | } | 24 | } |
21 | 25 | ||
22 | .history-switch { | 26 | .history-switch { |
27 | grid-column: 3; | ||
28 | |||
23 | display: flex; | 29 | display: flex; |
30 | margin-left: auto; | ||
31 | margin-right: 15px; | ||
24 | 32 | ||
25 | label { | 33 | label { |
26 | margin: 0 0 0 5px; | 34 | margin: 0 0 0 5px; |
@@ -31,6 +39,8 @@ | |||
31 | } | 39 | } |
32 | 40 | ||
33 | .delete-history { | 41 | .delete-history { |
42 | grid-column: 4; | ||
43 | |||
34 | @include peertube-button; | 44 | @include peertube-button; |
35 | @include grey-button; | 45 | @include grey-button; |
36 | @include button-with-icon; | 46 | @include button-with-icon; |
@@ -40,26 +50,27 @@ | |||
40 | } | 50 | } |
41 | 51 | ||
42 | .video { | 52 | .video { |
43 | @include row-blocks; | 53 | @include row-blocks($column-responsive: false); |
44 | |||
45 | .my-video-miniature { | ||
46 | flex-grow: 1; | ||
47 | } | ||
48 | } | 54 | } |
49 | 55 | ||
50 | @media screen and (max-width: $mobile-view) { | 56 | @media screen and (max-width: $small-view) { |
51 | .top-buttons { | 57 | .top-buttons { |
52 | .history-switch label, .delete-history { | 58 | grid-template-columns: auto 1fr auto; |
53 | @include ellipsis; | 59 | row-gap: 20px; |
54 | } | ||
55 | 60 | ||
56 | .history-switch label { | 61 | .history-switch { |
57 | width: 60%; | 62 | grid-row: 1; |
63 | grid-column: 1; | ||
64 | margin: 0; | ||
58 | } | 65 | } |
59 | 66 | ||
60 | .delete-history { | 67 | .delete-history { |
61 | margin-left: auto; | 68 | grid-row: 1; |
62 | max-width: 32%; | 69 | grid-column: 3; |
70 | } | ||
71 | |||
72 | .search-wrapper { | ||
73 | grid-column: 1 / 4; | ||
63 | } | 74 | } |
64 | } | 75 | } |
65 | } | 76 | } |
diff --git a/client/src/app/+my-library/my-subscriptions/my-subscriptions.component.html b/client/src/app/+my-library/my-subscriptions/my-subscriptions.component.html index 510b400c0..ff448ad87 100644 --- a/client/src/app/+my-library/my-subscriptions/my-subscriptions.component.html +++ b/client/src/app/+my-library/my-subscriptions/my-subscriptions.component.html | |||
@@ -6,7 +6,7 @@ | |||
6 | </span> | 6 | </span> |
7 | </h1> | 7 | </h1> |
8 | 8 | ||
9 | <div class="video-subscriptions-header d-flex justify-content-between"> | 9 | <div class="video-subscriptions-header"> |
10 | <div class="has-feedback has-clear"> | 10 | <div class="has-feedback has-clear"> |
11 | <input type="text" placeholder="Search your subscriptions" i18n-placeholder [(ngModel)]="subscriptionsSearch" | 11 | <input type="text" placeholder="Search your subscriptions" i18n-placeholder [(ngModel)]="subscriptionsSearch" |
12 | (ngModelChange)="onSubscriptionsSearchChanged()" /> | 12 | (ngModelChange)="onSubscriptionsSearchChanged()" /> |
diff --git a/client/src/app/+my-library/my-subscriptions/my-subscriptions.component.scss b/client/src/app/+my-library/my-subscriptions/my-subscriptions.component.scss index 5ead45dd8..3c1a4d2ad 100644 --- a/client/src/app/+my-library/my-subscriptions/my-subscriptions.component.scss +++ b/client/src/app/+my-library/my-subscriptions/my-subscriptions.component.scss | |||
@@ -9,40 +9,40 @@ input[type=text] { | |||
9 | @include row-blocks; | 9 | @include row-blocks; |
10 | 10 | ||
11 | img { | 11 | img { |
12 | @include avatar(80px); | 12 | @include channel-avatar(80px); |
13 | 13 | ||
14 | margin-right: 10px; | 14 | margin-right: 10px; |
15 | } | 15 | } |
16 | } | ||
16 | 17 | ||
17 | .video-channel-info { | 18 | .video-channel-info { |
18 | flex-grow: 1; | 19 | flex-grow: 1; |
19 | 20 | ||
20 | a.video-channel-names { | 21 | a.video-channel-names { |
21 | @include disable-default-a-behaviour; | 22 | @include disable-default-a-behaviour; |
22 | 23 | ||
23 | width: fit-content; | 24 | width: fit-content; |
24 | display: flex; | 25 | display: flex; |
25 | align-items: baseline; | 26 | align-items: baseline; |
26 | color: pvar(--mainForegroundColor); | 27 | color: pvar(--mainForegroundColor); |
27 | 28 | ||
28 | .video-channel-display-name { | 29 | .video-channel-display-name { |
29 | font-weight: $font-semibold; | 30 | font-weight: $font-semibold; |
30 | font-size: 18px; | 31 | font-size: 18px; |
31 | } | 32 | } |
32 | 33 | ||
33 | .video-channel-name { | 34 | .video-channel-name { |
34 | font-size: 14px; | 35 | font-size: 14px; |
35 | color: $grey-actor-name; | 36 | color: $grey-actor-name; |
36 | margin-left: 5px; | 37 | margin-left: 5px; |
37 | } | ||
38 | } | 38 | } |
39 | } | 39 | } |
40 | } | ||
40 | 41 | ||
41 | .actor-owner { | 42 | .actor-owner { |
42 | @include actor-owner; | 43 | @include actor-owner; |
43 | 44 | ||
44 | margin-top: 0; | 45 | margin-top: 0; |
45 | } | ||
46 | } | 46 | } |
47 | 47 | ||
48 | .video-subscriptions-header { | 48 | .video-subscriptions-header { |
@@ -50,32 +50,22 @@ input[type=text] { | |||
50 | } | 50 | } |
51 | 51 | ||
52 | @media screen and (max-width: $small-view) { | 52 | @media screen and (max-width: $small-view) { |
53 | .video-channel { | 53 | .video-subscriptions-header input[type=text] { |
54 | .video-channel-info { | 54 | width: 100% !important; |
55 | padding-bottom: 10px; | ||
56 | text-align: center; | ||
57 | |||
58 | .video-channel-names { | ||
59 | flex-direction: column; | ||
60 | align-items: center !important; | ||
61 | margin: auto; | ||
62 | } | ||
63 | } | ||
64 | |||
65 | img { | ||
66 | margin-right: 0; | ||
67 | } | ||
68 | } | 55 | } |
69 | } | ||
70 | 56 | ||
71 | @media screen and (max-width: $mobile-view) { | 57 | .video-channel-info { |
72 | .video-subscriptions-header { | 58 | padding-bottom: 10px; |
73 | flex-direction: column; | 59 | text-align: center; |
74 | 60 | ||
75 | input[type=text] { | 61 | .video-channel-names { |
76 | width: 100% !important; | 62 | flex-direction: column; |
63 | align-items: center !important; | ||
64 | margin: auto; | ||
77 | } | 65 | } |
78 | } | 66 | } |
79 | } | ||
80 | |||
81 | 67 | ||
68 | img { | ||
69 | margin-right: 0; | ||
70 | } | ||
71 | } | ||
diff --git a/client/src/app/+my-library/my-video-playlists/my-video-playlist-elements.component.html b/client/src/app/+my-library/my-video-playlists/my-video-playlist-elements.component.html index a97b2b4fb..e7e3c17b3 100644 --- a/client/src/app/+my-library/my-video-playlists/my-video-playlist-elements.component.html +++ b/client/src/app/+my-library/my-video-playlists/my-video-playlist-elements.component.html | |||
@@ -1,6 +1,6 @@ | |||
1 | <div class="row"> | 1 | <div class="root"> |
2 | 2 | ||
3 | <div class="playlist-info col-xs-12 col-md-5 col-xl-3"> | 3 | <div class="playlist-info"> |
4 | <my-video-playlist-miniature | 4 | <my-video-playlist-miniature |
5 | *ngIf="playlist" [playlist]="playlist" [toManage]="false" [displayChannel]="true" | 5 | *ngIf="playlist" [playlist]="playlist" [toManage]="false" [displayChannel]="true" |
6 | [displayDescription]="true" [displayPrivacy]="true" | 6 | [displayDescription]="true" [displayPrivacy]="true" |
@@ -20,7 +20,7 @@ | |||
20 | 20 | ||
21 | </div> | 21 | </div> |
22 | 22 | ||
23 | <div class="playlist-elements col-xs-12 col-md-7 col-xl-9"> | 23 | <div class="playlist-elements"> |
24 | <div class="no-results" *ngIf="pagination.totalItems === 0"> | 24 | <div class="no-results" *ngIf="pagination.totalItems === 0"> |
25 | <div i18n>No videos in this playlist.</div> | 25 | <div i18n>No videos in this playlist.</div> |
26 | 26 | ||
diff --git a/client/src/app/+my-library/my-video-playlists/my-video-playlist-elements.component.scss b/client/src/app/+my-library/my-video-playlists/my-video-playlist-elements.component.scss index de7e1993f..0c68dedf6 100644 --- a/client/src/app/+my-library/my-video-playlists/my-video-playlist-elements.component.scss +++ b/client/src/app/+my-library/my-video-playlists/my-video-playlist-elements.component.scss | |||
@@ -2,21 +2,25 @@ | |||
2 | @import '_mixins'; | 2 | @import '_mixins'; |
3 | @import '_miniature'; | 3 | @import '_miniature'; |
4 | 4 | ||
5 | .root { | ||
6 | display: grid; | ||
7 | grid-template-columns: auto 1fr; | ||
8 | } | ||
9 | |||
5 | .playlist-info { | 10 | .playlist-info { |
6 | background-color: pvar(--submenuColor); | 11 | grid-column: 1; |
7 | margin-left: -$not-expanded-horizontal-margins; | 12 | background-color: pvar(--submenuBackgroundColor); |
13 | margin-left: calc(#{pvar(--horizontalMarginContent)} * -1); | ||
8 | margin-top: -$sub-menu-margin-bottom; | 14 | margin-top: -$sub-menu-margin-bottom; |
9 | 15 | ||
10 | padding: 10px; | 16 | padding: 15px; |
11 | 17 | ||
12 | display: flex; | 18 | display: flex; |
13 | flex-direction: column; | 19 | flex-direction: column; |
14 | justify-content: flex-start; | ||
15 | align-items: center; | ||
16 | 20 | ||
17 | /* fix ellipsis dots background color */ | 21 | /* fix ellipsis dots background color */ |
18 | ::ng-deep .miniature-name::after { | 22 | ::ng-deep .miniature-name::after { |
19 | background-color: pvar(--submenuColor) !important; | 23 | background-color: pvar(--submenuBackgroundColor) !important; |
20 | } | 24 | } |
21 | } | 25 | } |
22 | 26 | ||
@@ -59,15 +63,35 @@ | |||
59 | transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); | 63 | transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); |
60 | } | 64 | } |
61 | 65 | ||
62 | @media screen and (max-width: $small-view) { | 66 | .playlist-elements { |
67 | grid-column: 2; | ||
68 | } | ||
69 | |||
70 | my-video-playlist-miniature { | ||
71 | width: $video-thumbnail-width; | ||
72 | } | ||
73 | |||
74 | @include on-small-main-col { | ||
75 | my-video-playlist-miniature { | ||
76 | width: $video-thumbnail-medium-width; | ||
77 | } | ||
78 | } | ||
79 | |||
80 | @include on-mobile-main-col { | ||
81 | .root { | ||
82 | display: block; | ||
83 | } | ||
84 | |||
63 | .playlist-info { | 85 | .playlist-info { |
64 | width: 100vw; | 86 | width: calc(100% + (2 * var(--horizontalMarginContent))); |
65 | padding-top: 20px; | 87 | padding-top: 20px; |
66 | margin-left: calc(#{var(--expanded-horizontal-margin-content)} * -1); | 88 | margin-bottom: 10px; |
67 | } | 89 | } |
68 | 90 | ||
69 | .playlist-elements { | 91 | my-video-playlist-miniature, |
70 | padding: 0 !important; | 92 | .playlist-buttons { |
93 | margin-left: auto; | ||
94 | margin-right: auto; | ||
71 | } | 95 | } |
72 | 96 | ||
73 | ::ng-deep my-video-playlist-element-miniature { | 97 | ::ng-deep my-video-playlist-element-miniature { |
diff --git a/client/src/app/+my-library/my-video-playlists/my-video-playlists.component.html b/client/src/app/+my-library/my-video-playlists/my-video-playlists.component.html index afcf6a084..b88ea3db7 100644 --- a/client/src/app/+my-library/my-video-playlists/my-video-playlists.component.html +++ b/client/src/app/+my-library/my-video-playlists/my-video-playlists.component.html | |||
@@ -1,8 +1,6 @@ | |||
1 | <h1> | 1 | <h1> |
2 | <span> | 2 | <my-global-icon iconName="playlists" aria-hidden="true"></my-global-icon> |
3 | <my-global-icon iconName="playlists" aria-hidden="true"></my-global-icon> | 3 | <ng-container i18n>My playlists</ng-container> <span class="badge badge-secondary">{{ pagination.totalItems }}</span> |
4 | <ng-container i18n>My playlists</ng-container> <span class="badge badge-secondary">{{ pagination.totalItems }}</span> | ||
5 | </span> | ||
6 | </h1> | 4 | </h1> |
7 | 5 | ||
8 | <div class="video-playlists-header d-flex justify-content-between"> | 6 | <div class="video-playlists-header d-flex justify-content-between"> |
@@ -21,10 +19,10 @@ | |||
21 | 19 | ||
22 | <div class="video-playlists" myInfiniteScroller [autoInit]="true" (nearOfBottom)="onNearOfBottom()" [dataObservable]="onDataSubject.asObservable()"> | 20 | <div class="video-playlists" myInfiniteScroller [autoInit]="true" (nearOfBottom)="onNearOfBottom()" [dataObservable]="onDataSubject.asObservable()"> |
23 | <div *ngFor="let playlist of videoPlaylists" class="video-playlist"> | 21 | <div *ngFor="let playlist of videoPlaylists" class="video-playlist"> |
24 | <div class="miniature-wrapper"> | 22 | <my-video-playlist-miniature |
25 | <my-video-playlist-miniature [playlist]="playlist" [toManage]="true" [displayChannel]="true" [displayDescription]="true" [displayPrivacy]="true" | 23 | [playlist]="playlist" [toManage]="true" [displayChannel]="true" |
26 | ></my-video-playlist-miniature> | 24 | [displayDescription]="true" [displayPrivacy]="true" [displayAsRow]="true" |
27 | </div> | 25 | ></my-video-playlist-miniature> |
28 | 26 | ||
29 | <div *ngIf="isRegularPlaylist(playlist)" class="video-playlist-buttons"> | 27 | <div *ngIf="isRegularPlaylist(playlist)" class="video-playlist-buttons"> |
30 | <my-delete-button label (click)="deleteVideoPlaylist(playlist)"></my-delete-button> | 28 | <my-delete-button label (click)="deleteVideoPlaylist(playlist)"></my-delete-button> |
diff --git a/client/src/app/+my-library/my-video-playlists/my-video-playlists.component.scss b/client/src/app/+my-library/my-video-playlists/my-video-playlists.component.scss index 2b7c88246..94187efd4 100644 --- a/client/src/app/+my-library/my-video-playlists/my-video-playlists.component.scss +++ b/client/src/app/+my-library/my-video-playlists/my-video-playlists.component.scss | |||
@@ -1,6 +1,10 @@ | |||
1 | @import '_variables'; | 1 | @import '_variables'; |
2 | @import '_mixins'; | 2 | @import '_mixins'; |
3 | 3 | ||
4 | h1 { | ||
5 | display: flex; | ||
6 | } | ||
7 | |||
4 | .create-button { | 8 | .create-button { |
5 | @include create-button; | 9 | @include create-button; |
6 | } | 10 | } |
@@ -9,64 +13,45 @@ input[type=text] { | |||
9 | @include peertube-input-text(300px); | 13 | @include peertube-input-text(300px); |
10 | } | 14 | } |
11 | 15 | ||
12 | ::ng-deep .action-button { | ||
13 | &.action-button-delete { | ||
14 | margin-right: 10px; | ||
15 | } | ||
16 | } | ||
17 | |||
18 | .video-playlist { | 16 | .video-playlist { |
19 | @include row-blocks; | 17 | @include row-blocks($column-responsive: false); |
20 | 18 | } | |
21 | .miniature-wrapper { | ||
22 | flex-grow: 1; | ||
23 | |||
24 | ::ng-deep .miniature { | ||
25 | display: flex; | ||
26 | |||
27 | .miniature-info { | ||
28 | margin-left: 10px; | ||
29 | width: auto; | ||
30 | } | ||
31 | } | ||
32 | } | ||
33 | 19 | ||
34 | .video-playlist-buttons { | 20 | .video-playlist-buttons { |
35 | min-width: 190px; | 21 | display: flex; |
36 | height: max-content; | 22 | margin-left: 10px; |
37 | } | 23 | align-self: flex-end; |
38 | } | 24 | } |
39 | 25 | ||
40 | .video-playlists-header { | 26 | .video-playlists-header { |
41 | margin-bottom: 30px; | 27 | margin-bottom: 30px; |
42 | } | 28 | } |
43 | 29 | ||
44 | @media screen and (max-width: $small-view) { | 30 | my-video-playlist-miniature { |
31 | display: block; | ||
32 | flex-grow: 1; | ||
33 | } | ||
34 | |||
35 | my-delete-button { | ||
36 | margin-right: 10px; | ||
37 | } | ||
38 | |||
39 | @include on-small-main-col { | ||
45 | .video-playlists-header { | 40 | .video-playlists-header { |
46 | text-align: center; | 41 | text-align: center; |
47 | } | 42 | } |
48 | 43 | ||
49 | .video-playlist { | 44 | .video-playlist { |
50 | 45 | flex-wrap: wrap; | |
51 | .video-playlist-buttons { | ||
52 | margin-top: 10px; | ||
53 | } | ||
54 | } | 46 | } |
55 | 47 | ||
56 | my-video-playlist-miniature ::ng-deep .miniature { | 48 | .video-playlist-buttons { |
57 | flex-direction: column; | 49 | margin-top: 10px; |
58 | 50 | margin-left: auto; | |
59 | .miniature-info { | ||
60 | margin-left: 0 !important; | ||
61 | } | ||
62 | |||
63 | .miniature-name { | ||
64 | max-width: $video-thumbnail-width; | ||
65 | } | ||
66 | } | 51 | } |
67 | } | 52 | } |
68 | 53 | ||
69 | @media screen and (max-width: $mobile-view) { | 54 | @include on-mobile-main-col { |
70 | .video-playlists-header { | 55 | .video-playlists-header { |
71 | flex-direction: column; | 56 | flex-direction: column; |
72 | 57 | ||
@@ -75,4 +60,8 @@ input[type=text] { | |||
75 | margin-bottom: 12px; | 60 | margin-bottom: 12px; |
76 | } | 61 | } |
77 | } | 62 | } |
63 | |||
64 | .action-button { | ||
65 | margin-left: 0; | ||
66 | } | ||
78 | } | 67 | } |
diff --git a/client/src/app/+my-library/my-videos/my-videos.component.html b/client/src/app/+my-library/my-videos/my-videos.component.html index 5fa4c02ec..e9f436378 100644 --- a/client/src/app/+my-library/my-videos/my-videos.component.html +++ b/client/src/app/+my-library/my-videos/my-videos.component.html | |||
@@ -25,6 +25,17 @@ | |||
25 | <a class="glyphicon glyphicon-remove-sign form-control-feedback form-control-clear" (click)="resetSearch()"></a> | 25 | <a class="glyphicon glyphicon-remove-sign form-control-feedback form-control-clear" (click)="resetSearch()"></a> |
26 | <span class="sr-only" i18n>Clear filters</span> | 26 | <span class="sr-only" i18n>Clear filters</span> |
27 | </div> | 27 | </div> |
28 | |||
29 | <div class="peertube-select-container peertube-select-button"> | ||
30 | <select [(ngModel)]="sort" (ngModelChange)="onChangeSortColumn()" class="form-control"> | ||
31 | <option value="undefined" disabled>Sort by</option> | ||
32 | <option value="-publishedAt" i18n>Last published first</option> | ||
33 | <option value="-createdAt" i18n>Last created first</option> | ||
34 | <option value="-views" i18n>Most viewed first</option> | ||
35 | <option value="-likes" i18n>Most liked first</option> | ||
36 | <option value="-duration" i18n>Longest first</option> | ||
37 | </select> | ||
38 | </div> | ||
28 | </div> | 39 | </div> |
29 | 40 | ||
30 | <my-videos-selection | 41 | <my-videos-selection |
@@ -34,7 +45,6 @@ | |||
34 | [miniatureDisplayOptions]="miniatureDisplayOptions" | 45 | [miniatureDisplayOptions]="miniatureDisplayOptions" |
35 | [titlePage]="titlePage" | 46 | [titlePage]="titlePage" |
36 | [getVideosObservableFunction]="getVideosObservableFunction" | 47 | [getVideosObservableFunction]="getVideosObservableFunction" |
37 | [ownerDisplayType]="ownerDisplayType" | ||
38 | [user]="user" | 48 | [user]="user" |
39 | #videosSelection | 49 | #videosSelection |
40 | > | 50 | > |
diff --git a/client/src/app/+my-library/my-videos/my-videos.component.scss b/client/src/app/+my-library/my-videos/my-videos.component.scss index 59fc5fe80..aaf21126b 100644 --- a/client/src/app/+my-library/my-videos/my-videos.component.scss +++ b/client/src/app/+my-library/my-videos/my-videos.component.scss | |||
@@ -5,6 +5,11 @@ input[type=text] { | |||
5 | @include peertube-input-text(300px); | 5 | @include peertube-input-text(300px); |
6 | } | 6 | } |
7 | 7 | ||
8 | .peertube-select-container { | ||
9 | @include peertube-select-container(auto); | ||
10 | margin-left: 0.5rem; | ||
11 | } | ||
12 | |||
8 | h1 { | 13 | h1 { |
9 | display: flex; | 14 | display: flex; |
10 | justify-content: space-between; | 15 | justify-content: space-between; |
@@ -32,36 +37,9 @@ h1 { | |||
32 | } | 37 | } |
33 | } | 38 | } |
34 | 39 | ||
35 | ::ng-deep { | ||
36 | .video { | ||
37 | flex-wrap: wrap; | ||
38 | } | ||
39 | |||
40 | .action-button span { | ||
41 | white-space: nowrap; | ||
42 | } | ||
43 | |||
44 | .video-miniature { | ||
45 | &.display-as-row { | ||
46 | // width: min-content !important; | ||
47 | width: 100% !important; | ||
48 | |||
49 | .video-bottom .video-miniature-information { | ||
50 | width: max-content !important; | ||
51 | min-width: unset !important; | ||
52 | } | ||
53 | } | ||
54 | |||
55 | .video-bottom { | ||
56 | max-width: 350px; | ||
57 | } | ||
58 | } | ||
59 | } | ||
60 | |||
61 | .action-button { | 40 | .action-button { |
62 | display: flex; | 41 | display: flex; |
63 | margin-left: 55px; | 42 | margin-left: 10px; |
64 | margin-top: 10px; | ||
65 | align-self: flex-end; | 43 | align-self: flex-end; |
66 | } | 44 | } |
67 | 45 | ||
@@ -69,7 +47,7 @@ my-edit-button { | |||
69 | margin-right: 10px; | 47 | margin-right: 10px; |
70 | } | 48 | } |
71 | 49 | ||
72 | @media screen and (max-width: $small-view) { | 50 | @include on-small-main-col { |
73 | h1 { | 51 | h1 { |
74 | flex-direction: column; | 52 | flex-direction: column; |
75 | 53 | ||
@@ -80,59 +58,25 @@ my-edit-button { | |||
80 | } | 58 | } |
81 | 59 | ||
82 | .action-button { | 60 | .action-button { |
83 | flex-direction: column; | 61 | margin-top: 10px; |
84 | align-self: center; | 62 | margin-left: auto; |
85 | align-items: center; | ||
86 | margin-left: 0px; | ||
87 | } | ||
88 | |||
89 | my-edit-button { | ||
90 | margin: 15px 0 5px 0; | ||
91 | width: 100%; | ||
92 | text-align: center; | ||
93 | |||
94 | ::ng-deep { | ||
95 | .action-button { | ||
96 | /* same width than a.video-thumbnail */ | ||
97 | width: $video-thumbnail-width; | ||
98 | } | ||
99 | } | ||
100 | } | ||
101 | |||
102 | ::ng-deep { | ||
103 | .video-miniature { | ||
104 | align-items: center; | ||
105 | |||
106 | .video-bottom, | ||
107 | .video-bottom .video-miniature-information { | ||
108 | /* same width than a.video-thumbnail */ | ||
109 | max-width: $video-thumbnail-width !important; | ||
110 | } | ||
111 | } | ||
112 | } | 63 | } |
113 | } | 64 | } |
114 | 65 | ||
115 | // Adapt my-video-miniature on small screens with menu | 66 | @include on-mobile-main-col { |
116 | @media screen and (min-width: $small-view) and (max-width: #{breakpoint(lg) + ($not-expanded-horizontal-margins / 3) * 2}) { | ||
117 | :host-context(.main-col:not(.expanded)) { | ||
118 | ::ng-deep { | ||
119 | .video-miniature { | ||
120 | flex-direction: column; | ||
121 | |||
122 | .video-miniature-name { | ||
123 | max-width: $video-thumbnail-width; | ||
124 | } | ||
125 | } | ||
126 | } | ||
127 | } | ||
128 | } | ||
129 | |||
130 | @media screen and (max-width: $mobile-view) { | ||
131 | .videos-header { | 67 | .videos-header { |
132 | flex-direction: column; | 68 | flex-direction: column; |
133 | 69 | ||
134 | input[type=text] { | 70 | input[type=text] { |
135 | width: 100% !important; | 71 | width: 100%; |
72 | margin-bottom: 12px; | ||
73 | } | ||
74 | .peertube-select-container { | ||
75 | margin-left: 0; | ||
136 | } | 76 | } |
137 | } | 77 | } |
78 | |||
79 | .action-button { | ||
80 | margin-left: 0; | ||
81 | } | ||
138 | } | 82 | } |
diff --git a/client/src/app/+my-library/my-videos/my-videos.component.ts b/client/src/app/+my-library/my-videos/my-videos.component.ts index 6a2a62608..356e158d6 100644 --- a/client/src/app/+my-library/my-videos/my-videos.component.ts +++ b/client/src/app/+my-library/my-videos/my-videos.component.ts | |||
@@ -2,12 +2,12 @@ import { concat, Observable, Subject } from 'rxjs' | |||
2 | import { debounceTime, tap, toArray } from 'rxjs/operators' | 2 | import { debounceTime, tap, toArray } from 'rxjs/operators' |
3 | import { Component, OnInit, ViewChild } from '@angular/core' | 3 | import { Component, OnInit, ViewChild } from '@angular/core' |
4 | import { ActivatedRoute, Router } from '@angular/router' | 4 | import { ActivatedRoute, Router } from '@angular/router' |
5 | import { AuthService, ComponentPagination, ConfirmService, Notifier, ScreenService, ServerService, User, UserService } from '@app/core' | 5 | import { AuthService, ComponentPagination, ConfirmService, Notifier, ScreenService, ServerService, User } from '@app/core' |
6 | import { DisableForReuseHook } from '@app/core/routing/disable-for-reuse-hook' | 6 | import { DisableForReuseHook } from '@app/core/routing/disable-for-reuse-hook' |
7 | import { immutableAssign } from '@app/helpers' | 7 | import { immutableAssign } from '@app/helpers' |
8 | import { DropdownAction, Video, VideoService } from '@app/shared/shared-main' | 8 | import { DropdownAction, Video, VideoService } from '@app/shared/shared-main' |
9 | import { LiveStreamInformationComponent } from '@app/shared/shared-video-live' | 9 | import { LiveStreamInformationComponent } from '@app/shared/shared-video-live' |
10 | import { MiniatureDisplayOptions, OwnerDisplayType, SelectionType, VideosSelectionComponent } from '@app/shared/shared-video-miniature' | 10 | import { MiniatureDisplayOptions, SelectionType, VideosSelectionComponent } from '@app/shared/shared-video-miniature' |
11 | import { VideoSortField } from '@shared/models' | 11 | import { VideoSortField } from '@shared/models' |
12 | import { VideoChangeOwnershipComponent } from './modals/video-change-ownership.component' | 12 | import { VideoChangeOwnershipComponent } from './modals/video-change-ownership.component' |
13 | 13 | ||
@@ -36,7 +36,6 @@ export class MyVideosComponent implements OnInit, DisableForReuseHook { | |||
36 | state: true, | 36 | state: true, |
37 | blacklistInfo: true | 37 | blacklistInfo: true |
38 | } | 38 | } |
39 | ownerDisplayType: OwnerDisplayType = 'videoChannel' | ||
40 | 39 | ||
41 | videoActions: DropdownAction<{ video: Video }>[] = [] | 40 | videoActions: DropdownAction<{ video: Video }>[] = [] |
42 | 41 | ||
@@ -44,6 +43,7 @@ export class MyVideosComponent implements OnInit, DisableForReuseHook { | |||
44 | videosSearch: string | 43 | videosSearch: string |
45 | videosSearchChanged = new Subject<string>() | 44 | videosSearchChanged = new Subject<string>() |
46 | getVideosObservableFunction = this.getVideosObservable.bind(this) | 45 | getVideosObservableFunction = this.getVideosObservable.bind(this) |
46 | sort: VideoSortField = '-publishedAt' | ||
47 | 47 | ||
48 | user: User | 48 | user: User |
49 | 49 | ||
@@ -81,6 +81,10 @@ export class MyVideosComponent implements OnInit, DisableForReuseHook { | |||
81 | this.videosSearchChanged.next() | 81 | this.videosSearchChanged.next() |
82 | } | 82 | } |
83 | 83 | ||
84 | onChangeSortColumn () { | ||
85 | this.videosSelection.reloadVideos() | ||
86 | } | ||
87 | |||
84 | disableForReuse () { | 88 | disableForReuse () { |
85 | this.videosSelection.disableForReuse() | 89 | this.videosSelection.disableForReuse() |
86 | } | 90 | } |
@@ -89,10 +93,10 @@ export class MyVideosComponent implements OnInit, DisableForReuseHook { | |||
89 | this.videosSelection.enabledForReuse() | 93 | this.videosSelection.enabledForReuse() |
90 | } | 94 | } |
91 | 95 | ||
92 | getVideosObservable (page: number, sort: VideoSortField) { | 96 | getVideosObservable (page: number) { |
93 | const newPagination = immutableAssign(this.pagination, { currentPage: page }) | 97 | const newPagination = immutableAssign(this.pagination, { currentPage: page }) |
94 | 98 | ||
95 | return this.videoService.getMyVideos(newPagination, sort, this.videosSearch) | 99 | return this.videoService.getMyVideos(newPagination, this.sort, this.videosSearch) |
96 | .pipe( | 100 | .pipe( |
97 | tap(res => this.pagination.totalItems = res.total) | 101 | tap(res => this.pagination.totalItems = res.total) |
98 | ) | 102 | ) |