improve notification popup interactivity: read all, layout, position

fixes #1730
pull/2356/head
Rigel Kent 2019-12-19 14:51:35 +01:00
parent dddc8b1fe0
commit 10475dea7d
No known key found for this signature in database
GPG Key ID: 5E53E96A494E452F
10 changed files with 78 additions and 13 deletions

View File

@ -4,9 +4,12 @@
Notification preferences Notification preferences
</a> </a>
<button (click)="markAllAsRead()" i18n> <button class="btn" [disabled]="!getUnreadNotifications()" (click)="markAllAsRead()">
<my-global-icon iconName="circle-tick"></my-global-icon> <my-global-icon *ngIf="getUnreadNotifications()" iconName="inbox-full"></my-global-icon>
Mark all as read <span i18n *ngIf="getUnreadNotifications()">Mark all as read</span>
<my-global-icon *ngIf="!getUnreadNotifications()" iconName="circle-tick"></my-global-icon>
<span i18n *ngIf="!getUnreadNotifications()">All read</span>
</button> </button>
</div> </div>

View File

@ -11,4 +11,8 @@ export class MyAccountNotificationsComponent {
markAllAsRead () { markAllAsRead () {
this.userNotification.markAllAsRead() this.userNotification.markAllAsRead()
} }
getUnreadNotifications () {
return this.userNotification.notifications.filter(n => n.read === false).length
}
} }

View File

@ -12,10 +12,17 @@
<div class="notifications-header"> <div class="notifications-header">
<div i18n>Notifications</div> <div i18n>Notifications</div>
<a <div>
i18n-title title="Update your notification preferences" class="glyphicon glyphicon-cog" <button
routerLink="/my-account/settings" fragment="notifications" *ngIf="unreadNotifications"
></a> i18n-title title="Mark all as read" class="glyphicon glyphicon-inbox mr-2"
(click)="markAllAsRead()"
></button>
<a
i18n-title title="Update your notification preferences" class="glyphicon glyphicon-cog"
routerLink="/my-account/settings" fragment="notifications"
></a>
</div>
</div> </div>
<div *ngIf="!loaded" class="loader"> <div *ngIf="!loaded" class="loader">
@ -27,6 +34,9 @@
(notificationsLoaded)="onNotificationLoaded()" (notificationsLoaded)="onNotificationLoaded()"
></my-user-notifications> ></my-user-notifications>
<a *ngIf="loaded" class="all-notifications" routerLink="/my-account/notifications" i18n>See all your notifications</a> <a *ngIf="loaded" class="all-notifications" routerLink="/my-account/notifications">
<my-global-icon class="mr-1" iconName="inbox-full"></my-global-icon>
<span i18n>See all your notifications</span>
</a>
</div> </div>
</ng-template> </ng-template>

View File

