Skip to content

Commit

Permalink
Refactoring Nested Comments
Browse files Browse the repository at this point in the history
  • Loading branch information
siwachs committed Sep 5, 2024
1 parent a9ce3ef commit 7e9370a
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import ChapterLink from "@/components/buttons/chapterLink";

import { CHAPTERS_LIST_DEFAULT_PAGE_SIZE } from "@/constants";

import { AiOutlineLoading } from "react-icons/ai";
import { LiaTimesSolid } from "react-icons/lia";
import LoadingSpinner from "@/components/utils/loadingSpinner";

const InfiniteScrollWithIntersectionObserver: React.FC<{
infiniteScroll: boolean;
Expand Down Expand Up @@ -126,12 +126,12 @@ const InfiniteScrollWithIntersectionObserver: React.FC<{
/>
))}

<div
ref={loaderRef}
className={`my-5 ${chaptersPayload.pageNumber < chaptersPayload.totalPages ? "" : "hidden"} text-[var(--app-text-color-bright-pink)]`}
>
<AiOutlineLoading className="mx-auto size-8 animate-spin" />
</div>
<LoadingSpinner
loaderRef={loaderRef}
hideLoader={
chaptersPayload.pageNumber >= chaptersPayload.totalPages
}
/>
</div>
</div>
</ModelOverlay>
Expand Down
3 changes: 0 additions & 3 deletions src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,12 @@
/* Nested Comment System Variables */
--app-text-color-cool-tone-grayish-blue: #656c7a;
--app-text-color-muted-blue-gray: #030304;
--app-text-color-dark-grayish-green: #2a2e2e;
--app-text-color-blue-gray: #687a86;
--app-text-color-grayish-blue: #e7e9ee;
--app-text-color-gunmelt-gray: rgb(51, 51, 51);
--app-text-color-very-dary-steel-blue: #494e58;
--app-text-color-medium-gray-blue: #7f919e;
--app-text-color-light-blue-gray: rgba(60, 75, 120, 0.12);

