improve notification popup interactivity: read all, layout, position
authorRigel Kent <sendmemail@rigelk.eu>
Thu, 19 Dec 2019 13:51:35 +0000 (14:51 +0100)
committerRigel Kent <sendmemail@rigelk.eu>
Thu, 19 Dec 2019 13:53:01 +0000 (14:53 +0100)
fixes #1730

client/src/app/+my-account/my-account-notifications/my-account-notifications.component.html
client/src/app/+my-account/my-account-notifications/my-account-notifications.component.ts
client/src/app/menu/avatar-notification.component.html
client/src/app/menu/avatar-notification.component.scss
client/src/app/menu/avatar-notification.component.ts
client/src/app/shared/images/global-icon.component.ts
client/src/app/videos/+video-watch/video-watch.component.scss
client/src/app/videos/+video-watch/video-watch.component.ts
client/src/assets/images/global/inbox-full.svg [new file with mode: 0644]
client/src/assets/player/peertube-player-manager.ts

index d518b22ecf2b57f44b61671b432045bb4ce74552..daf721f033fccb32d658025dc15382725079c06a 100644 (file)
@@ -4,9 +4,12 @@
     Notification preferences
   </a>
 
-  <button (click)="markAllAsRead()" i18n>
-    <my-global-icon iconName="circle-tick"></my-global-icon>
-    Mark all as read
+  <button class="btn" [disabled]="!getUnreadNotifications()" (click)="markAllAsRead()">
+    <my-global-icon *ngIf="getUnreadNotifications()" iconName="inbox-full"></my-global-icon>
+    <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>
 </div>
 
index 9eca13d0f220fba69bc951b1009170e63dbb0d05..156e7713d48e7a87ee1ba64f00ae6b14c91a0502 100644 (file)
@@ -11,4 +11,8 @@ export class MyAccountNotificationsComponent {
   markAllAsRead () {
     this.userNotification.markAllAsRead()
   }
+
+  getUnreadNotifications () {
+    return this.userNotification.notifications.filter(n => n.read === false).length
+  }
 }
index a5ef43d42ab2ab817383ece6d0f1bf61f5d3b6bc..1b6e6dcf8b3533473783046a2f2d2277df8b184a 100644 (file)
     <div class="notifications-header">
       <div i18n>Notifications</div>
 
-      <a
-        i18n-title title="Update your notification preferences" class="glyphicon glyphicon-cog"
-        routerLink="/my-account/settings" fragment="notifications"
-      ></a>
+      <div>
+        <button
+          *ngIf="unreadNotifications"
+          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 *ngIf="!loaded" class="loader">
@@ -27,6 +34,9 @@
       (notificationsLoaded)="onNotificationLoaded()"
     ></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>
 </ng-template>
index d0f01fc3277d0c752238332302e7bc79035bb640..713ac7cb910b6fcf3be99cce0cfcb59ae6848f29 100644 (file)
@@ -4,12 +4,12 @@
 ::ng-deep {
   .popover-notifications.popover {
     max-width: none;
+    left: 7px !important;
 
     .popover-body {
       padding: 0;
       font-size: 14px;
       font-family: $main-fonts;
-      overflow-y: scroll;
       width: 400px;
       box-shadow: 0 6px 14px rgba(0, 0, 0, 0.30);
 
       .content {
         max-height: 150px;
         transition: max-height 0.15s ease-out;
+        display: flex;
+        height: 500px;
+        flex-direction: column;
 
         &.loaded {
           max-height: 500px;
         }
+
+        & > my-user-notifications:nth-child(2) {
+          overflow-y: auto;
+        }
       }
 
       .notifications-header {
 
         a {
           @include disable-default-a-behaviour;
+        }
+        
+        button {
+          @include peertube-button;
+        
+          padding: 0;
+          background: transparent;
+        }
 
+        a, button {
           color: rgba(20, 20, 20, 0.5);
 
-          &:hover {
+          &:hover:not(:disabled) {
             color: rgba(20, 20, 20, 0.8);
           }
         }
@@ -58,6 +74,8 @@
         font-weight: $font-semibold;
         color: $fg-color;
         padding: 7px 0;
+        margin-top: auto;
+        text-decoration: none;
       }
     }
   }
 
 @media screen and (max-width: $mobile-view) {
   ::ng-deep {
-    .popover-notifications.popover .popover-body {
-      width: 400px;
+    .popover-notifications.popover {
+      left: unset !important;
+
+      .arrow {
+        left: calc(2em + 7px);
+      }
+
+      .popover-body {
+        width: 100vw;
+      }
     }
   }
 }
index 38dbb935b5568a09d088e54138e37d637f1d5c86..680129a48a5b10a1df4e23ad661dbf8493a82213 100644 (file)
@@ -63,6 +63,10 @@ export class AvatarNotificationComponent implements OnInit, OnDestroy {
     this.loaded = true
   }
 
+  markAllAsRead () {
+    this.userNotificationService.markAllAsRead()
+  }
+
   private async subscribeToNotifications () {
     const obs = await this.userNotificationSocket.getMyNotificationsSocket()
 
index 31cfe26664249be81256dbaef8968cb99ea7cba8..8a49659265076cbaf6064ec4b99bdb8e2f2b998e 100644 (file)
@@ -27,6 +27,7 @@ const icons = {
   'validate': require('!!raw-loader?!../../../assets/images/global/validate.svg'),
   'tick': require('!!raw-loader?!../../../assets/images/global/tick.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'),
   'support': require('!!raw-loader?!../../../assets/images/video/support.svg'),
   'like': require('!!raw-loader?!../../../assets/images/video/like.svg'),
index 1b5d355f8d536d8bb022d208cd3a4ae5b1082281..180b7c6ad2488f3129c546820fb9c5450659fe06 100644 (file)
@@ -395,6 +395,7 @@ $video-info-margin-left: 44px;
 
   ::ng-deep .other-videos {
     padding-left: 15px;
+    min-width: $video-miniature-width;
 
     .title-page {
       margin: 0 !important;
index dbd75b35a57335faa6ec3f9ea6326821357f657e..134af751d4e652493dc0fc619f6bfd7b9f2e8e6a 100644 (file)
@@ -469,7 +469,6 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
     this.zone.runOutsideAngular(async () => {
       this.player = await PeertubePlayerManager.initialize(playerMode, playerOptions, player => this.player = player)
       this.player.focus()
-      this.player.bezels()
 
       this.player.on('customError', ({ err }: { err: any }) => this.handleError(err))
 
diff --git a/client/src/assets/images/global/inbox-full.svg b/client/src/assets/images/global/inbox-full.svg
new file mode 100644 (file)
index 0000000..949f761
--- /dev/null
@@ -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>
\ No newline at end of file
index 27aa360e66e8aa30cdbefadf085270dadf3a5cfb..276f9ec5915a1a878b5a6d9cee4f475eea3cc6d8 100644 (file)
@@ -129,6 +129,8 @@ export class PeertubePlayerManager {
 
         self.addContextMenu(mode, player, options.common.embedUrl)
 
+        player.bezels()
+
         return res(player)
       })
     })