From 19222a66fe6a98160bf0c28be265a3411e15d160 Mon Sep 17 00:00:00 2001 From: "Tom (plebeius.eth)" Date: Sat, 8 Jun 2024 13:39:35 +0200 Subject: [PATCH] feat(post): add "time ago" tooltip to dates --- .../post/post-desktop/post-desktop.tsx | 4 +- .../post/post-mobile/post-mobile.tsx | 4 +- src/components/post/timestamp/index.ts | 1 + src/components/post/timestamp/timestamp.tsx | 45 +++++++++++++++++++ src/index.css | 28 ++++++++++++ src/views/home/boards-box/boards-box.tsx | 2 +- src/views/home/home.module.css | 4 -- src/views/home/home.tsx | 2 +- .../popular-threads-box.tsx | 2 +- 9 files changed, 81 insertions(+), 11 deletions(-) create mode 100644 src/components/post/timestamp/index.ts create mode 100644 src/components/post/timestamp/timestamp.tsx diff --git a/src/components/post/post-desktop/post-desktop.tsx b/src/components/post/post-desktop/post-desktop.tsx index 4bc805bd..eab6903c 100644 --- a/src/components/post/post-desktop/post-desktop.tsx +++ b/src/components/post/post-desktop/post-desktop.tsx @@ -5,7 +5,6 @@ import { Comment, useAccount, useBlock, useComment } from '@plebbit/plebbit-reac import Plebbit from '@plebbit/plebbit-js/dist/browser/index.js'; import styles from '../post.module.css'; import { getCommentMediaInfo, getDisplayMediaInfoType, getHasThumbnail } from '../../../lib/utils/media-utils'; -import { getFormattedDate } from '../../../lib/utils/time-utils'; import { isValidURL } from '../../../lib/utils/url-utils'; import { isAllView, isPendingPostView, isPostPageView, isSubscriptionsView } from '../../../lib/utils/view-utils'; import useCountLinksInReplies from '../../../hooks/use-count-links-in-replies'; @@ -20,6 +19,7 @@ import PostMenuDesktop from './post-menu-desktop/'; import EditMenu from '../edit-menu/edit-menu'; import ReplyQuotePreview from '../reply-quote-preview'; import { PostProps } from '../post'; +import Timestamp from '../timestamp'; import _ from 'lodash'; const PostInfo = ({ openReplyModal, post, roles, isHidden }: PostProps) => { @@ -58,7 +58,7 @@ const PostInfo = ({ openReplyModal, post, roles, isHidden }: PostProps) => { {!(isDescription || isRules) && (u/{shortAddress || accountShortAddress}) } - {getFormattedDate(timestamp)} + {isDescription || isRules ? '' : ' '} diff --git a/src/components/post/post-mobile/post-mobile.tsx b/src/components/post/post-mobile/post-mobile.tsx index 75be17c9..7b4c43d3 100644 --- a/src/components/post/post-mobile/post-mobile.tsx +++ b/src/components/post/post-mobile/post-mobile.tsx @@ -5,7 +5,6 @@ import { Comment, useAccount, useComment } from '@plebbit/plebbit-react-hooks'; import Plebbit from '@plebbit/plebbit-js/dist/browser/index.js'; import styles from '../post.module.css'; import { getCommentMediaInfo, getHasThumbnail } from '../../../lib/utils/media-utils'; -import { getFormattedDate } from '../../../lib/utils/time-utils'; import { isAllView, isPendingPostView, isPostPageView, isSubscriptionsView } from '../../../lib/utils/view-utils'; import useCountLinksInReplies from '../../../hooks/use-count-links-in-replies'; import useReplies from '../../../hooks/use-replies'; @@ -16,6 +15,7 @@ import Markdown from '../../markdown'; import ReplyQuotePreview from '../reply-quote-preview'; import PostMenuMobile from './post-menu-mobile'; import { PostProps } from '../post'; +import Timestamp from '../timestamp'; import _ from 'lodash'; const PostInfoAndMedia = ({ openReplyModal, post, roles }: PostProps) => { @@ -78,7 +78,7 @@ const PostInfoAndMedia = ({ openReplyModal, post, roles }: PostProps) => { p/{subplebbitAddress && Plebbit.getShortAddress(subplebbitAddress)} )} - {getFormattedDate(timestamp)}{' '} + {' '} {!(isDescription || isRules) && ( !cid && e.preventDefault()}> diff --git a/src/components/post/timestamp/index.ts b/src/components/post/timestamp/index.ts new file mode 100644 index 00000000..8fe28740 --- /dev/null +++ b/src/components/post/timestamp/index.ts @@ -0,0 +1 @@ +export { default } from './timestamp'; diff --git a/src/components/post/timestamp/timestamp.tsx b/src/components/post/timestamp/timestamp.tsx new file mode 100644 index 00000000..d5b71828 --- /dev/null +++ b/src/components/post/timestamp/timestamp.tsx @@ -0,0 +1,45 @@ +import { useState } from 'react'; +import { getFormattedDate, getFormattedTimeAgo } from '../../../lib/utils/time-utils'; +import { useFloating, autoUpdate, offset, flip, shift, useHover, useFocus, useDismiss, useRole, useInteractions, FloatingPortal } from '@floating-ui/react'; + +const Timestamp = ({ timestamp }: { timestamp: number }) => { + const [isOpen, setIsOpen] = useState(false); + + const { refs, floatingStyles, context } = useFloating({ + open: isOpen, + onOpenChange: setIsOpen, + placement: 'top', + whileElementsMounted: autoUpdate, + middleware: [ + offset(5), + flip({ + fallbackAxisSideDirection: 'start', + }), + shift(), + ], + }); + + const hover = useHover(context, { move: false, delay: { open: 250, close: 0 } }); + const focus = useFocus(context); + const dismiss = useDismiss(context); + const role = useRole(context, { role: 'tooltip' }); + + const { getReferenceProps, getFloatingProps } = useInteractions([hover, focus, dismiss, role]); + + return ( + <> + + {getFormattedDate(timestamp)} + + + {isOpen && ( +
+ {getFormattedTimeAgo(timestamp)} +
+ )} +
+ + ); +}; + +export default Timestamp; diff --git a/src/index.css b/src/index.css index 2ed703e2..d62858cd 100644 --- a/src/index.css +++ b/src/index.css @@ -34,6 +34,34 @@ hr { text-transform: capitalize; } +.tooltip { + position: absolute; + background-color: #181f24; + font-size: 11px; + line-height: 13px; + padding: 3px 6px; + z-index: 100000; + word-wrap: break-word; + white-space: pre-line; + max-width: 400px; + color: #fff; + text-align: center; +} + +.tooltip::before { + content: ""; + display: block; + width: 0; + height: 0; + position: absolute; + border-left: 4px solid transparent; + border-right: 4px solid transparent; + border-top: 4px solid #181f24; + margin-left: -4px; + bottom: -4px; + left: 50%; +} + @media (max-width: 640px) { .button { font-size: var(--button-font-size-mobile); diff --git a/src/views/home/boards-box/boards-box.tsx b/src/views/home/boards-box/boards-box.tsx index ee7ce7aa..aef5bbed 100644 --- a/src/views/home/boards-box/boards-box.tsx +++ b/src/views/home/boards-box/boards-box.tsx @@ -197,7 +197,7 @@ const BoardsBox = ({ multisub, subplebbits }: { multisub: Subplebbit[]; subplebb return (
-

{t('boards')}

+

{t('boards')}

diff --git a/src/views/home/home.module.css b/src/views/home/home.module.css index 0bad3b19..a7855eba 100644 --- a/src/views/home/home.module.css +++ b/src/views/home/home.module.css @@ -150,10 +150,6 @@ content: '✔ '; } -.capitalize { - text-transform: capitalize; -} - .list a { color: var(--homepage-box-link-text-color); text-decoration: var(--homepage-box-link-text-decoration); diff --git a/src/views/home/home.tsx b/src/views/home/home.tsx index ec9fbe3b..3c61045d 100644 --- a/src/views/home/home.tsx +++ b/src/views/home/home.tsx @@ -88,7 +88,7 @@ const Stats = ({ multisub, subplebbitAddresses }: { multisub: any; subplebbitAdd return (
-

{t('stats')}

+

{t('stats')}

{enoughStats ? ( diff --git a/src/views/home/popular-threads-box/popular-threads-box.tsx b/src/views/home/popular-threads-box/popular-threads-box.tsx index 76b13a1e..338dc4c8 100644 --- a/src/views/home/popular-threads-box/popular-threads-box.tsx +++ b/src/views/home/popular-threads-box/popular-threads-box.tsx @@ -63,7 +63,7 @@ const PopularThreadsBox = ({ multisub, subplebbits }: { multisub: Subplebbit[]; return (
-

{t('popular_threads')}

+

{t('popular_threads')}