--app-border-color-slightly-blue-gray: #c2c6cc;
--app-border-color-grayish-blue: rgba(60, 78, 110, 0.18);
--app-border-color-periwinkle: #9ca1de;
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/nestedCommentSystem/commentForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ const CommentForm: React.FC<{
<button
disabled={!userId}
type="submit"
className="h-fit whitespace-nowrap rounded-[14px] bg-[var(--app-text-color-gunmelt-gray)] p-[3.5px_15px] text-[15px] font-bold text-white hover:border-[#526069] hover:bg-[#526069] disabled:bg-[#526069]"
className="h-fit whitespace-nowrap rounded-[14px] bg-gray-800 p-[3.5px_15px] text-[15px] font-bold text-white hover:border-[#526069] hover:bg-[#526069] disabled:bg-[#526069]"
>
Comment
</button>
Expand Down
75 changes: 30 additions & 45 deletions src/components/nestedCommentSystem/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import Image from "next/image";

import { formatDistanceToNow, parseISO } from "date-fns";
import { roboto } from "@/libs/fonts";
import { Comment as CommentType, VoteType } from "@/types";
import { Comment as CommentType, SortKey, VoteType } from "@/types";

import { useNestedCommentSystem } from "@/contexts/nestedCommentContext";
import CommentForm from "./commentForm";
Expand All @@ -21,9 +21,6 @@ import { FaMinus, FaPlus } from "react-icons/fa6";
import { TiFlag } from "react-icons/ti";
import { IoMdShareAlt } from "react-icons/io";

const sortButtonClasses =
"text-sm/[19px] font-semibold data-[active=true]:border-b-[3px] data-[active=true]:border-[var(--app-text-color-gunmelt-gray)]";

const NestedCommentsContainer: React.FC = () => {
const {
rootComments,
Expand Down Expand Up @@ -57,10 +54,10 @@ const NestedCommentsContainer: React.FC = () => {

return (
<div
className={`${roboto.className} nested-comment-system-wrapper text-[var(--app-text-color-dark-grayish-green)]`}
className={`${roboto.className} nested-comment-system-wrapper text-gray-800`}
>
<header className="mb-6">
<div className="flex items-center justify-between border-b-2 border-[var(--app-border-color-slightly-blue-gray)] py-3 font-bold">
<div className="flex items-center justify-between border-b-2 border-gray-300 py-3 font-bold">
<span
className={
commentsPayload.loading
Expand All @@ -81,6 +78,7 @@ const NestedCommentsContainer: React.FC = () => {
<span className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 text-xs text-white">
1
</span>

<IoChatbubble className="size-[22px]" />
</div>

Expand All @@ -98,49 +96,37 @@ const NestedCommentsContainer: React.FC = () => {
<div className="mb-3 ml-3 flex items-center gap-2.5">
<FaRegHeart />

<span className="text-xs/[18px] font-bold">6</span>
<span className="text-xs/[18px] font-bold">0</span>
</div>

<div className="mb-3 flex items-center gap-4 pt-[3px]">
<button
type="button"
onClick={() => changeCommentsOrder("BEST")}
data-active={commentsPayload.sortKey === "BEST"}
className={sortButtonClasses}
>
Best
</button>

<button
type="button"
onClick={() => changeCommentsOrder("NEWEST")}
data-active={commentsPayload.sortKey === "NEWEST"}
className={sortButtonClasses}
>
Newest
</button>

<button
type="button"
onClick={() => changeCommentsOrder("OLDEST")}
data-active={commentsPayload.sortKey === "OLDEST"}
className={sortButtonClasses}
>
Oldest
</button>
{["BEST", "NEWEST", "OLDEST"].map((order) => (
<button
key={order}
onClick={() => changeCommentsOrder(order as SortKey)}
data-active={commentsPayload.sortKey === order}
className="text-sm/[19px] font-semibold data-[active=true]:border-b-[3px] data-[active=true]:border-gray-800"
>
{order === "BEST"
? "Best"
: order === "NEWEST"
? "Newest"
: "Oldest"}
</button>
))}
</div>
</div>

{renderComments()}

{commentsPayload.pageNumber !== commentsPayload.totalPages && (
{commentsPayload.pageNumber < commentsPayload.totalPages && (
<button
type="button"
onClick={() => loadMoreComments(commentsPayload.pageNumber + 1)}
disabled={
commentsPayload.loading || commentsPayload.loadMoreCommentsLoding
}
className="my-1.5 w-full rounded-[15px] border border-[var(--app-text-color-gunmelt-gray)] pb-[8px] pt-[9px] text-center text-lg/[21px] font-bold text-[var(--app-text-color-gunmelt-gray)] transition-all duration-200 hover:bg-[var(--app-text-color-gunmelt-gray)] hover:text-white disabled:pointer-events-none"
className="my-1.5 w-full rounded-[15px] border border-gray-800 pb-[8px] pt-[9px] text-center text-lg/[21px] font-bold text-gray-800 transition-all duration-200 hover:bg-gray-800 hover:text-white disabled:pointer-events-none"
>
Load more comments
</button>
Expand All @@ -153,7 +139,7 @@ const NestedCommentsContainer: React.FC = () => {
};

const CommentList: React.FC<{ comments: CommentType[] }> = ({ comments }) => {
return comments.map((comment: any) => (
return comments.map((comment: CommentType) => (
<Comment key={comment.id} comment={comment} />
));
};
Expand Down Expand Up @@ -190,8 +176,9 @@ const Comment: React.FC<{ comment: CommentType }> = memo(({ comment }) => {
className={`relative mb-[9px] mr-2.5 ${isChildrenCollapsed ? "size-10" : "size-[52px]"} flex-shrink-0 rounded-2xl`}
>
<div
className={`absolute left-0 top-0 hidden ${isChildrenCollapsed ? "h-10" : "h-[52px]"} w-[5px] rounded-[3px] bg-[var(--app-text-color-gunmelt-gray)]`}
className={`absolute left-0 top-0 hidden ${isChildrenCollapsed ? "h-10" : "h-[52px]"} w-[5px] rounded-[3px] bg-gray-800`}
/>

<Image // ml-3
src={comment.user?.avatar ?? "/assets/person.png"}
alt={comment.user?.username ?? "profile-pic"}
Expand All @@ -211,15 +198,14 @@ const Comment: React.FC<{ comment: CommentType }> = memo(({ comment }) => {
className="mr-3 flex-1 text-xs/[21px]"
>
<div className="flex flex-wrap items-center">
<span className="mr-1 line-clamp-1 text-[15px] font-bold text-[var(--app-text-color-gunmelt-gray)]">
<span className="mr-1 line-clamp-1 text-[15px] font-bold text-gray-800">
{comment.user?.username ?? "deleted"}
&nbsp;
<HiUserAdd
className="-mt-1 inline-block size-[18px] text-[var(--app-text-color-blue-gray)] hover:text-[var(--app-text-color-gunmelt-gray)]"
className="-mt-1 inline-block size-[18px] text-[var(--app-text-color-blue-gray)] hover:text-gray-800"
tabIndex={0}
role="button"
aria-label="Add user"
onClick={() => {}}
/>
</span>

Expand Down Expand Up @@ -247,15 +233,15 @@ const Comment: React.FC<{ comment: CommentType }> = memo(({ comment }) => {
>
{isChildrenCollapsed ? (
<FaPlus
className="mr-2.5 size-4 hover:text-[var(--app-text-color-gunmelt-gray)]"
className="mr-2.5 size-4 hover:text-gray-800"
tabIndex={0}
role="button"
aria-label="Expand Children"
onClick={() => setIsChildrenCollapsed(false)}
/>
) : (
<FaMinus
className="mr-2.5 size-[18px] hover:text-[var(--app-text-color-gunmelt-gray)]"
className="mr-2.5 size-[18px] hover:text-gray-800"
tabIndex={0}
role="button"
aria-label="Collapse Children"
Expand All @@ -264,11 +250,10 @@ const Comment: React.FC<{ comment: CommentType }> = memo(({ comment }) => {
)}

<TiFlag
className="mt-0.5 size-4 hover:text-[var(--app-text-color-gunmelt-gray)]"
className="mt-0.5 size-4 hover:text-gray-800"
tabIndex={0}
role="button"
aria-label="Flag Comment"
onClick={() => {}}
/>
</div>
</div>
Expand All @@ -288,7 +273,7 @@ const Comment: React.FC<{ comment: CommentType }> = memo(({ comment }) => {
}}
/>

<div className="mt-3 flex flex-wrap items-center gap-2 text-xs font-medium text-[var(--app-text-color-dark-grayish-green)]">
<div className="mt-3 flex flex-wrap items-center gap-2 text-xs font-medium text-gray-800">
<div className="flex flex-wrap items-center">
<button
onClick={() => onClickVoteComment("up")}
Expand Down
14 changes: 7 additions & 7 deletions src/components/utils/lazyLoadComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,12 @@
import { useState, useRef, useEffect } from "react";
import dynamic from "next/dynamic";

const Loader = () => {
return (
<div className="mx-auto h-[107px] max-w-[1110px] animate-pulse bg-gray-400" />
);
};
import LoadingSpinner from "./loadingSpinner";

// Dynamic Imports
const NestedCommentsSystem = dynamic(() => import("../nestedCommentSystem"), {
ssr: false,
loading: () => <Loader />,
loading: () => <LoadingSpinner />,
});

type ComponentType = "NestedCommentSystem";
Expand Down Expand Up @@ -54,7 +50,11 @@ const LazyLoadComponent: React.FC<{ component: ComponentType }> = ({

const Component = getComponent();

return <div ref={ref}>{isVisible && Component && <Component />}</div>;
return (
<div ref={ref}>
{isVisible && Component ? <Component /> : <LoadingSpinner />}
</div>
);
};

export default LazyLoadComponent;
17 changes: 17 additions & 0 deletions src/components/utils/loadingSpinner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { AiOutlineLoading } from "react-icons/ai";

const LoadingSpinner: React.FC<{
loaderRef?: React.RefObject<HTMLDivElement>;
hideLoader?: boolean;
}> = ({ loaderRef, hideLoader }) => {
return (
<div
ref={loaderRef}
className={`my-5 ${hideLoader ? "hidden" : ""} text-[var(--app-text-color-bright-pink)]`}
>
<AiOutlineLoading className="mx-auto size-8 animate-spin" />
</div>
);
};

export default LoadingSpinner;
8 changes: 4 additions & 4 deletions src/contexts/nestedCommentContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ type ContextType = {
headers: Record<string, any>,
commentId: string,
) => Promise<void>;
loadMoreComments: (pageNumber: string) => Promise<void>;
loadMoreComments: (pageNumber: number) => Promise<void>;
};

const NestedCommentSystemContext = createContext<ContextType | undefined>(
Expand Down Expand Up @@ -174,7 +174,7 @@ export function NestedCommentProvider({

// Nested Comment System CRUD
const loadMoreComments = useCallback(
async (pageNumber: string) => {
async (pageNumber: number) => {
updateCommentsPayload({ loading: true });
const commentsSortKey =
commentsPayload.sortKey || DEFAULT_NESTED_COMMENT_SYSTEM_SORT_KEY;
Expand All @@ -184,12 +184,12 @@ export function NestedCommentProvider({
contentId,
chapterId,
commentsSortKey,
pageNumber,
pageNumber: pageNumber.toString(),
}
: {
contentId,
commentsSortKey,
pageNumber,
pageNumber: pageNumber.toString(),
},
).toString();

Expand Down

0 comments on commit 7e9370a

Please sign in to comment.