@ -4,12 +4,12 @@
::ng-deep { ::ng-deep {
.popover-notifications.popover { .popover-notifications.popover {
max-width: none; max-width: none;
left: 7px !important;
.popover-body { .popover-body {
padding: 0; padding: 0;
font-size: 14px; font-size: 14px;
font-family: $main-fonts; font-family: $main-fonts;
overflow-y: scroll;
width: 400px; width: 400px;
box-shadow: 0 6px 14px rgba(0, 0, 0, 0.30); box-shadow: 0 6px 14px rgba(0, 0, 0, 0.30);
@ -24,10 +24,17 @@
.content { .content {
max-height: 150px; max-height: 150px;
transition: max-height 0.15s ease-out; transition: max-height 0.15s ease-out;
display: flex;
height: 500px;
flex-direction: column;
&.loaded { &.loaded {
max-height: 500px; max-height: 500px;
} }
& > my-user-notifications:nth-child(2) {
overflow-y: auto;
}
} }
.notifications-header { .notifications-header {
@ -42,10 +49,19 @@
a { a {
@include disable-default-a-behaviour; @include disable-default-a-behaviour;
}
button {
@include peertube-button;
padding: 0;
background: transparent;
}
a, button {
color: rgba(20, 20, 20, 0.5); color: rgba(20, 20, 20, 0.5);
&:hover { &:hover:not(:disabled) {
color: rgba(20, 20, 20, 0.8); color: rgba(20, 20, 20, 0.8);
} }
} }
@ -58,6 +74,8 @@
font-weight: $font-semibold; font-weight: $font-semibold;
color: $fg-color; color: $fg-color;
padding: 7px 0; padding: 7px 0;
margin-top: auto;
text-decoration: none;
} }
} }
} }
@ -100,8 +118,16 @@
@media screen and (max-width: $mobile-view) { @media screen and (max-width: $mobile-view) {
::ng-deep { ::ng-deep {
.popover-notifications.popover .popover-body { .popover-notifications.popover {
width: 400px; left: unset !important;
.arrow {
left: calc(2em + 7px);
}
.popover-body {
width: 100vw;
}
} }
} }
} }

View File

@ -63,6 +63,10 @@ export class AvatarNotificationComponent implements OnInit, OnDestroy {
this.loaded = true this.loaded = true
} }
markAllAsRead () {
this.userNotificationService.markAllAsRead()
}
private async subscribeToNotifications () { private async subscribeToNotifications () {
const obs = await this.userNotificationSocket.getMyNotificationsSocket() const obs = await this.userNotificationSocket.getMyNotificationsSocket()

View File

@ -27,6 +27,7 @@ const icons = {
'validate': require('!!raw-loader?!../../../assets/images/global/validate.svg'), 'validate': require('!!raw-loader?!../../../assets/images/global/validate.svg'),
'tick': require('!!raw-loader?!../../../assets/images/global/tick.svg'), 'tick': require('!!raw-loader?!../../../assets/images/global/tick.svg'),
'repeat': require('!!raw-loader?!../../../assets/images/global/repeat.svg'), 'repeat': require('!!raw-loader?!../../../assets/images/global/repeat.svg'),
'inbox-full': require('!!raw-loader?!../../../assets/images/global/inbox-full.svg'),
'dislike': require('!!raw-loader?!../../../assets/images/video/dislike.svg'), 'dislike': require('!!raw-loader?!../../../assets/images/video/dislike.svg'),
'support': require('!!raw-loader?!../../../assets/images/video/support.svg'), 'support': require('!!raw-loader?!../../../assets/images/video/support.svg'),
'like': require('!!raw-loader?!../../../assets/images/video/like.svg'), 'like': require('!!raw-loader?!../../../assets/images/video/like.svg'),

View File

@ -395,6 +395,7 @@ $video-info-margin-left: 44px;
::ng-deep .other-videos { ::ng-deep .other-videos {
padding-left: 15px; padding-left: 15px;
min-width: $video-miniature-width;
.title-page { .title-page {
margin: 0 !important; margin: 0 !important;

View File

@ -469,7 +469,6 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
this.zone.runOutsideAngular(async () => { this.zone.runOutsideAngular(async () => {
this.player = await PeertubePlayerManager.initialize(playerMode, playerOptions, player => this.player = player) this.player = await PeertubePlayerManager.initialize(playerMode, playerOptions, player => this.player = player)
this.player.focus() this.player.focus()
this.player.bezels()
this.player.on('customError', ({ err }: { err: any }) => this.handleError(err)) this.player.on('customError', ({ err }: { err: any }) => this.handleError(err))

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Artboard-4" transform="translate(-356.000000, -1046.000000)">
<g id="Extras" transform="translate(48.000000, 1046.000000)">
<g id="inbox-full" transform="translate(308.000000, 0.000000)">
<path d="M7.41604369,14 L3,14 L2,14 L2,15 L2,20.009222 C2,21.1033032 2.89446021,22 3.99339768,22 L20.0066023,22 C21.1067838,22 22,21.1092551 22,20.009222 L22,15 L22,14 L21,14 L16.5839563,14 L15.9295922,14 L15.6676034,14.5996284 C15.0357833,16.0457106 13.6054999,17 12,17 C10.3945001,17 8.96421673,16.0457106 8.33239655,14.5996284 L8.07040776,14 L7.41604369,14 Z" id="Front" stroke="#333333" stroke-width="2" stroke-linejoin="round"></path>
<path d="M2,15.5000001 L2,13.0001355 L5.63085938,3.9134128 C5.83473011,3.40319837 6.44341249,2.98958785 7.00723108,2.98958785 L17.0497215,2.98958785 C17.6059998,2.98958785 18.223735,3.40698372 18.4260932,3.91341276 L22.0569525,13.000135 L22,15" id="Back" stroke="#333333" stroke-width="2" stroke-linejoin="round"></path>
<path d="M6,9 L18,9 L18,10 L6,10 L6,9 Z M5,11 L19,11 L19,12 L5,12 L5,11 Z M7,7 L17,7 L17,8 L7,8 L7,7 Z M8,5 L16,5 L16,6 L8,6 L8,5 Z" id="Combined-Shape" fill="#333333"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -129,6 +129,8 @@ export class PeertubePlayerManager {
self.addContextMenu(mode, player, options.common.embedUrl) self.addContextMenu(mode, player, options.common.embedUrl)
player.bezels()
return res(player) return res(player)
}) })
}) })