diff --git a/src/components/flow/FlowRecentItem/index.tsx b/src/components/flow/FlowRecentItem/index.tsx index 9c01f980..02e18c8d 100644 --- a/src/components/flow/FlowRecentItem/index.tsx +++ b/src/components/flow/FlowRecentItem/index.tsx @@ -1,10 +1,9 @@ -import React, { FC, MouseEventHandler } from 'react'; +import { FC, MouseEventHandler } from 'react'; import classNames from 'classnames'; import { Anchor } from '~/components/common/Anchor'; -import { Icon } from '~/components/input/Icon'; -import { NodeRelatedItem } from '~/components/node/NodeRelatedItem'; +import { NodeThumbnail } from '~/components/node/NodeThumbnail'; import { URLS } from '~/constants/urls'; import { INode } from '~/types'; import { getPrettyDate } from '~/utils/dom'; @@ -31,7 +30,7 @@ const FlowRecentItem: FC = ({ node, has_new, onClick }) => { [styles.lab]: !node.is_promoted, })} > - +
diff --git a/src/components/node/NodeRelated/index.tsx b/src/components/node/NodeRelated/index.tsx index ea300ff6..b5b7ede1 100644 --- a/src/components/node/NodeRelated/index.tsx +++ b/src/components/node/NodeRelated/index.tsx @@ -3,7 +3,7 @@ import React, { FC, ReactElement } from 'react'; import { Hoverable } from '~/components/common/Hoverable'; import { SubTitle } from '~/components/common/SubTitle'; import { Group } from '~/components/containers/Group'; -import { NodeRelatedItem } from '~/components/node/NodeRelatedItem'; +import { NodeThumbnail } from '~/components/node/NodeThumbnail'; import { INode } from '~/types'; import styles from './styles.module.scss'; @@ -21,7 +21,7 @@ const NodeRelated: FC = ({ title, items }) => {
{items.map((item) => ( - + ))}
diff --git a/src/components/node/NodeRelated/placeholder.tsx b/src/components/node/NodeRelated/placeholder.tsx index e1749b2e..b63433a8 100644 --- a/src/components/node/NodeRelated/placeholder.tsx +++ b/src/components/node/NodeRelated/placeholder.tsx @@ -3,7 +3,7 @@ import React, { FC, memo } from 'react'; import classNames from 'classnames'; import { Group } from '~/components/containers/Group'; -import cell_style from '~/components/node/NodeRelatedItem/styles.module.scss'; +import cell_style from '~/components/node/NodeThumbnail/styles.module.scss'; import { Placeholder } from '~/components/placeholders/Placeholder'; import { range } from '~/utils/ramda'; diff --git a/src/components/node/NodeRelatedItem/index.tsx b/src/components/node/NodeThumbnail/index.tsx similarity index 92% rename from src/components/node/NodeRelatedItem/index.tsx rename to src/components/node/NodeThumbnail/index.tsx index d33693b8..1dd757a3 100644 --- a/src/components/node/NodeRelatedItem/index.tsx +++ b/src/components/node/NodeThumbnail/index.tsx @@ -8,13 +8,17 @@ import { Icon } from '~/components/input/Icon'; import { imagePresets } from '~/constants/urls'; import { useColorGradientFromString } from '~/hooks/color/useColorGradientFromString'; import { useGotoNode } from '~/hooks/node/useGotoNode'; -import { INode } from '~/types'; import { getURL, getURLFromString } from '~/utils/dom'; import styles from './styles.module.scss'; -type IProps = { - item: Partial; +type NodeThumbnailProps = { + item: { + thumbnail?: string; + title?: string; + is_promoted?: boolean; + id?: number; + }; }; type CellSize = 'small' | 'medium' | 'large'; @@ -33,7 +37,7 @@ const getTitleLetters = (title?: string): string => { : words[0].substr(0, 2).toUpperCase(); }; -const NodeRelatedItem: FC = memo(({ item }) => { +const NodeThumbnail: FC = memo(({ item }) => { const onClick = useGotoNode(item.id); const [is_loaded, setIsLoaded] = useState(false); const [width, setWidth] = useState(0); @@ -118,4 +122,4 @@ const NodeRelatedItem: FC = memo(({ item }) => { ); }); -export { NodeRelatedItem }; +export { NodeThumbnail }; diff --git a/src/components/node/NodeRelatedItem/styles.module.scss b/src/components/node/NodeThumbnail/styles.module.scss similarity index 100% rename from src/components/node/NodeRelatedItem/styles.module.scss rename to src/components/node/NodeThumbnail/styles.module.scss diff --git a/src/components/notifications/NotificationComment/index.tsx b/src/components/notifications/NotificationComment/index.tsx index 2f7c1b42..0310cc85 100644 --- a/src/components/notifications/NotificationComment/index.tsx +++ b/src/components/notifications/NotificationComment/index.tsx @@ -1,6 +1,7 @@ import { FC } from 'react'; import { Anchor } from '~/components/common/Anchor'; +import { Avatar } from '~/components/common/Avatar'; import { InlineUsername } from '~/components/common/InlineUsername'; import { Square } from '~/components/common/Square'; import { NotificationItem } from '~/types/notifications'; @@ -16,8 +17,10 @@ const NotificationComment: FC = ({ item }) => (
-
@@ -25,9 +28,17 @@ const NotificationComment: FC = ({ item }) => (
- {item.user.username}: + {item.user.username} + - + +
{item.title}
+
* { + padding-right: 5px; + } +} + +.item_title { + flex: 1; + padding-left: 5px; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; +} + +.item_image { + flex: 0 0 16px; + border-radius: 2px; } .time { @@ -47,6 +67,6 @@ color: $gray_75; } -.circle { +div.circle { border-radius: 4px 0 0 4px; } diff --git a/src/components/notifications/NotificationNode/index.tsx b/src/components/notifications/NotificationNode/index.tsx new file mode 100644 index 00000000..ce7deb0d --- /dev/null +++ b/src/components/notifications/NotificationNode/index.tsx @@ -0,0 +1,39 @@ +import { FC, useMemo } from 'react'; + +import { NodeThumbnail } from '~/components/node/NodeThumbnail'; +import { NotificationItem } from '~/types/notifications'; +import { getPrettyDate } from '~/utils/dom'; + +import styles from './styles.module.scss'; + +interface NotificationNodeProps { + item: NotificationItem; +} + +const NotificationNode: FC = ({ item }) => { + const thumbnail = useMemo( + () => ({ + title: item.title, + thumbnail: item.thumbnail, + is_promoted: true, + }), + [item], + ); + + return ( +
+
+ +
+ +
+
{item.title || '...'}
+
+ ~{item.user.username}, {getPrettyDate(item.created_at)} +
+
+
+ ); +}; + +export { NotificationNode }; diff --git a/src/components/notifications/NotificationNode/styles.module.scss b/src/components/notifications/NotificationNode/styles.module.scss new file mode 100644 index 00000000..89672976 --- /dev/null +++ b/src/components/notifications/NotificationNode/styles.module.scss @@ -0,0 +1,36 @@ +@import 'src/styles/variables'; + +.card { + background-color: $content_bg; + display: flex; + flex-direction: row; + border-radius: $radius; + justify-content: center; + align-items: center; + padding: $gap/2; +} + +.text { + flex: 1; + min-width: 0; + padding-left: $gap; + margin-top: -0.2em; +} + +.title { + font-size: 1.2em; + font-weight: bold; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + text-transform: capitalize; +} + +.user { + font-size: 0.7em; + color: $gray_50; +} + +.image { + flex: 0 0 48px; +} diff --git a/src/containers/notifications/NotificationList/index.tsx b/src/containers/notifications/NotificationList/index.tsx index 60f1ec4d..5c859f67 100644 --- a/src/containers/notifications/NotificationList/index.tsx +++ b/src/containers/notifications/NotificationList/index.tsx @@ -1,4 +1,4 @@ -import { FC, useEffect } from 'react'; +import { FC, useCallback, useEffect } from 'react'; import classNames from 'classnames'; @@ -6,7 +6,9 @@ import { Button } from '~/components/input/Button'; import { InputRow } from '~/components/input/InputRow'; import { LoaderScreen } from '~/components/input/LoaderScreen'; import { NotificationComment } from '~/components/notifications/NotificationComment'; +import { NotificationNode } from '~/components/notifications/NotificationNode'; import { useNotificationsList } from '~/hooks/notifications/useNotificationsList'; +import { NotificationItem, NotificationType } from '~/types/notifications'; import { useNotifications } from '~/utils/providers/NotificationProvider'; import styles from './styles.module.scss'; @@ -22,6 +24,17 @@ const NotificationList: FC = () => { return () => markAsRead(); }, []); + const renderItem = useCallback((item: NotificationItem) => { + switch (item.type) { + case NotificationType.Comment: + return ; + case NotificationType.Node: + return ; + default: + return null; + } + }, []); + if (isLoading) { return ; } @@ -46,7 +59,7 @@ const NotificationList: FC = () => {
{items?.map((item) => (
- + {renderItem(item)}
))}
diff --git a/src/containers/notifications/NotificationList/styles.module.scss b/src/containers/notifications/NotificationList/styles.module.scss index f2f9fbc1..3c391f7b 100644 --- a/src/containers/notifications/NotificationList/styles.module.scss +++ b/src/containers/notifications/NotificationList/styles.module.scss @@ -47,8 +47,9 @@ .item { @include row_shadow; - padding-right: $gap; + padding: $gap / 2 $gap $gap / 2 $gap / 2; transition: background-color 0.25s; + min-width: 0; &:hover { background-color: $content_bg_lighter; diff --git a/src/hooks/node/useGotoNode.ts b/src/hooks/node/useGotoNode.ts index 8a22289c..156ea1a6 100644 --- a/src/hooks/node/useGotoNode.ts +++ b/src/hooks/node/useGotoNode.ts @@ -2,10 +2,15 @@ import { useCallback } from 'react'; import { URLS } from '~/constants/urls'; import { useNavigation } from '~/hooks/navigation/useNavigation'; -import { INode } from '~/types'; // useGotoNode returns fn, that navigates to node -export const useGotoNode = (id: INode['id']) => { +export const useGotoNode = (id?: number) => { const { push } = useNavigation(); - return useCallback(() => push(URLS.NODE_URL(id)), [push, id]); + return useCallback(() => { + if (!id) { + return; + } + + push(URLS.NODE_URL(id)); + }, [push, id]); }; diff --git a/src/types/notifications/index.ts b/src/types/notifications/index.ts index 29f038b9..a610089a 100644 --- a/src/types/notifications/index.ts +++ b/src/types/notifications/index.ts @@ -4,6 +4,7 @@ export interface NotificationItem { id: number; url: string; type: NotificationType; + title: string; text: string; user: ShallowUser; thumbnail: string;