mirror of
https://github.com/usememos/memos.git
synced 2025-04-07 06:11:08 +02:00
chore(frontend): add reactions setting
This commit is contained in:
parent
e527b6a878
commit
2acad978d1
@ -68,15 +68,15 @@ const ReactionSelector = (props: Props) => {
|
|||||||
<SmilePlusIcon className="w-4 h-4 mx-auto text-gray-500 dark:text-gray-400" />
|
<SmilePlusIcon className="w-4 h-4 mx-auto text-gray-500 dark:text-gray-400" />
|
||||||
</span>
|
</span>
|
||||||
</MenuButton>
|
</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 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) => {
|
{workspaceMemoRelatedSetting.reactions.map((reactionType) => {
|
||||||
return (
|
return (
|
||||||
<span
|
<span
|
||||||
key={reactionType}
|
key={reactionType}
|
||||||
className={clsx(
|
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",
|
hasReacted(reactionType) && "bg-blue-100 dark:bg-zinc-800",
|
||||||
)}
|
)}
|
||||||
onClick={() => handleReactionClick(reactionType)}
|
onClick={() => handleReactionClick(reactionType)}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { Button, Input, Switch, Select, Option } from "@mui/joy";
|
import { Button, Input, Switch, Select, Option, Chip, ChipDelete } from "@mui/joy";
|
||||||
import { isEqual } from "lodash-es";
|
import { isEqual, uniq } from "lodash-es";
|
||||||
|
import { CheckIcon } from "lucide-react";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { toast } from "react-hot-toast";
|
import { toast } from "react-hot-toast";
|
||||||
import { workspaceSettingNamePrefix, useWorkspaceSettingStore } from "@/store/v1";
|
import { workspaceSettingNamePrefix, useWorkspaceSettingStore } from "@/store/v1";
|
||||||
@ -17,6 +18,7 @@ const MemoRelatedSettings = () => {
|
|||||||
workspaceSettingStore.getWorkspaceSettingByKey(WorkspaceSettingKey.MEMO_RELATED)?.memoRelatedSetting || {},
|
workspaceSettingStore.getWorkspaceSettingByKey(WorkspaceSettingKey.MEMO_RELATED)?.memoRelatedSetting || {},
|
||||||
);
|
);
|
||||||
const [memoRelatedSetting, setMemoRelatedSetting] = useState<WorkspaceMemoRelatedSetting>(originalSetting);
|
const [memoRelatedSetting, setMemoRelatedSetting] = useState<WorkspaceMemoRelatedSetting>(originalSetting);
|
||||||
|
const [editingReaction, setEditingReaction] = useState<string>("");
|
||||||
|
|
||||||
const updatePartialSetting = (partial: Partial<WorkspaceMemoRelatedSetting>) => {
|
const updatePartialSetting = (partial: Partial<WorkspaceMemoRelatedSetting>) => {
|
||||||
const newWorkspaceMemoRelatedSetting = WorkspaceMemoRelatedSetting.fromPartial({
|
const newWorkspaceMemoRelatedSetting = WorkspaceMemoRelatedSetting.fromPartial({
|
||||||
@ -26,7 +28,21 @@ const MemoRelatedSettings = () => {
|
|||||||
setMemoRelatedSetting(newWorkspaceMemoRelatedSetting);
|
setMemoRelatedSetting(newWorkspaceMemoRelatedSetting);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const upsertReaction = () => {
|
||||||
|
if (!editingReaction) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
updatePartialSetting({ reactions: uniq([...memoRelatedSetting.reactions, editingReaction.trim()]) });
|
||||||
|
setEditingReaction("");
|
||||||
|
};
|
||||||
|
|
||||||
const updateSetting = async () => {
|
const updateSetting = async () => {
|
||||||
|
if (memoRelatedSetting.reactions.length === 0) {
|
||||||
|
toast.error("Reactions must not be empty.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await workspaceSettingStore.setWorkspaceSetting({
|
await workspaceSettingStore.setWorkspaceSetting({
|
||||||
name: `${workspaceSettingNamePrefix}${WorkspaceSettingKey.MEMO_RELATED}`,
|
name: `${workspaceSettingNamePrefix}${WorkspaceSettingKey.MEMO_RELATED}`,
|
||||||
@ -120,6 +136,41 @@ const MemoRelatedSettings = () => {
|
|||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
</div>
|
</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">
|
<div className="mt-2 w-full flex justify-end">
|
||||||
<Button disabled={isEqual(memoRelatedSetting, originalSetting)} onClick={updateSetting}>
|
<Button disabled={isEqual(memoRelatedSetting, originalSetting)} onClick={updateSetting}>
|
||||||
{t("common.save")}
|
{t("common.save")}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user