pull/4914/head
johnnyjoy 3 months ago
commit 9b5b7b1ea2

@ -108,6 +108,9 @@ func (s *APIV1Service) convertActivityPayloadFromStore(ctx context.Context, payl
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to get memo: %v", err)
}
if memo == nil {
return nil, status.Errorf(codes.NotFound, "memo does not exist")
}
relatedMemo, err := s.Store.GetMemo(ctx, &store.FindMemo{
ID: &payload.MemoComment.RelatedMemoId,
ExcludeContent: true,

@ -1,4 +1,4 @@
import { InboxIcon, LoaderIcon, MessageCircleIcon } from "lucide-react";
import { InboxIcon, LoaderIcon, MessageCircleIcon, TrashIcon } from "lucide-react";
import { observer } from "mobx-react-lite";
import { useState } from "react";
import toast from "react-hot-toast";
@ -24,24 +24,32 @@ const MemoCommentMessage = observer(({ inbox }: Props) => {
const [relatedMemo, setRelatedMemo] = useState<Memo | undefined>(undefined);
const [sender, setSender] = useState<User | undefined>(undefined);
const [initialized, setInitialized] = useState<boolean>(false);
const [hasError, setHasError] = useState<boolean>(false);
useAsyncEffect(async () => {
if (!inbox.activityId) {
return;
}
const activity = await activityServiceClient.getActivity({
name: `${activityNamePrefix}${inbox.activityId}`,
});
if (activity.payload?.memoComment) {
const memoCommentPayload = activity.payload.memoComment;
const memo = await memoStore.getOrFetchMemoByName(memoCommentPayload.relatedMemo, {
skipStore: true,
try {
const activity = await activityServiceClient.getActivity({
name: `${activityNamePrefix}${inbox.activityId}`,
});
setRelatedMemo(memo);
const sender = await userStore.getOrFetchUserByName(inbox.sender);
setSender(sender);
setInitialized(true);
if (activity.payload?.memoComment) {
const memoCommentPayload = activity.payload.memoComment;
const memo = await memoStore.getOrFetchMemoByName(memoCommentPayload.relatedMemo, {
skipStore: true,
});
setRelatedMemo(memo);
const sender = await userStore.getOrFetchUserByName(inbox.sender);
setSender(sender);
setInitialized(true);
}
} catch (error) {
console.error("Failed to fetch activity:", error);
setHasError(true);
return;
}
}, [inbox.activityId]);
@ -69,6 +77,51 @@ const MemoCommentMessage = observer(({ inbox }: Props) => {
}
};
const handleDeleteMessage = async () => {
await userStore.deleteInbox(inbox.name);
toast.success(t("message.deleted-successfully"));
};
const deleteButton = () => (
<>
<div>
<TooltipProvider>
<Tooltip>
<TooltipTrigger>
<TrashIcon
className="w-4 h-auto cursor-pointer text-muted-foreground hover:text-primary"
onClick={() => handleDeleteMessage()}
/>
</TooltipTrigger>
<TooltipContent>
<p>{t("common.delete")}</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
</>
);
const archiveButton = () => (
<>
<div>
<TooltipProvider>
<Tooltip>
<TooltipTrigger>
<InboxIcon
className="w-4 h-auto cursor-pointer text-muted-foreground hover:text-primary"
onClick={() => handleArchiveMessage()}
/>
</TooltipTrigger>
<TooltipContent>
<p>{t("common.archive")}</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
</>
);
return (
<div className="w-full flex flex-row justify-start items-start gap-3">
<div
@ -100,23 +153,7 @@ const MemoCommentMessage = observer(({ inbox }: Props) => {
<>
<div className="w-full flex flex-row justify-between items-center">
<span className="text-sm text-muted-foreground">{inbox.createTime?.toLocaleString()}</span>
<div>
{inbox.status === Inbox_Status.UNREAD && (
<TooltipProvider>
<Tooltip>
<TooltipTrigger>
<InboxIcon
className="w-4 h-auto cursor-pointer text-muted-foreground hover:text-primary"
onClick={() => handleArchiveMessage()}
/>
</TooltipTrigger>
<TooltipContent>
<p>{t("common.archive")}</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
)}
</div>
{inbox.status === Inbox_Status.UNREAD ? archiveButton() : deleteButton()}
</div>
<p
className="text-base leading-tight cursor-pointer text-muted-foreground hover:underline hover:text-primary"
@ -129,6 +166,11 @@ const MemoCommentMessage = observer(({ inbox }: Props) => {
})}
</p>
</>
) : hasError ? (
<div className="w-full flex flex-row justify-between items-center">
<span className="text-sm text-muted-foreground">{t("inbox.failed-to-load")}</span>
{deleteButton()}
</div>
) : (
<div className="w-full flex flex-row justify-center items-center my-2">
<LoaderIcon className="animate-spin text-muted-foreground" />

@ -107,7 +107,8 @@
},
"inbox": {
"memo-comment": "{{user}} hat einen Kommentar zu {{memo}} hinterlassen.",
"version-update": "Die neue Version {{version}} ist jetzt verfügbar!"
"version-update": "Die neue Version {{version}} ist jetzt verfügbar!",
"failed-to-load": "Fehler beim Laden des Eintrags"
},
"markdown": {
"checkbox": "Checkbox",

@ -123,7 +123,8 @@
},
"inbox": {
"memo-comment": "{{user}} has a comment on your {{memo}}.",
"version-update": "New version {{version}} is available now!"
"version-update": "New version {{version}} is available now!",
"failed-to-load": "Failed to load inbox item"
},
"markdown": {
"checkbox": "Checkbox",

@ -189,6 +189,13 @@ const userStore = (() => {
return updatedInbox;
};
const deleteInbox = async (name: string) => {
await inboxServiceClient.deleteInbox({ name });
state.setPartial({
inboxes: state.inboxes.filter((i) => i.name !== name),
});
};
const fetchUserStats = async (user?: string) => {
const userStatsByName: Record<string, UserStats> = {};
if (!user) {
@ -224,6 +231,7 @@ const userStore = (() => {
fetchShortcuts,
fetchInboxes,
updateInbox,
deleteInbox,
fetchUserStats,
setStatsStateId,
};

Loading…
Cancel
Save