Skip to content

Commit c25c57a

Browse files
committed
feat: support updating display time
1 parent b0aad6f commit c25c57a

File tree

8 files changed

+65
-38
lines changed

8 files changed

+65
-38
lines changed

server/router/api/v1/memo_service.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,17 @@ func (s *APIV1Service) UpdateMemo(ctx context.Context, request *v1pb.UpdateMemoR
277277
} else if path == "created_ts" {
278278
createdTs := request.Memo.CreateTime.AsTime().Unix()
279279
update.CreatedTs = &createdTs
280+
} else if path == "display_ts" {
281+
displayTs := request.Memo.DisplayTime.AsTime().Unix()
282+
memoRelatedSetting, err := s.Store.GetWorkspaceMemoRelatedSetting(ctx)
283+
if err != nil {
284+
return nil, status.Errorf(codes.Internal, "failed to get workspace memo related setting")
285+
}
286+
if memoRelatedSetting.DisplayWithUpdateTime {
287+
update.UpdatedTs = &displayTs
288+
} else {
289+
update.CreatedTs = &displayTs
290+
}
280291
} else if path == "pinned" {
281292
if _, err := s.Store.UpsertMemoOrganizer(ctx, &store.MemoOrganizer{
282293
MemoID: id,

web/src/components/Dialog/BaseDialog.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,8 @@ export function generateDialog<T extends DialogProps>(
7777
const cbs: DialogCallback = {
7878
destroy: () => {
7979
document.body.style.removeProperty("overflow");
80-
setTimeout(() => {
81-
dialog.unmount();
82-
tempDiv.remove();
83-
});
80+
dialog.unmount();
81+
tempDiv.remove();
8482
},
8583
};
8684

web/src/components/ExploreSidebar/ExploreSidebar.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const ExploreSidebar = (props: Props) => {
1515
)}
1616
>
1717
<SearchBar />
18-
<TagsSection hideTips={true} />
18+
<TagsSection readonly={true} />
1919
</aside>
2020
);
2121
};

web/src/components/HomeSidebar/TagsSection.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import Icon from "../Icon";
1414
import showRenameTagDialog from "../RenameTagDialog";
1515

1616
interface Props {
17-
hideTips?: boolean;
17+
readonly?: boolean;
1818
}
1919

2020
const TagsSection = (props: Props) => {
@@ -62,7 +62,7 @@ const TagsSection = (props: Props) => {
6262
<div className="flex flex-col justify-start items-start w-full mt-3 px-1 h-auto shrink-0 flex-nowrap hide-scrollbar">
6363
<div className="group flex flex-row justify-start items-center w-full gap-1 mb-1">
6464
<span className="text-sm leading-6 font-mono text-gray-400 select-none">{t("common.tags")}</span>
65-
{!props.hideTips && (
65+
{!props.readonly && (
6666
<div className={clsx("group-hover:block", tagAmounts.length > 0 ? "hidden" : "")}>
6767
<Tooltip title={"Rebuild"} placement="top">
6868
<Icon.RefreshCcw
@@ -80,7 +80,7 @@ const TagsSection = (props: Props) => {
8080
))}
8181
</div>
8282
) : (
83-
!props.hideTips && (
83+
!props.readonly && (
8484
<div className="p-2 border border-dashed dark:border-zinc-800 rounded-md flex flex-row justify-start items-start gap-1 text-gray-400 dark:text-gray-500">
8585
<Icon.Tags />
8686
<p className="mt-0.5 text-sm leading-snug italic">{t("tag.create-tags-guide")}</p>

web/src/components/MemoContent/Code.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ interface Props {
33
}
44

55
const Code: React.FC<Props> = ({ content }: Props) => {
6-
return <code className="inline break-all px-1 font-mono rounded bg-gray-100 dark:bg-zinc-700">{content}</code>;
6+
return <code className="inline break-all px-1 font-mono text-sm rounded opacity-80 bg-gray-100 dark:bg-zinc-700">{content}</code>;
77
};
88

99
export default Code;

web/src/components/MemoEditor/MemoEditorDialog.tsx

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
import { IconButton } from "@mui/joy";
2-
import { useEffect } from "react";
3-
import { useTagStore } from "@/store/v1";
2+
import clsx from "clsx";
3+
import { useEffect, useRef, useState } from "react";
4+
import { useMemoStore, useTagStore } from "@/store/v1";
5+
import { Memo } from "@/types/proto/api/v1/memo_service";
46
import MemoEditor, { Props as MemoEditorProps } from ".";
57
import { generateDialog } from "../Dialog";
68
import Icon from "../Icon";
79

810
interface Props extends DialogProps, MemoEditorProps {}
911

1012
const MemoEditorDialog: React.FC<Props> = ({
11-
memoName: memo,
13+
memoName,
1214
parentMemoName,
1315
placeholder,
1416
cacheKey,
@@ -17,11 +19,21 @@ const MemoEditorDialog: React.FC<Props> = ({
1719
destroy,
1820
}: Props) => {
1921
const tagStore = useTagStore();
22+
const memoStore = useMemoStore();
23+
const [displayTime, setDisplayTime] = useState<string | undefined>(memoStore.getMemoByName(memoName || "")?.displayTime?.toISOString());
24+
const memoPatchRef = useRef<Partial<Memo>>({
25+
displayTime: memoStore.getMemoByName(memoName || "")?.displayTime,
26+
});
2027

2128
useEffect(() => {
2229
tagStore.fetchTags(undefined, { skipCache: false });
2330
}, []);
2431

32+
const updateDisplayTime = (displayTime: string) => {
33+
setDisplayTime(displayTime);
34+
memoPatchRef.current.displayTime = new Date(displayTime);
35+
};
36+
2537
const handleCloseBtnClick = () => {
2638
destroy();
2739
};
@@ -35,10 +47,25 @@ const MemoEditorDialog: React.FC<Props> = ({
3547

3648
return (
3749
<>
38-
<div className="w-full flex flex-row justify-between items-center mb-2">
39-
<div className="flex flex-row justify-start items-center">
40-
<img className="w-6 h-auto rounded-full shadow" src={"/full-logo.webp"} alt="" />
41-
<p className="ml-1 text-lg opacity-80 dark:text-gray-300">Memos</p>
50+
<div className="w-full flex flex-row justify-between items-center">
51+
<div className={clsx("flex flex-row justify-start items-center", !displayTime && "mb-2")}>
52+
{displayTime ? (
53+
<div className="relative">
54+
<span className="cursor-pointer text-gray-500 dark:text-gray-400">{new Date(displayTime).toLocaleString()}</span>
55+
<input
56+
className="inset-0 absolute z-1 opacity-0"
57+
type="datetime-local"
58+
value={displayTime}
59+
onFocus={(e: any) => e.target.showPicker()}
60+
onChange={(e) => updateDisplayTime(e.target.value)}
61+
/>
62+
</div>
63+
) : (
64+
<>
65+
<img className="w-6 h-auto rounded-full shadow" src={"/full-logo.webp"} alt="" />
66+
<p className="ml-1 text-lg opacity-80 dark:text-gray-300">Memos</p>
67+
</>
68+
)}
4269
</div>
4370
<IconButton size="sm" onClick={handleCloseBtnClick}>
4471
<Icon.X className="w-5 h-auto" />
@@ -47,11 +74,12 @@ const MemoEditorDialog: React.FC<Props> = ({
4774
<div className="flex flex-col justify-start items-start max-w-full w-[36rem]">
4875
<MemoEditor
4976
className="border-none !p-0 -mb-2"
50-
cacheKey={`memo-editor-${cacheKey || memo}`}
51-
memoName={memo}
77+
cacheKey={`memo-editor-${cacheKey || memoName}`}
78+
memoName={memoName}
5279
parentMemoName={parentMemoName}
5380
placeholder={placeholder}
5481
relationList={relationList}
82+
memoPatchRef={memoPatchRef}
5583
onConfirm={handleConfirm}
5684
autoFocus
5785
/>

web/src/components/MemoEditor/index.tsx

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { isValidUrl } from "@/helpers/utils";
99
import useCurrentUser from "@/hooks/useCurrentUser";
1010
import { useMemoStore, useResourceStore, useUserStore, useWorkspaceSettingStore } from "@/store/v1";
1111
import { MemoRelation, MemoRelation_Type } from "@/types/proto/api/v1/memo_relation_service";
12-
import { Visibility } from "@/types/proto/api/v1/memo_service";
12+
import { Memo, Visibility } from "@/types/proto/api/v1/memo_service";
1313
import { Resource } from "@/types/proto/api/v1/resource_service";
1414
import { UserSetting } from "@/types/proto/api/v1/user_service";
1515
import { WorkspaceMemoRelatedSetting } from "@/types/proto/api/v1/workspace_setting_service";
@@ -36,8 +36,8 @@ export interface Props {
3636
parentMemoName?: string;
3737
relationList?: MemoRelation[];
3838
autoFocus?: boolean;
39+
memoPatchRef?: React.MutableRefObject<Partial<Memo>>;
3940
onConfirm?: (memoName: string) => void;
40-
onEditPrevious?: () => void;
4141
}
4242

4343
interface State {
@@ -159,12 +159,6 @@ const MemoEditor = (props: Props) => {
159159
}
160160
return;
161161
}
162-
163-
if (!!props.onEditPrevious && event.key === "ArrowDown" && !state.isComposing && editorRef.current.getContent() === "") {
164-
event.preventDefault();
165-
props.onEditPrevious();
166-
return;
167-
}
168162
};
169163

170164
const handleMemoVisibilityChange = (visibility: Visibility) => {
@@ -293,13 +287,18 @@ const MemoEditor = (props: Props) => {
293287
if (memoName) {
294288
const prevMemo = await memoStore.getOrFetchMemoByName(memoName);
295289
if (prevMemo) {
290+
const updateMask = ["content", "visibility"];
291+
if (props.memoPatchRef?.current?.displayTime) {
292+
updateMask.push("display_ts");
293+
}
296294
const memo = await memoStore.updateMemo(
297295
{
298296
name: prevMemo.name,
299297
content,
300298
visibility: state.memoVisibility,
299+
...props.memoPatchRef?.current,
301300
},
302-
["content", "visibility"],
301+
updateMask,
303302
);
304303
await memoServiceClient.setMemoResources({
305304
name: memo.name,

web/src/pages/Home.tsx

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import { Button } from "@mui/joy";
22
import clsx from "clsx";
3-
import { useCallback, useEffect, useState } from "react";
3+
import { useEffect, useState } from "react";
44
import Empty from "@/components/Empty";
55
import { HomeSidebar, HomeSidebarDrawer } from "@/components/HomeSidebar";
66
import Icon from "@/components/Icon";
77
import MemoEditor from "@/components/MemoEditor";
8-
import showMemoEditorDialog from "@/components/MemoEditor/MemoEditorDialog";
98
import MemoFilter from "@/components/MemoFilter";
109
import MemoView from "@/components/MemoView";
1110
import MobileHeader from "@/components/MobileHeader";
@@ -59,14 +58,6 @@ const Home = () => {
5958
setNextPageToken(response.nextPageToken);
6059
};
6160

62-
const handleEditPrevious = useCallback(() => {
63-
const lastMemo = memoList.value[memoList.value.length - 1];
64-
showMemoEditorDialog({
65-
memoName: lastMemo.name,
66-
cacheKey: `${lastMemo.name}-${lastMemo.displayTime}`,
67-
});
68-
}, [memoList]);
69-
7061
return (
7162
<section className="@container w-full max-w-5xl min-h-full flex flex-col justify-start items-center sm:pt-3 md:pt-6 pb-8">
7263
{!md && (
@@ -76,7 +67,7 @@ const Home = () => {
7667
)}
7768
<div className={clsx("w-full flex flex-row justify-start items-start px-4 sm:px-6 gap-4")}>
7869
<div className={clsx(md ? "w-[calc(100%-15rem)]" : "w-full")}>
79-
<MemoEditor className="mb-2" cacheKey="home-memo-editor" onEditPrevious={handleEditPrevious} />
70+
<MemoEditor className="mb-2" cacheKey="home-memo-editor" />
8071
<div className="flex flex-col justify-start items-start w-full max-w-full">
8172
<MemoFilter className="px-2 pb-2" />
8273
{sortedMemos.map((memo) => (

0 commit comments

Comments
 (0)