chore(frontend): add reactions setting

This commit is contained in:
Steven 2024-10-10 22:04:35 +08:00
parent e527b6a878
commit 2acad978d1
2 changed files with 56 additions and 5 deletions

View File

@ -68,15 +68,15 @@ const ReactionSelector = (props: Props) => {
<SmilePlusIcon className="w-4 h-4 mx-auto text-gray-500 dark:text-gray-400" />
</span>
</MenuButton>
<Menu className="relative text-sm" component="div" size="sm" placement="bottom-start">
<Menu className="relative" component="div" size="sm" placement="bottom-start">
<div ref={containerRef}>
<div className="grid grid-cols-6 py-0.5 px-2 h-auto font-mono gap-1">
<div className="flex flex-row flex-wrap py-0.5 px-2 h-auto gap-1 max-w-56">
{workspaceMemoRelatedSetting.reactions.map((reactionType) => {
return (
<span
key={reactionType}
className={clsx(
"inline-flex w-auto cursor-pointer rounded text-lg px-1 text-gray-500 dark:text-gray-400 hover:opacity-80",
"inline-flex w-auto text-base cursor-pointer rounded px-1 text-gray-500 dark:text-gray-400 hover:opacity-80",
hasReacted(reactionType) && "bg-blue-100 dark:bg-zinc-800",
)}
onClick={() => handleReactionClick(reactionType)}

View File

@ -1,5 +1,6 @@
import { Button, Input, Switch, Select, Option } from "@mui/joy";
import { isEqual } from "lodash-es";
import { Button, Input, Switch, Select, Option, Chip, ChipDelete } from "@mui/joy";
import { isEqual, uniq } from "lodash-es";
import { CheckIcon } from "lucide-react";
import { useState } from "react";
import { toast } from "react-hot-toast";
import { workspaceSettingNamePrefix, useWorkspaceSettingStore } from "@/store/v1";
@ -17,6 +18,7 @@ const MemoRelatedSettings = () => {
workspaceSettingStore.getWorkspaceSettingByKey(WorkspaceSettingKey.MEMO_RELATED)?.memoRelatedSetting || {},
);
const [memoRelatedSetting, setMemoRelatedSetting] = useState<WorkspaceMemoRelatedSetting>(originalSetting);
const [editingReaction, setEditingReaction] = useState<string>("");
const updatePartialSetting = (partial: Partial<WorkspaceMemoRelatedSetting>) => {
const newWorkspaceMemoRelatedSetting = WorkspaceMemoRelatedSetting.fromPartial({
@ -26,7 +28,21 @@ const MemoRelatedSettings = () => {
setMemoRelatedSetting(newWorkspaceMemoRelatedSetting);
};
const upsertReaction = () => {
if (!editingReaction) {
return;
}
updatePartialSetting({ reactions: uniq([...memoRelatedSetting.reactions, editingReaction.trim()]) });
setEditingReaction("");
};
const updateSetting = async () => {
if (memoRelatedSetting.reactions.length === 0) {
toast.error("Reactions must not be empty.");
return;
}
try {
await workspaceSettingStore.setWorkspaceSetting({
name: `${workspaceSettingNamePrefix}${WorkspaceSettingKey.MEMO_RELATED}`,
@ -120,6 +136,41 @@ const MemoRelatedSettings = () => {
))}
</Select>
</div>
<div className="w-full">
<span className="truncate">Reactions</span>
<div className="mt-2 w-full flex flex-row flex-wrap gap-1">
{memoRelatedSetting.reactions.map((reactionType) => {
return (
<Chip
className="!h-8"
key={reactionType}
variant="outlined"
size="lg"
endDecorator={
<ChipDelete
onDelete={() => updatePartialSetting({ reactions: memoRelatedSetting.reactions.filter((r) => r !== reactionType) })}
/>
}
>
{reactionType}
</Chip>
);
})}
<Input
className="w-32 !rounded-full !pl-3"
placeholder="Input"
size="sm"
value={editingReaction}
onChange={(event) => setEditingReaction(event.target.value.trim())}
endDecorator={
<CheckIcon
className="w-5 h-5 text-gray-500 dark:text-gray-400 cursor-pointer hover:text-teal-600"
onClick={() => upsertReaction()}
/>
}
/>
</div>
</div>
<div className="mt-2 w-full flex justify-end">
<Button disabled={isEqual(memoRelatedSetting, originalSetting)} onClick={updateSetting}>
{t("common.save")}