Skip to content

Commit

Permalink
Merge pull request #2385 from shanberg/polish-notifications
Browse files Browse the repository at this point in the history
refactor, polish notifications
  • Loading branch information
shanberg committed Sep 27, 2022
2 parents 2b848ca + be7bdff commit a1757c0
Show file tree
Hide file tree
Showing 9 changed files with 227 additions and 299 deletions.
2 changes: 1 addition & 1 deletion src/cljs/athens/views/app_toolbar.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@
:presenceDetails (when (electron.utils/remote-db? @selected-db)
(r/as-element [toolbar-presence-el]))}
(when (notifications/enabled?)
{:notificationPopover (r/as-element [notifications-popover])
{:notificationPopover (r/as-element [:f> notifications-popover])
:isNotificationsPopoverOpen @notificationsPopoverOpen?})
(when (comments/enabled?)
{:isShowComments @show-comments?
Expand Down
128 changes: 83 additions & 45 deletions src/cljs/athens/views/notifications/popover.cljs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
(ns athens.views.notifications.popover
(:require
["/components/Empty/Empty" :refer [Empty EmptyTitle EmptyIcon EmptyMessage]]
["/components/Icons/Icons" :refer [BellFillIcon ArrowRightIcon]]
["/components/Inbox/Inbox" :refer [InboxItemsList]]
["/components/Icons/Icons" :refer [BellIcon ArrowRightIcon]]
["/components/Notifications/NotificationItem" :refer [NotificationItem]]
["/timeAgo.js" :refer [timeAgo]]
["@chakra-ui/react" :refer [Badge Box IconButton Flex PopoverBody PopoverTrigger Popover PopoverContent PopoverCloseButton PopoverHeader Button]]
["@chakra-ui/react" :refer [Badge Text Box Heading VStack IconButton PopoverBody PopoverTrigger Popover PopoverContent PopoverCloseButton PopoverHeader Button]]
[athens.common-db :as common-db]
[athens.db :as db]
[athens.parse-renderer :as parse-renderer]
[athens.reactive :as reactive]
[athens.router :as router]
[athens.views.notifications.actions :as actions]
Expand Down Expand Up @@ -94,6 +95,13 @@
(not (get inbox-notif "isArchived")))


(def event-verb
{"Comments" "commented on"
"Mentions" "mentioned you in"
"Assignments" "assigned you to"
"Created" "created"})


(defn get-inbox-items-for-popover
[db at-username]
(let [inbox-uid (get-inbox-uid-for-user db at-username)
Expand All @@ -118,50 +126,80 @@
[]
(let [username (rf/subscribe [:username])]
(fn []
(when (notifications/enabled?)
(let [user-page-title (str "@" @username)
notification-list (get-inbox-items-for-popover @db/dsdb user-page-title)
navigate-user-page #(router/navigate-page user-page-title)
num-notifications (count notification-list)]
[:> Popover {:closeOnBlur true :size "md"}

[:> PopoverTrigger
[:> Box {:position "relative"}
[:> IconButton {"aria-label" "Notifications"
:onDoubleClick navigate-user-page
:onClick (fn [e]
(when (.. e -shiftKey)
(rf/dispatch [:right-sidebar/open-item [:node/title user-page-title]])))
:icon (r/as-element [:> BellFillIcon])}]
(when (> num-notifications 0)
[:> Badge {:position "absolute"
:bg "gold"
:color "goldContrast"
:right "-3px"
:bottom "-1px"
:zIndex 1} num-notifications])]]


[:> PopoverContent {:maxHeight "calc(100vh - 4rem)"}
[:> PopoverCloseButton]
[:> PopoverHeader [:> Button {:onClick navigate-user-page :rightIcon (r/as-element [:> ArrowRightIcon])} "Notifications"]]
[:> Flex {:p 0
:as PopoverBody
(let [user-page-title (str "@" @username)
notification-list (get-inbox-items-for-popover @db/dsdb user-page-title)
navigate-user-page #(router/navigate-page user-page-title)
notifications-grouped-by-object (group-by #(get % "object") notification-list)
num-notifications (count notification-list)]

[:> Popover {:closeOnBlur false
:isLazy true
:size "lg"}
[:> PopoverTrigger
[:> Box {:position "relative"}
[:> IconButton {"aria-label" "Notifications"
:onDoubleClick navigate-user-page
:onClick (fn [e]
(when (.. e -shiftKey)
(rf/dispatch [:right-sidebar/open-item [:node/title user-page-title]])))
:icon (r/as-element [:> BellIcon])}]
(when (> num-notifications 0)
[:> Badge {:position "absolute"
:bg "gold"
:pointerEvents "none"
:color "goldContrast"
:right "-3px"
:bottom "-1px"
:zIndex 1} num-notifications])]]

[:> PopoverContent {:maxHeight "calc(100vh - 4rem)"}
[:> PopoverCloseButton]
[:> PopoverHeader
[:> Button {:onClick navigate-user-page :rightIcon (r/as-element [:> ArrowRightIcon])}
"Notifications"]]
[:> VStack {:as PopoverBody
:flexDirection "column"
:overflow "hidden"}
(if (seq notification-list)
[:> InboxItemsList

{:onOpenItem on-click-notification-item
:onMarkAsRead #(rf/dispatch (actions/update-state-prop % "athens/notification/is-read" "true"))
:onMarkAsUnread #(rf/dispatch (actions/update-state-prop % "athens/notification/is-read" "false"))
:onArchive (fn [e uid]
(.. e stopPropagation)
(rf/dispatch (actions/update-state-prop uid "athens/notification/is-archived" "true")))
;; :onUnarchive #(rf/dispatch (actions/update-state-prop % "athens/notification/is-read" "false"))
:notificationsList notification-list}]
:align "stretch"
:overflowY "auto"
:overscrollBehavior "contain"
:spacing 6
:p 2}

(doall
(if (seq notifications-grouped-by-object)
(for [[object notifs] notifications-grouped-by-object]

^{:key (get object "parentUid")}
[:> VStack {:align "stretch"
:key (str (:parentUid object))}
[:> Heading {:size "xs"
:fontWeight "normal"
:noOfLines 1
:color "foreground.secondary"
:lineHeight "base"
:px 2
:pt 2}
[parse-renderer/parse-and-render (or (get object "name") (get object "string")) (get object "parentUid")]]

(for [notification notifs]

^{:key (get notification "id")}
[:> NotificationItem
{:notification notification
:onOpenItem on-click-notification-item
:onMarkAsRead #(rf/dispatch (actions/update-state-prop % "athens/notification/is-read" "true"))
:onMarkAsUnread #(rf/dispatch (actions/update-state-prop % "athens/notification/is-read" "false"))
:onArchive #(rf/dispatch (actions/update-state-prop % "athens/notification/is-archived" "true"))}
[:> Text {:fontWeight "bold" :noOfLines 2 :fontSize "sm"}
(str (get-in notification ["subject" "username"]) " "
(get event-verb (get notification "type")) " ")
[parse-renderer/parse-and-render (or
(get object "name")
(get object "string"))
(:id notification)]]
[:> Text [parse-renderer/parse-and-render (get notification "body")]]])])

[:> Empty {:size "sm" :py 8}
[:> EmptyIcon]
[:> EmptyTitle "All clear"]
[:> EmptyMessage "Unread notifications will appear here."]])]]])))))
[:> EmptyMessage "Unread notifications will appear here."]]))]]]))))
17 changes: 7 additions & 10 deletions src/js/components/App/ContextMenuContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,19 +111,16 @@ const useContextMenuState = () => {
}, [menuState]);

/**
* Returns true when the menu is open for this item
* @param ref: React.MutableRefObject<HTMLElement>,
* @returns
* Returns true when the menu is open
* If a ref is passed, it will return true if the ref is open
* @param ref?: React.MutableRefObject<HTMLElement>,
* @returns boolean
*/
const getIsMenuOpen = (ref: React.MutableRefObject<HTMLElement>) => {
if (!menuState.sources.filter(Boolean).length) {
return false;
} else {
return menuState.sources?.includes(ref.current)
}
const getIsMenuOpen = (ref?: React.MutableRefObject<HTMLElement>) => {
if (!ref) return menuState?.isOpen;
return menuState?.sources?.includes(ref.current);
};


return {
addToContextMenu,
getIsMenuOpen,
Expand Down
10 changes: 9 additions & 1 deletion src/js/components/Icons/Icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -819,4 +819,12 @@ export const GraphChildIcon = createIcon({
),
})

export const EditIcon = PencilIcon
export const UnreadIcon = createIcon({
displayName: 'UnreadIcon',
viewBox: '0 0 14 14',
path: (
<path fillRule="evenodd" clipRule="evenodd" d="M10.5 6C11.8807 6 13 4.88071 13 3.5C13 2.11929 11.8807 1 10.5 1C9.11929 1 8 2.11929 8 3.5C8 4.88071 9.11929 6 10.5 6ZM12 10V6.66318C11.6891 6.81085 11.3531 6.91405 11 6.96456V10C11 10.5523 10.5523 11 10 11H4C3.44772 11 3 10.5523 3 10V4C3 3.44772 3.44772 3 4 3H7.03544C7.08595 2.64693 7.18915 2.31085 7.33682 2H4C2.89543 2 2 2.89543 2 4V10C2 11.1046 2.89543 12 4 12H10C11.1046 12 12 11.1046 12 10Z" fill="currentColor" />
),
})

export const EditIcon = PencilIcon
105 changes: 0 additions & 105 deletions src/js/components/Inbox/Inbox.tsx

This file was deleted.

27 changes: 0 additions & 27 deletions src/js/components/Inbox/InboxViewListBody.tsx

This file was deleted.

0 comments on commit a1757c0

Please sign in to comment.