Skip to content

Commit

Permalink
Add comment sorting (aeharding#39)
Browse files Browse the repository at this point in the history
* Add comment sorting

* Finalize
  • Loading branch information
aeharding authored Jun 28, 2023
1 parent a555f4c commit ab1d826
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 22 deletions.
71 changes: 71 additions & 0 deletions src/features/comment/CommentSort.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import type { IonActionSheetCustomEvent } from "@ionic/core";
import {
ActionSheetButton,
IonActionSheet,
IonButton,
IonIcon,
} from "@ionic/react";
import { OverlayEventDetail } from "@ionic/react/dist/types/components/react-component-lib/interfaces";
import {
arrowUpCircleOutline,
flameOutline,
hourglassOutline,
timeOutline,
} from "ionicons/icons";
import { useState } from "react";
import { startCase } from "lodash";
import { CommentSortType } from "lemmy-js-client";

export const COMMENT_SORTS = ["Hot", "Top", "New", "Old"] as const;

const BUTTONS: ActionSheetButton<CommentSortType>[] = COMMENT_SORTS.map(
(sortType) => ({
text: startCase(sortType),
data: sortType,
icon: getSortIcon(sortType),
})
);

interface CommentSortProps {
sort: CommentSortType;
setSort: (sort: CommentSortType) => void;
}

export default function CommentSort({ sort, setSort }: CommentSortProps) {
const [open, setOpen] = useState(false);

return (
<>
<IonButton fill="default" onClick={() => setOpen(true)}>
<IonIcon icon={getSortIcon(sort)} color="primary" />
</IonButton>
<IonActionSheet
cssClass="left-align-buttons"
isOpen={open}
onDidDismiss={() => setOpen(false)}
onWillDismiss={(
e: IonActionSheetCustomEvent<OverlayEventDetail<CommentSortType>>
) => {
if (e.detail.data) {
setSort(e.detail.data);
}
}}
header="Sort by..."
buttons={BUTTONS}
/>
</>
);
}

function getSortIcon(sort: CommentSortType): string {
switch (sort) {
case "Hot":
return flameOutline;
case "Top":
return arrowUpCircleOutline;
case "New":
return timeOutline;
case "Old":
return hourglassOutline;
}
}
23 changes: 12 additions & 11 deletions src/features/comment/Comments.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
} from "@ionic/react";
import styled from "@emotion/styled";
import { css } from "@emotion/react";
import { CommentView, Person } from "lemmy-js-client";
import { CommentSortType, CommentView, Person } from "lemmy-js-client";
import { pullAllBy, uniqBy } from "lodash";
import { Virtuoso, VirtuosoHandle } from "react-virtuoso";
import { useAppDispatch, useAppSelector } from "../../store";
Expand Down Expand Up @@ -53,13 +53,17 @@ interface CommentsProps {
postId: number;
commentPath?: string;
op: Person;
sort: CommentSortType;
commentsLastUpdated: number;
}

export default function Comments({
header,
postId,
commentPath,
op,
sort,
commentsLastUpdated,
}: CommentsProps) {
const dispatch = useAppDispatch();
const jwt = useAppSelector(jwtSelector);
Expand Down Expand Up @@ -91,22 +95,19 @@ export default function Comments({
useEffect(() => {
fetchComments(true);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [postId, commentId]);
}, [sort, commentPath, jwt, postId, commentsLastUpdated]);

async function fetchComments(refresh = false) {
if (refresh) {
setLoading(false);
setFinishedPaging(false);
setPage(0);
setComments([]);
} else {
if (loading) return;
if (finishedPaging) return;
}

let response;

if (loading) return;
if (finishedPaging) return;

const currentPage = page + 1;
const currentPage = refresh ? 1 : page + 1;

const reqPostId = postId;
const reqCommentId = commentId;
Expand All @@ -117,7 +118,7 @@ export default function Comments({
post_id: reqPostId,
parent_id: commentId,
limit: 10,
sort: "Hot",
sort,
type_: "All",
max_depth: 8,
saved_only: false,
Expand Down Expand Up @@ -151,7 +152,7 @@ export default function Comments({
if (!newComments.length) setFinishedPaging(true);

let potentialComments = uniqBy(
[...comments, ...newComments],
[...existingComments, ...newComments],
(c) => c.comment.id
);

Expand Down
22 changes: 11 additions & 11 deletions src/features/post/detail/PostDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import AppBackButton from "../../shared/AppBackButton";
import Img from "./Img";
import { maxWidthCss } from "../../shared/AppContent";
import PersonLink from "../../labels/links/PersonLink";
import { PostView } from "lemmy-js-client";
import { CommentSortType, PostView } from "lemmy-js-client";
import { useBuildGeneralBrowseLink } from "../../../helpers/routes";
import ViewAllComments from "./ViewAllComments";
import CommentReply from "../../comment/reply/CommentReply";
Expand All @@ -38,6 +38,7 @@ import Video from "../../shared/Video";
import { css } from "@emotion/react";
import { PageContext } from "../../auth/PageContext";
import { jwtSelector } from "../../auth/authSlice";
import CommentSort from "../../comment/CommentSort";

const BorderlessIonItem = styled(IonItem)`
--padding-start: 0;
Expand Down Expand Up @@ -138,11 +139,12 @@ export default function PostDetail() {
);
const titleRef = useRef<HTMLDivElement>(null);
const pageContext = useContext(PageContext);
const [commentsKey, setCommentsKey] = useState(Date.now());
const [commentsLastUpdated, setCommentsLastUpdated] = useState(Date.now());
const [sort, setSort] = useState<CommentSortType>("Hot");

const [reply, onDismissReply] = useIonModal(CommentReply, {
onDismiss: (data: string, role: string) => {
if (role === "post") setCommentsKey(Date.now());
if (role === "post") setCommentsLastUpdated(Date.now());
onDismissReply(data, role);
},
item: post,
Expand All @@ -156,13 +158,7 @@ export default function PostDetail() {
if (post) return;

dispatch(getPost(+id));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [post]);

useEffect(() => {
dispatch(getPost(+id));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [jwt]);
}, [post, jwt, dispatch, id]);

useEffect(() => {
titleRef.current?.scrollIntoView({ behavior: "smooth" });
Expand Down Expand Up @@ -271,16 +267,20 @@ export default function PostDetail() {
/>
</IonButtons>
<IonTitle>{post?.counts.comments} Comments</IonTitle>
<IonButtons slot="end">
<CommentSort sort={sort} setSort={setSort} />
</IonButtons>
</IonToolbar>
</IonHeader>
<IonContent>
{post ? (
<Comments
key={commentsKey}
header={renderHeader(post)}
postId={post.post.id}
commentPath={commentPath}
op={post.creator}
sort={sort}
commentsLastUpdated={commentsLastUpdated}
/>
) : (
<CenteredSpinner />
Expand Down

0 comments on commit ab1d826

Please sign in to comment.