Repository: osmlab/maproulette3
Pull request #1424 (2020-10-21 14:26:16)

Show count of unread messages in top navbar
- Show the actual count of unread messages in top navbar instead of
simply an indicator that the user has unread messages


Patch:
diff --git a/src/components/HOCs/WithCurrentUser/WithCurrentUser.js b/src/components/HOCs/WithCurrentUser/WithCurrentUser.js
index 03037acb..3a11e063 100644
--- a/src/components/HOCs/WithCurrentUser/WithCurrentUser.js
+++ b/src/components/HOCs/WithCurrentUser/WithCurrentUser.js
@@ -46,6 +46,7 @@ export const mapStateToProps = state => {
       props.user.isLoggedIn = endUser.isLoggedIn()
       props.user.isSuperUser = endUser.isSuperUser()
       props.user.hasUnreadNotifications = endUser.hasUnreadNotifications()
+      props.user.unreadNotificationCount = endUser.unreadNotificationCount()
     }
   }
 
diff --git a/src/components/Navbar/Navbar.js b/src/components/Navbar/Navbar.js
index bcbfe5d7..3b52a589 100644
--- a/src/components/Navbar/Navbar.js
+++ b/src/components/Navbar/Navbar.js
@@ -186,11 +186,19 @@ const UnreadNotificationsIndicator = function(props) {
   }
 
   return (
-    <span
-      className={classNames("mr-rounded-full mr-bg-red-light mr-text-white", {
-                            "mr-absolute mr-top-0 mr-left-50 mr-translate-x-1/2 mr-w-3 mr-h-3": !props.inline,
-                            "mr-inline-block mr-ml-2 mr-w-2 mr-h-2": props.inline})}
-    />
+    <div
+      className={classNames(
+        "mr-rounded-full mr-bg-red-light mr-flex mr-justify-center mr-items-center",
+        {
+          "mr-absolute mr-top-0 mr-left-45/100 mr-translate-x-1/2 mr-w-5 mr-h-5": !props.inline,
+          "mr-inline-block mr-ml-2 mr-w-5 mr-h-5": props.inline,
+        }
+      )}
+    >
+      <div className="mr-text-white mr-text-xxs">
+        {props.user.unreadNotificationCount}
+      </div>
+    </div>
   )
 }
 
@@ -199,8 +207,10 @@ const ProfileMenu = function(props) {
     <ol className="mr-list-dropdown">
       <li>
         <NavLink to="/inbox" onClick={props.closeDropdown}>
-          <FormattedMessage {...messages.inbox} />
-          <UnreadNotificationsIndicator {...props} inline />
+          <div className="mr-flex">
+            <FormattedMessage {...messages.inbox} />
+            <UnreadNotificationsIndicator {...props} inline />
+          </div>
         </NavLink>
       </li>
       <li>
diff --git a/src/interactions/User/AsEndUser.js b/src/interactions/User/AsEndUser.js
index 5e363fef..7379e309 100644
--- a/src/interactions/User/AsEndUser.js
+++ b/src/interactions/User/AsEndUser.js
@@ -1,6 +1,7 @@
 import { GUEST_USER_ID } from '../../services/User/User'
 import { ROLE_SUPERUSER } from '../../services/Grant/Role'
 import _find from 'lodash/find'
+import _filter from 'lodash/filter'
 import _isObject from 'lodash/isObject'
 import _isNumber from 'lodash/isNumber'
 
@@ -72,6 +73,17 @@ export class AsEndUser {
     return this.isLoggedIn() &&
            !!_find(this.user.notifications, {isRead: false})
   }
+
+  /**
+   * Returns the number of notifications not marked as read
+   */
+  unreadNotificationCount() {
+    if (!this.isLoggedIn()) {
+      return 0
+    }
+
+    return _filter(this.user.notifications, {isRead: false}).length
+  }
 }
 
 /**
diff --git a/src/tailwind.config.js b/src/tailwind.config.js
index 21cddc48..c1e901dc 100644
--- a/src/tailwind.config.js
+++ b/src/tailwind.config.js
@@ -514,6 +514,7 @@ module.exports = {
 
     inset: {
       '0': 0,
+      '45/100': '45%',
       '1/2': '50%',
       'screen20': '-20vw',
       'auto': 'auto',


Test patch:
diff --git a/src/components/HOCs/WithCurrentUser/WithCurrentUser.test.js b/src/components/HOCs/WithCurrentUser/WithCurrentUser.test.js
index a819a9c3..0580d5c7 100644
--- a/src/components/HOCs/WithCurrentUser/WithCurrentUser.test.js
+++ b/src/components/HOCs/WithCurrentUser/WithCurrentUser.test.js
@@ -20,10 +20,12 @@ userDenormalizationSchema.mockImplementation(() => schema)
 const isLoggedIn = jest.fn()
 const isSuperUser = jest.fn()
 const hasUnreadNotifications = jest.fn()
+const unreadNotificationCount = jest.fn()
 AsEndUser.mockImplementation(() => ({
   isLoggedIn,
   isSuperUser,
   hasUnreadNotifications,
+  unreadNotificationCount,
 }))
 
 
diff --git a/src/components/HOCs/WithCurrentUser/__snapshots__/WithCurrentUser.test.js.snap b/src/components/HOCs/WithCurrentUser/__snapshots__/WithCurrentUser.test.js.snap
index 9c8deeb8..c5a93c88 100644
--- a/src/components/HOCs/WithCurrentUser/__snapshots__/WithCurrentUser.test.js.snap
+++ b/src/components/HOCs/WithCurrentUser/__snapshots__/WithCurrentUser.test.js.snap
@@ -11,6 +11,7 @@ Object {
       "id": 456,
       "isLoggedIn": true,
       "isSuperUser": true,
+      "unreadNotificationCount": undefined,
     },
   },
   "user": Object {
@@ -18,6 +19,7 @@ Object {
     "id": 456,
     "isLoggedIn": true,
     "isSuperUser": true,
+    "unreadNotificationCount": undefined,
   },
 }
 `;
@@ -33,6 +35,7 @@ Object {
       "id": 456,
       "isLoggedIn": undefined,
       "isSuperUser": undefined,
+      "unreadNotificationCount": undefined,
     },
   },
   "user": Object {
@@ -40,6 +43,7 @@ Object {
     "id": 456,
     "isLoggedIn": undefined,
     "isSuperUser": undefined,
+    "unreadNotificationCount": undefined,
   },
 }
 `;