Skip to content

Commit

Permalink
Merge pull request #4268 from coralproject/develop
Browse files Browse the repository at this point in the history
v8.2.4
  • Loading branch information
tessalt authored Jun 14, 2023
2 parents b4441d4 + a64e06b commit 5b87ba5
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 46 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@coralproject/talk",
"version": "8.2.3",
"version": "8.2.4",
"author": "The Coral Project",
"homepage": "https://coralproject.net/",
"sideEffects": [
Expand Down
2 changes: 1 addition & 1 deletion src/core/client/admin/components/BanModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ const BanModal: FunctionComponent<Props> = ({
message: customizeMessage ? emailMessage : getDefaultMessage,
rejectExistingComments,
siteIDs: viewerIsScoped
? viewer.moderationScopes!.sites!.map(({ id }) => id)
? viewer?.moderationScopes?.sites?.map(({ id }) => id)
: [],
});
break;
Expand Down
30 changes: 30 additions & 0 deletions src/core/client/admin/components/ModerateCard/ModerateCard.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Localized } from "@fluent/react/compat";
import cn from "classnames";
import key from "keymaster";
import { noop } from "lodash";
import React, {
FunctionComponent,
useCallback,
Expand All @@ -9,6 +11,7 @@ import React, {
} from "react";

import { MediaContainer } from "coral-admin/components/MediaContainer";
import { HOTKEYS } from "coral-admin/constants";
import { GQLWordlistMatch } from "coral-framework/schema";
import { PropTypesOf } from "coral-framework/types";
import {
Expand Down Expand Up @@ -133,6 +136,33 @@ const ModerateCard: FunctionComponent<Props> = ({
}) => {
const div = useRef<HTMLDivElement>(null);

useEffect(() => {
if (selected) {
key.setScope(id);
}
}, [selected, id]);

useEffect(() => {
if (selectNext) {
key(HOTKEYS.NEXT, id, selectNext);
}
if (selectPrev) {
key(HOTKEYS.PREV, id, selectPrev);
}
if (onBan) {
key(HOTKEYS.BAN, id, onBan);
}
key(HOTKEYS.APPROVE, id, onApprove);
key(HOTKEYS.REJECT, id, onReject);

return () => {
// Remove all events that are set in the ${id} scope.
key.deleteScope(id);
};

return noop;
}, [id, selectNext, selectPrev, onBan, onApprove, onReject]);

useEffect(() => {
if (selected && div && div.current) {
div.current.focus();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ import {
import { ModerateCardContainer_settings } from "coral-admin/__generated__/ModerateCardContainer_settings.graphql";
import { ModerateCardContainer_viewer } from "coral-admin/__generated__/ModerateCardContainer_viewer.graphql";
import { ModerateCardContainerLocal } from "coral-admin/__generated__/ModerateCardContainerLocal.graphql";

import { UserStatusChangeContainer_viewer } from "coral-admin/__generated__/UserStatusChangeContainer_viewer.graphql";

import FeatureCommentMutation from "./FeatureCommentMutation";
import ModerateCard from "./ModerateCard";
import ModeratedByContainer from "./ModeratedByContainer";
Expand All @@ -52,6 +52,7 @@ interface Props {
selectPrev?: () => void;
selectNext?: () => void;
loadNext?: (() => void) | null;
onModerated?: () => void;
}

function getStatus(comment: ModerateCardContainer_comment) {
Expand Down Expand Up @@ -84,6 +85,7 @@ const ModerateCardContainer: FunctionComponent<Props> = ({
onConversationClicked: conversationClicked,
onSetSelected: setSelected,
loadNext,
onModerated,
}) => {
const approveComment = useMutation(ApproveCommentMutation);
const rejectComment = useMutation(RejectCommentMutation);
Expand Down Expand Up @@ -129,6 +131,9 @@ const ModerateCardContainer: FunctionComponent<Props> = ({
if (loadNext) {
loadNext();
}
if (onModerated) {
onModerated();
}
}, [
approveComment,
comment.id,
Expand All @@ -137,6 +142,7 @@ const ModerateCardContainer: FunctionComponent<Props> = ({
match,
readOnly,
moderationQueueSort,
onModerated,
]);

const handleReject = useCallback(async () => {
Expand All @@ -161,6 +167,9 @@ const ModerateCardContainer: FunctionComponent<Props> = ({
if (loadNext) {
loadNext();
}
if (onModerated) {
onModerated();
}
}, [
comment.revision,
comment.id,
Expand All @@ -169,6 +178,7 @@ const ModerateCardContainer: FunctionComponent<Props> = ({
rejectComment,
loadNext,
moderationQueueSort,
onModerated,
]);

const handleFeature = useCallback(() => {
Expand Down
77 changes: 36 additions & 41 deletions src/core/client/admin/routes/Moderate/Queue/Queue.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Localized } from "@fluent/react/compat";
import key from "keymaster";
import { noop } from "lodash";
import React, {
FunctionComponent,
useCallback,
Expand Down Expand Up @@ -40,8 +39,6 @@ interface Props {
viewNewCount?: number;
}

const QUEUE_HOTKEY_ID = "moderation-queue";

const Queue: FunctionComponent<Props> = ({
settings,
comments,
Expand All @@ -63,8 +60,16 @@ const Queue: FunctionComponent<Props> = ({
const [conversationModalVisible, setConversationModalVisible] =
useState(false);
const [conversationCommentID, setConversationCommentID] = useState("");
const [hasModerated, setHasModerated] = useState(false);
const memoize = useMemoizer();

// So we can register hotkeys for the first comment without immediately pulling focus
useEffect(() => {
if (comments.length > 0) {
key.setScope(comments[0].id);
}
}, []);

const toggleView = useCallback(() => {
if (!singleView) {
setSelectedComment(0);
Expand All @@ -81,49 +86,38 @@ const Queue: FunctionComponent<Props> = ({
const commentsRef = useRef<Props["comments"]>(comments);
commentsRef.current = comments;

const selectNext = useCallback(() => {
const index = selectedCommentRef.current || 0;
const nextComment = commentsRef.current[index + 1];
if (nextComment) {
setSelectedComment(index + 1);
const container: HTMLElement | null = window.document.getElementById(
`moderate-comment-${nextComment.id}`
);
if (container) {
container.scrollIntoView();
useEffect(() => {
if (selectedComment !== null && commentsRef.current.length > 0) {
// We've moderated the last comment via hotkey
if (selectedComment >= commentsRef.current.length) {
setSelectedComment(commentsRef.current.length - 1);
// We've moderated the first comment via hotkey
} else if (selectedComment < 0 && hasModerated) {
setSelectedComment(0);
}
}
}, [window.document]);

const selectPrev = useCallback(() => {
const index = selectedCommentRef.current || 0;
const prevComment = commentsRef.current[index - 1];
if (prevComment) {
setSelectedComment(index - 1);
const container: HTMLElement | null = window.document.getElementById(
`moderate-comment-${prevComment.id}`
);
if (container) {
container.scrollIntoView();
}, [commentsRef.current.length, selectedComment, hasModerated]);

const varyComment = useCallback(
(delta: number) => {
const index = selectedCommentRef.current || 0;
const targetComment = commentsRef.current[index + delta];
if (targetComment) {
setSelectedComment(index + delta);
const container: HTMLElement | null = window.document.getElementById(
`moderate-comment-${targetComment.id}`
);
if (container) {
container.scrollIntoView();
}
}
}
}, [window.document]);

useEffect(() => {
key(HOTKEYS.NEXT, QUEUE_HOTKEY_ID, selectNext);
key(HOTKEYS.PREV, QUEUE_HOTKEY_ID, selectPrev);

// The the scope such that only events attached to the ${id} scope will
// be honored.
key.setScope(QUEUE_HOTKEY_ID);
},
[window.document]
);

return () => {
// Remove all events that are set in the ${id} scope.
key.deleteScope(QUEUE_HOTKEY_ID);
};
const selectNext = useCallback(() => varyComment(1), [varyComment]);

return noop;
}, [selectNext, selectPrev]);
const selectPrev = useCallback(() => varyComment(-1), [varyComment]);

const onSetUserDrawerUserID = useCallback((userID: string) => {
setUserDrawerID(userID);
Expand Down Expand Up @@ -189,6 +183,7 @@ const Queue: FunctionComponent<Props> = ({
selected={selectedComment === i}
selectPrev={selectPrev}
selectNext={selectNext}
onModerated={() => setHasModerated(true)}
/>
)}
/>
Expand Down

0 comments on commit 5b87ba5

Please sign in to comment.