diff --git a/app/services/sqlstore/postgres/notification.go b/app/services/sqlstore/postgres/notification.go index 5832e9edc..473a9fce2 100644 --- a/app/services/sqlstore/postgres/notification.go +++ b/app/services/sqlstore/postgres/notification.go @@ -115,7 +115,7 @@ func getActiveNotifications(ctx context.Context, q *query.GetActiveNotifications // Iterate over notifications and build avatar URL for i := range q.Result { - q.Result[i].AvatarURL = buildAvatarURL(ctx, q.Result[i].AvatarType, int(q.Result[i].ID), q.Result[i].AuthorName, q.Result[i].AvatarBlobKey) + q.Result[i].AvatarURL = buildAvatarURL(ctx, q.Result[i].AvatarType, int(q.Result[i].AuthorID), q.Result[i].AuthorName, q.Result[i].AvatarBlobKey) } return nil diff --git a/public/assets/styles/utility/display.scss b/public/assets/styles/utility/display.scss index 23f3cd134..38ea83e9e 100644 --- a/public/assets/styles/utility/display.scss +++ b/public/assets/styles/utility/display.scss @@ -149,7 +149,7 @@ border: 0 solid get("colors.gray.100"); border-top-width: 1px; } - .flex-y.flex--divide-#{$i} > *:last-child { + .flex-y.flex--divide-#{$i}:not(.no-lastchild-paddingzero) > *:last-child { padding-bottom: 0; } } @@ -203,3 +203,11 @@ cursor: pointer; pointer-events: inherit; } + + +.hover { + &:hover { + background-color: get("colors.gray.100") + } +} + diff --git a/public/components/NotificationIndicator.scss b/public/components/NotificationIndicator.scss index d36e2da63..12eecac8e 100644 --- a/public/components/NotificationIndicator.scss +++ b/public/components/NotificationIndicator.scss @@ -13,3 +13,8 @@ border-radius: 100%; } } + +.c-notifications-container { + max-height: 80vh; + overflow-y: auto; +} diff --git a/public/components/NotificationIndicator.tsx b/public/components/NotificationIndicator.tsx index 63d1d0a88..f971d88b6 100644 --- a/public/components/NotificationIndicator.tsx +++ b/public/components/NotificationIndicator.tsx @@ -10,8 +10,13 @@ import { Notification } from "@fider/models" import { HStack, VStack } from "./layout" export const NotificationItem = ({ notification }: { notification: Notification }) => { + const openNotification = () => { + console.log(notification.link) + window.location.href = `/notifications/${notification.id}` + } + return ( - +
@@ -38,7 +43,8 @@ export const NotificationIndicator = () => { const fider = useFider() const [unreadNotifications, setUnreadNotifications] = useState(0) const [showingNotifications, setShowingNotifications] = useState(false) - const [notifications, setNotifications] = useState() + const [recent, setRecent] = useState() + const [unread, setUnread] = useState() useEffect(() => { if (fider.session.isAuthenticated) { @@ -54,7 +60,16 @@ export const NotificationIndicator = () => { if (showingNotifications) { actions.getAllNotifications().then((result) => { if (result) { - setNotifications(result.data) + const [unread, recent] = (result.data || []).reduce( + (result, item) => { + result[item.read ? 1 : 0].push(item) + return result + }, + [[] as Notification[], [] as Notification[]] + ) + setRecent(recent) + setUnread(unread) + setUnreadNotifications(unread.length) } }) } @@ -64,19 +79,35 @@ export const NotificationIndicator = () => { setShowingNotifications(!showingNotifications)} + fullsceenSm={true} + onToggled={(isOpen: boolean) => setShowingNotifications(isOpen)} renderHandle={} > -
- {showingNotifications && notifications !== undefined && notifications?.length > 0 && ( +
+ {showingNotifications && (unread !== undefined || recent !== undefined) && ( <> -

No new notifications

-

Previous notifications

- - {notifications.map((n) => ( - - ))} - + {unread !== undefined && unread?.length > 0 ? ( + <> +

Unread notifications

+ + {unread.map((n) => ( + + ))} + + + ) : ( +

No new notifications

+ )} + {recent !== undefined && recent?.length > 0 && ( + <> +

Previous notifications

+ + {recent.map((n) => ( + + ))} + + + )} )}
diff --git a/public/components/common/Dropdown.scss b/public/components/common/Dropdown.scss index 005b84568..38d94f00e 100644 --- a/public/components/common/Dropdown.scss +++ b/public/components/common/Dropdown.scss @@ -31,7 +31,15 @@ } &--wide { - max-width: sizing(120); + max-width: sizing(180); + } + + &--fullscreen-small { + @include media("sm") { + position: fixed; + left: 0; + width: 100vw; + } } } diff --git a/public/components/common/Dropdown.tsx b/public/components/common/Dropdown.tsx index 61e36c197..3493307b9 100644 --- a/public/components/common/Dropdown.tsx +++ b/public/components/common/Dropdown.tsx @@ -45,6 +45,7 @@ interface DropdownProps { onToggled?: (isOpen: boolean) => void children: React.ReactNode wide?: boolean + fullsceenSm?: boolean } interface DropdownContextFuncs { @@ -62,6 +63,7 @@ export const Dropdown = (props: DropdownProps) => { const changeToggleState = (newState: boolean) => { setIsOpen(newState) if (props.onToggled) { + console.log("onToggled", newState) props.onToggled(newState) } } @@ -93,6 +95,7 @@ export const Dropdown = (props: DropdownProps) => { const listClassName = classSet({ "c-dropdown__list--wide": props.wide, "c-dropdown__list shadow-lg": true, + "c-dropdown__list--fullscreen-small": props.fullsceenSm, [`c-dropdown__list--${position}`]: position === "left", })