From 6430607363419b695487942ec31ea071f4205912 Mon Sep 17 00:00:00 2001 From: "Tom (plebeius.eth)" Date: Mon, 22 Jul 2024 12:29:05 +0200 Subject: [PATCH 1/8] fix(reply modal): cursor would move to end of text while replying --- src/components/reply-modal/reply-modal.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/components/reply-modal/reply-modal.tsx b/src/components/reply-modal/reply-modal.tsx index b4a1a440..c8842b93 100644 --- a/src/components/reply-modal/reply-modal.tsx +++ b/src/components/reply-modal/reply-modal.tsx @@ -86,11 +86,16 @@ const ReplyModal = ({ closeModal, parentCid, scrollY }: ReplyModalProps) => { if (ref) { textRef.current = ref; !isMobile && ref.focus(); - const len = ref.value.length; - ref.setSelectionRange(len, len); } }; + useEffect(() => { + if (textRef.current) { + const len = textRef.current.value.length; + textRef.current.setSelectionRange(len, len); + } + }, []); + const contentPrefix = `c/${parentCid && Plebbit.getShortCid(parentCid)}\n`; const handleContentInput = (e: React.ChangeEvent) => { From 7ff8af7fcd78f044d352fc74b67f7d3a712e5a7d Mon Sep 17 00:00:00 2001 From: "Tom (plebeius.eth)" Date: Mon, 22 Jul 2024 12:29:32 +0200 Subject: [PATCH 2/8] feat(post): show loading state info --- src/components/post-desktop/post-desktop.tsx | 19 ++++++++++--------- src/components/post-mobile/post-mobile.tsx | 17 +++++++++-------- src/views/post/post.module.css | 10 ---------- 3 files changed, 19 insertions(+), 27 deletions(-) diff --git a/src/components/post-desktop/post-desktop.tsx b/src/components/post-desktop/post-desktop.tsx index 768afb7b..c8e16445 100644 --- a/src/components/post-desktop/post-desktop.tsx +++ b/src/components/post-desktop/post-desktop.tsx @@ -434,7 +434,7 @@ const PostDesktop = ({ openReplyModal, post, roles, showAllReplies, showReplies )} )} - {post?.replyCount === undefined && ( + {post?.replyCount === undefined && !isInPendingPostView && ( @@ -452,14 +452,15 @@ const PostDesktop = ({ openReplyModal, post, roles, showAllReplies, showReplies ))} - {stateString && stateString !== 'Failed' ? ( -
-
- -
- ) : ( - state === 'failed' && {t('failed')} - )} + {!isInPendingPostView && + (stateString && stateString !== 'Failed' ? ( +
+
+ +
+ ) : ( + state === 'failed' && {t('failed')} + ))} ); }; diff --git a/src/components/post-mobile/post-mobile.tsx b/src/components/post-mobile/post-mobile.tsx index 980e7ec3..322f0860 100644 --- a/src/components/post-mobile/post-mobile.tsx +++ b/src/components/post-mobile/post-mobile.tsx @@ -348,7 +348,7 @@ const PostMobile = ({ openReplyModal, post, roles, showAllReplies, showReplies = )} - {post?.replyCount === undefined && ( + {post?.replyCount === undefined && !isInPendingPostView && ( @@ -365,13 +365,14 @@ const PostMobile = ({ openReplyModal, post, roles, showAllReplies, showReplies = ))} - {stateString && stateString !== 'Failed' ? ( -
- -
- ) : ( - state === 'failed' && {t('failed')} - )} + {!isInPendingPostView && + (stateString && stateString !== 'Failed' ? ( +
+ +
+ ) : ( + state === 'failed' && {t('failed')} + ))} )} diff --git a/src/views/post/post.module.css b/src/views/post/post.module.css index 2583f8a3..4b8a2777 100644 --- a/src/views/post/post.module.css +++ b/src/views/post/post.module.css @@ -519,8 +519,6 @@ white-space: nowrap; overflow: hidden; text-overflow: ellipsis; - width: calc(100vw - 28px); - width: 100vw; } @media (max-width: 640px) { @@ -544,10 +542,6 @@ .authorAvatar { vertical-align: middle; } - - .stateString { - padding-left: 5px; - } } @media (min-width: 640px) { @@ -568,8 +562,4 @@ .replyMobile { display: none; } - - .stateString { - padding-top: 10px; - } } \ No newline at end of file From ddb462b95e7c00fc81f28234d12ce3909ede7dc8 Mon Sep 17 00:00:00 2001 From: "Tom (plebeius.eth)" Date: Mon, 22 Jul 2024 16:10:59 +0200 Subject: [PATCH 3/8] fix(post): reply quote link couldn't render in posts with link and no content --- src/components/post-desktop/post-desktop.tsx | 4 +- src/components/post-mobile/post-mobile.tsx | 130 +++++++++--------- .../avatar-settings.module.css | 1 - 3 files changed, 66 insertions(+), 69 deletions(-) diff --git a/src/components/post-desktop/post-desktop.tsx b/src/components/post-desktop/post-desktop.tsx index c8e16445..1b73dfad 100644 --- a/src/components/post-desktop/post-desktop.tsx +++ b/src/components/post-desktop/post-desktop.tsx @@ -341,7 +341,7 @@ const Reply = ({ openReplyModal, postReplyCount, reply, roles }: PostProps) => { post = editedComment; } - const { author, cid, content, link, postCid, subplebbitAddress } = post || {}; + const { author, cid, link, postCid, subplebbitAddress } = post || {}; const isRouteLinkToReply = useLocation().pathname.startsWith(`/p/${subplebbitAddress}/c/${cid}`); const { hidden } = useHide({ cid }); @@ -356,7 +356,7 @@ const Reply = ({ openReplyModal, postReplyCount, reply, roles }: PostProps) => { > {link && !hidden && isValidURL(link) && } - {content && !hidden && } + {!hidden && } ); diff --git a/src/components/post-mobile/post-mobile.tsx b/src/components/post-mobile/post-mobile.tsx index 322f0860..4d735d41 100644 --- a/src/components/post-mobile/post-mobile.tsx +++ b/src/components/post-mobile/post-mobile.tsx @@ -185,72 +185,70 @@ const PostMessageMobile = ({ post }: PostProps) => { ); return ( - content && ( -
- {isReply && !(removed || deleted) && state !== 'failed' && isReplyingToReply && } - {removed ? ( +
+ {isReply && !(removed || deleted) && state !== 'failed' && isReplyingToReply && } + {removed ? ( + ({t('this_post_was_removed')})} + content={`${_.capitalize(t('reason'))}: "${reason}"`} + showTooltip={!!reason} + /> + ) : deleted ? ( + {t('user_deleted_this_post')}} content={reason && `${t('reason')}: ${reason}`} /> + ) : ( + <> + {!showOriginal && } + {edit && original?.content !== post?.content && ( + + {showOriginal && } +
+ {t('comment_edited_at_timestamp', { timestamp: getFormattedDate(edit?.timestamp), interpolation: { escapeValue: false } })}{' '} + {reason && <>{t('reason_reason', { reason: reason, interpolation: { escapeValue: false } })} } + {showOriginal ? ( + setShowOriginal(!showOriginal)} /> }} + /> + ) : ( + setShowOriginal(!showOriginal)} /> }} + /> + )} +
+ )} + + )} + {/* TODO: commentAuthor is not available outside of editedComment, update when available */} + {/* {banned && ( + +
+
({t('this_post_was_removed')})
} - content={`${_.capitalize(t('reason'))}: "${reason}"`} - showTooltip={!!reason} + children={`(${t('user_banned')})`} + content={`${t('ban_expires_at', { + address: subplebbitAddress && Plebbit.getShortAddress(subplebbitAddress), + timestamp: getFormattedDate(commentAuthor?.banExpiresAt), + interpolation: { escapeValue: false }, + })}${reason ? `. ${_.capitalize(t('reason'))}: "${reason}"` : ''}`} /> - ) : deleted ? ( - {t('user_deleted_this_post')}} content={reason && `${t('reason')}: ${reason}`} /> - ) : ( - <> - {!showOriginal && } - {edit && original?.content !== post?.content && ( - - {showOriginal && } -
- {t('comment_edited_at_timestamp', { timestamp: getFormattedDate(edit?.timestamp), interpolation: { escapeValue: false } })}{' '} - {reason && <>{t('reason_reason', { reason: reason, interpolation: { escapeValue: false } })} } - {showOriginal ? ( - setShowOriginal(!showOriginal)} /> }} - /> - ) : ( - setShowOriginal(!showOriginal)} /> }} - /> - )} -
- )} - - )} - {/* TODO: commentAuthor is not available outside of editedComment, update when available */} - {/* {banned && ( - -
-
- -
- )} */} - {!isReply && content.length > 1000 && !isInPostView && ( - -
- }} /> -
- )} - {!cid && state === 'pending' && stateString !== 'Failed' && ( - <> -
- {loadingString} - - )} -
- ) + + )} */} + {!isReply && content.length > 1000 && !isInPostView && ( + +
+ }} /> +
+ )} + {!cid && state === 'pending' && stateString !== 'Failed' && ( + <> +
+ {loadingString} + + )} +
); }; @@ -261,7 +259,7 @@ const Reply = ({ openReplyModal, postReplyCount, reply, roles }: PostProps) => { if (editedComment) { post = editedComment; } - const { author, cid, content, postCid, subplebbitAddress } = post || {}; + const { author, cid, postCid, subplebbitAddress } = post || {}; const isRouteLinkToReply = useLocation().pathname.startsWith(`/p/${subplebbitAddress}/c/${cid}`); const { hidden } = useHide({ cid }); @@ -275,7 +273,7 @@ const Reply = ({ openReplyModal, postReplyCount, reply, roles }: PostProps) => { data-post-cid={postCid} > - {content && !hidden && } + {!hidden && } diff --git a/src/components/settings-modal/avatar-settings/avatar-settings.module.css b/src/components/settings-modal/avatar-settings/avatar-settings.module.css index 163afba8..409947bb 100644 --- a/src/components/settings-modal/avatar-settings/avatar-settings.module.css +++ b/src/components/settings-modal/avatar-settings/avatar-settings.module.css @@ -4,7 +4,6 @@ border: 1px solid #aaa; background-color: var(--avatar-background-color, white); margin-left: 10px; - border-radius: 32px; overflow: hidden; } From 7646402ca45c80b5c32d1a27d43a9664e14a71e4 Mon Sep 17 00:00:00 2001 From: "Tom (plebeius.eth)" Date: Mon, 22 Jul 2024 16:52:13 +0200 Subject: [PATCH 4/8] update avatar style --- src/components/post-desktop/post-desktop.tsx | 6 ++--- src/components/post-mobile/post-mobile.tsx | 6 ++--- src/views/post/post.module.css | 23 ++++++++++++++------ 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/components/post-desktop/post-desktop.tsx b/src/components/post-desktop/post-desktop.tsx index 1b73dfad..5d84ba7e 100644 --- a/src/components/post-desktop/post-desktop.tsx +++ b/src/components/post-desktop/post-desktop.tsx @@ -102,9 +102,9 @@ const PostInfo = ({ openReplyModal, post, postReplyCount = 0, roles, isHidden }: {!(isDescription || isRules) && ( <> {isReply && author?.avatar && ( - <> - {' '} - + + + )} (u/ {isReply && author?.avatar && ( - <> - {' '} - + + + )} (u/ Date: Mon, 22 Jul 2024 18:14:22 +0200 Subject: [PATCH 5/8] show 'loading' while pending post state isn't defined --- src/components/post-desktop/post-desktop.tsx | 4 ++-- src/components/post-mobile/post-mobile.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/post-desktop/post-desktop.tsx b/src/components/post-desktop/post-desktop.tsx index 5d84ba7e..1a149f92 100644 --- a/src/components/post-desktop/post-desktop.tsx +++ b/src/components/post-desktop/post-desktop.tsx @@ -256,8 +256,8 @@ const PostMessage = ({ post }: PostProps) => { const stateString = useStateString(post); - const loadingString = stateString && ( -
{stateString !== 'Failed' ? : stateString}
+ const loadingString = ( +
{stateString !== 'Failed' ? : stateString}
); return ( diff --git a/src/components/post-mobile/post-mobile.tsx b/src/components/post-mobile/post-mobile.tsx index bd50aafc..0eb84770 100644 --- a/src/components/post-mobile/post-mobile.tsx +++ b/src/components/post-mobile/post-mobile.tsx @@ -180,8 +180,8 @@ const PostMessageMobile = ({ post }: PostProps) => { const stateString = useStateString(post); - const loadingString = stateString && ( -
{stateString !== 'Failed' ? : stateString}
+ const loadingString = ( +
{stateString !== 'Failed' ? : stateString}
); return ( From bd7c5ae57912e54b7cf996952a291d7de2467cc6 Mon Sep 17 00:00:00 2001 From: "Tom (plebeius.eth)" Date: Mon, 22 Jul 2024 18:15:13 +0200 Subject: [PATCH 6/8] perf(offline indicator): improve reliability --- src/hooks/use-is-subplebbit-offline.ts | 14 +++---- ...plebbits-loading-start-timestamps-store.ts | 42 +++++++++++++++++++ 2 files changed, 49 insertions(+), 7 deletions(-) create mode 100644 src/hooks/use-subplebbits-loading-start-timestamps-store.ts diff --git a/src/hooks/use-is-subplebbit-offline.ts b/src/hooks/use-is-subplebbit-offline.ts index 70181ff8..f94c2f64 100644 --- a/src/hooks/use-is-subplebbit-offline.ts +++ b/src/hooks/use-is-subplebbit-offline.ts @@ -3,11 +3,13 @@ import { useEffect } from 'react'; import { Subplebbit } from '@plebbit/plebbit-react-hooks'; import { getFormattedTimeAgo } from '../lib/utils/time-utils'; import useSubplebbitOfflineStore from '../stores/use-subplebbit-offline-store'; +import useSubplebbitsLoadingStartTimestamps from './use-subplebbits-loading-start-timestamps-store'; const useIsSubplebbitOffline = (subplebbit: Subplebbit) => { const { t } = useTranslation(); const { address, state, updatedAt, updatingState } = subplebbit || {}; const { subplebbitOfflineState, setSubplebbitOfflineState, initializesubplebbitOfflineState } = useSubplebbitOfflineStore(); + const subplebbitsLoadingStartTimestamps = useSubplebbitsLoadingStartTimestamps([address]); useEffect(() => { if (address && !subplebbitOfflineState[address]) { @@ -22,15 +24,13 @@ const useIsSubplebbitOffline = (subplebbit: Subplebbit) => { }, [address, state, updatedAt, updatingState, setSubplebbitOfflineState]); const subplebbitOfflineStore = subplebbitOfflineState[address] || { initialLoad: true }; + const loadingStartTimestamp = subplebbitsLoadingStartTimestamps[0] || 0; - const isLoading = - updatingState === 'resolving-address' || - (updatingState === 'stopped' && state === 'stopped' && !updatedAt) || - (subplebbitOfflineStore.initialLoad && updatingState === 'fetching-ipns' && !updatedAt); + const isLoading = subplebbitOfflineStore.initialLoad && (!updatedAt || Date.now() / 1000 - updatedAt >= 60 * 60) && Date.now() / 1000 - loadingStartTimestamp < 30; - const isOffline = - !isLoading && ((updatedAt && updatedAt < Date.now() / 1000 - 60 * 60) || updatingState === 'failed' || (updatingState === 'fetching-ipns' && !updatedAt)); + const isOffline = !isLoading && ((updatedAt && updatedAt < Date.now() / 1000 - 60 * 60) || (!updatedAt && Date.now() / 1000 - loadingStartTimestamp >= 30)); + const isOnline = updatedAt && Date.now() / 1000 - updatedAt < 60 * 60; const offlineIconClass = isLoading ? 'yellowOfflineIcon' : isOffline ? 'redOfflineIcon' : ''; const offlineTitle = isLoading @@ -39,7 +39,7 @@ const useIsSubplebbitOffline = (subplebbit: Subplebbit) => { ? isOffline && t('posts_last_synced_info', { time: getFormattedTimeAgo(updatedAt), interpolation: { escapeValue: false } }) : t('subplebbit_offline_info'); - return { isOffline, isOnlineStatusLoading: isLoading, offlineIconClass, offlineTitle }; + return { isOffline: !isOnline && isOffline, isOnlineStatusLoading: !isOnline && isLoading, offlineIconClass, offlineTitle }; }; export default useIsSubplebbitOffline; diff --git a/src/hooks/use-subplebbits-loading-start-timestamps-store.ts b/src/hooks/use-subplebbits-loading-start-timestamps-store.ts new file mode 100644 index 00000000..80ecdb5b --- /dev/null +++ b/src/hooks/use-subplebbits-loading-start-timestamps-store.ts @@ -0,0 +1,42 @@ +import { useEffect, useMemo } from 'react'; +import { create } from 'zustand'; + +interface SubplebbitsLoadingStartTimestampsState { + timestamps: Record; + addSubplebbits: (subplebbitAddresses: string[]) => void; +} + +const useSubplebbitsLoadingStartTimestampsStore = create((set, get) => ({ + timestamps: {}, + addSubplebbits: (subplebbitAddresses) => { + const { timestamps } = get(); + const newTimestamps: Record = {}; + subplebbitAddresses.forEach((subplebbitAddress) => { + if (!timestamps[subplebbitAddress]) { + newTimestamps[subplebbitAddress] = Math.round(Date.now() / 1000); + } + }); + if (Object.keys(newTimestamps).length) { + set((state) => ({ timestamps: { ...state.timestamps, ...newTimestamps } })); + } + }, +})); + +const useSubplebbitsLoadingStartTimestamps = (subplebbitAddresses?: string[]) => { + const timestampsStore = useSubplebbitsLoadingStartTimestampsStore((state) => state.timestamps); + const addSubplebbits = useSubplebbitsLoadingStartTimestampsStore((state) => state.addSubplebbits); + + useEffect(() => { + if (subplebbitAddresses) { + addSubplebbits(subplebbitAddresses); + } + }, [subplebbitAddresses, addSubplebbits]); + + const subplebbitsLoadingStartTimestamps = useMemo(() => { + return subplebbitAddresses?.map((subplebbitAddress) => timestampsStore[subplebbitAddress]) || []; + }, [timestampsStore, subplebbitAddresses]); + + return subplebbitsLoadingStartTimestamps; +}; + +export default useSubplebbitsLoadingStartTimestamps; From 38e60fd797812756480c84d46fb81a4223efec9a Mon Sep 17 00:00:00 2001 From: "Tom (plebeius.eth)" Date: Tue, 23 Jul 2024 09:01:03 +0200 Subject: [PATCH 7/8] fix(board title): offline icon would appear in p/all and p/subscriptions --- src/components/board-header/board-header.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/board-header/board-header.tsx b/src/components/board-header/board-header.tsx index dbcc7bd5..cf7f0ae9 100644 --- a/src/components/board-header/board-header.tsx +++ b/src/components/board-header/board-header.tsx @@ -45,7 +45,9 @@ const BoardHeader = () => { )}
{title || `p/${shortAddress || subplebbitAddress}`} - {(isOffline || isOnlineStatusLoading) && } + {(isOffline || isOnlineStatusLoading) && !isInAllView && !isInSubscriptionsView && ( + + )}
{subtitle}

From 9552938b6de5fd3d860cca8c9335ce6f1487adbb Mon Sep 17 00:00:00 2001 From: "Tom (plebeius.eth)" Date: Tue, 23 Jul 2024 12:18:02 +0200 Subject: [PATCH 8/8] fix(markdown): bullet point lists were bugged --- src/components/markdown/markdown.module.css | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/components/markdown/markdown.module.css b/src/components/markdown/markdown.module.css index fe6b2eec..9ecbb5e8 100644 --- a/src/components/markdown/markdown.module.css +++ b/src/components/markdown/markdown.module.css @@ -8,10 +8,6 @@ text-decoration: var(--post-content-link-text-decoration-hover); } -.markdown li { - list-style-position: inside; -} - .hrWrapper { padding: 0.5em 0; }